#include "timer.h" #include #include #include using namespace std; class IncompatibleDataTypeException { public: IncompatibleDataTypeException(const int type1, const int type2) : data_type1(type1), data_type2(type2) {} int data_type1, data_type2; }; //#undef assert //#define assert(expr) ((void) 0) #undef DEBUG #define DEBUG 0 #if DEBUG #define MAX_ITER 10.0 #else #define MAX_ITER 10000000.0 #endif #define FINE_GRAINED_LISTS 1 template class FreeList { public: FreeList() : count(0) { #if DEBUG cout << "FreeList(): this: " << this << " data_type: " << data_type << endl; #endif } ~FreeList() { #if DEBUG cout << "~FreeList(): this: " << this << endl; #endif assert( count==0 ); } static FreeList *alloc() { if(begin) { #if DEBUG cout << "FreeList.alloc(): get from list: " << begin << endl; #endif FreeList *res = begin; assert( res->count == 0 ); //res->incRef(); begin = begin->next; return res; } #if DEBUG cout << "FreeList.alloc(): new" << endl; #endif return new FreeList; } void free() { #if DEBUG cout << "FreeList.free(): this: " << this << " data_type: " << data_type << endl; #endif //data.freeObjectPtr(); next = begin; begin = this; } void incRef() { #if DEBUG cout << "FreeList.incRef(): this: " << this << " count: " << count << " -> " << count+1 << endl; #endif count++; } void decRef() { #if DEBUG cout << "FreeList.decRef(): this: " << this << " count: " << count << " -> " << count-1 << endl; #endif assert( count >= 0 ); if(!count) { free(); return; } count--; } //private: static int data_type; int count; static FreeList *begin; FreeList *next; T data; }; class ObjectData; inline void decRef(FreeList *ptr); enum { OBJECT_DATA, ENTITY_DATA, OPERATION_DATA }; class ObjectData { public: ObjectData() : parent(NULL) { type = OBJECT_DATA; } #define freeFoo(a) if(a) { decRef(a); a = NULL; } ~ObjectData() { freeObjectPtr(); } void freeObjectPtr() { freeFoo(parent); } int type; int id; #define setFoo(a) \ void set_##a(FreeList *p) { \ if(a!=p) { \ if(a) ::decRef(a); \ if(p) p->incRef(); \ a = p; \ } \ } setFoo(parent); FreeList *parent; int objtype; }; FreeList *FreeList::begin = NULL; int FreeList::data_type = OBJECT_DATA; class EntityData : public ObjectData { public: EntityData() : loc(NULL) { type = ENTITY_DATA; } void freeObjectPtr() { ObjectData::freeObjectPtr(); freeFoo(loc); } setFoo(loc); FreeList *loc; double pos[3]; double velocity[3]; }; FreeList *FreeList::begin = NULL; int FreeList::data_type = ENTITY_DATA; class OperationData : public ObjectData { public: OperationData() : from(NULL), to(NULL), arg(NULL) { type = OPERATION_DATA; } void freeObjectPtr() { ObjectData::freeObjectPtr(); freeFoo(from); freeFoo(to); freeFoo(arg); } setFoo(from); setFoo(to); setFoo(arg); FreeList *from, *to; FreeList *arg; }; FreeList *FreeList::begin = NULL; int FreeList::data_type = OPERATION_DATA; inline void decRef(FreeList *ptr) { switch(ptr->data.type) { case OBJECT_DATA: ptr->decRef(); break; case ENTITY_DATA: ((FreeList *)ptr)->decRef(); break; case OPERATION_DATA: ((FreeList *)ptr)->decRef(); break; default: cout << "Unknown object class: " << ptr->data.type; } } template class SmartPtr { public: FreeList *ptr; SmartPtr() { ptr = FreeList::alloc(); #if DEBUG cout << "SmartPtr(): this: " << this << " ptr: " << ptr << endl; #endif } SmartPtr(const SmartPtr& a) { #if DEBUG cout << "SmartPtr(): this: " << this << " ptr: " << ptr << " a: " << &a << " a.ptr: " << a.ptr << endl; #endif ptr = a.get(); incRef(); } // FreeList* -> SmartPtr SmartPtr(const FreeList*a_ptr) throw (IncompatibleDataTypeException) { #if DEBUG cout << "SmartPtr(const FreeList*a_ptr): this: " << this << "a_ptr: " << a_ptr << " FreeList::data_type: " << FreeList::data_type << " a_ptr->data.type: " << a_ptr->data.type << endl; #endif int type = FreeList::data_type; if(type != a_ptr->data.type) throw IncompatibleDataTypeException(type, a_ptr->data.type); ptr = (FreeList*)a_ptr; incRef(); } ~SmartPtr() { #if DEBUG cout << "~SmartPtr(): this: " << this << " ptr: " << ptr << endl; #endif decRef(); } void decRef() { ptr->decRef(); } void incRef() { ptr->incRef(); } // SmartPtr -> FreeList* FreeList* asObjectPtr() { #if DEBUG cout << "asObjectPtr(): this: " << this << " ptr: " << ptr << endl; #endif //recipient should takes care of this: incRef(); return (FreeList*)get(); } SmartPtr& operator=(const SmartPtr& a) { #if DEBUG cout << "SmartPtr.=: " << this << " ptr: " << ptr << " a:" << &a << " a.ptr: " << a.ptr << endl; #endif if (a.get() != this->get()) { #if DEBUG cout << "SmartPtr.=: yup, different" << endl; #endif decRef(); ptr = a.get(); incRef(); } return *this; } T& operator*() { return ptr->data; } T* operator->() { return &ptr->data; } FreeList* get() const { return ptr; } }; typedef SmartPtr Object; typedef SmartPtr Entity; typedef SmartPtr Operation; enum { OBJECT, OP }; Entity human; Operation move; Operation sight; Entity test_cc(Entity in) { cout << "test: " << &in << endl; return in; } Entity test_cr(Entity &in) { cout << "test: " << &in << endl; return in; } Entity& test_rc(Entity in) { cout << "test: " << &in << endl; return in; } Entity& test_rr(Entity &in) { cout << "test: " << &in << endl; return in; } Entity test2(Entity &in) { cout << "test2: " << &in << endl; static Entity bar; bar = in; return in; } Entity test3(Entity &in) { cout << "test3: " << &in << endl; static Entity bar3(in); return in; } Entity test4(Entity &in) { cout << "test4: " << &in << endl; Entity bar; bar = in; return bar; } FreeList *test_obj_ptr() { Operation ent; ent.incRef(); return ent.asObjectPtr(); } #if DEBUG==2 int main() { cout << endl << "Entity foo;" << endl; Entity foo; cout << endl << "foo = human;" << endl; foo = human; cout << endl << "foo = test_cc(foo);" << endl; foo = test_cc(foo); cout << endl << "foo = test_cr(foo);" << endl; foo = test_cr(foo); cout << endl << "foo = test_rc(foo);" << endl; foo = test_rc(foo); cout << endl << "foo = test_rr(foo);" << endl; foo = test_rr(foo); cout << endl << "foo = test(human);" << endl; foo = test_rr(human); cout << endl << "foo = test2(foo);" << endl; foo = test2(foo); cout << endl << "foo = test3(foo);" << endl; foo = test3(foo); cout << endl << "Entity foo4;" << endl; Entity foo4; cout << endl << "foo4 = test4(foo4);" << endl; foo4 = test4(foo4); cout << endl << "Entity from_obj(human.asObjectPtr());" << endl; Entity from_obj(human.asObjectPtr()); cout << endl << "try {Operation op_from_obj(human.asObjectPtr());}..." << endl; try { Operation op_from_obj(human.asObjectPtr()); } catch (IncompatibleDataTypeException e) { cout << "IncompatibleDataTypeException: " << e.data_type1 << "!=" << e.data_type2 << endl; } cout << endl << "FreeList *obj_ptr = test_obj_ptr();" << endl; FreeList *obj_ptr = test_obj_ptr(); cout << endl << "decRef(obj_ptr);" << endl; decRef(obj_ptr); cout << endl << "...DONE" << endl; return 0; } #else class NPC { public: NPC() : id(123) {x=y=z = vx=vy=vz = 0.0;} Operation move(Operation &op); int getId() {return id;} private: int id; double x,y,z; double vx,vy,vz; }; Operation NPC::move(Operation &op) { #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Entity op_arg = op->arg;" << endl; #endif Entity op_arg = op->arg; double *new_vel = op_arg->velocity; vx = new_vel[0]; vy = new_vel[1]; vz = new_vel[2]; x += vx; y += vy; z += vz; //human: #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Entity human_ent;" << endl; #endif Entity human_ent; #if !FINE_GRAINED_LISTS #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": human_ent->set_parent(human.asObjectPtr());" << endl; #endif human_ent->set_parent(human.asObjectPtr()); #endif // !FINE_GRAINED_LISTS human_ent->id = getId(); human_ent->pos[0] = x; human_ent->pos[1] = y; human_ent->pos[2] = z; human_ent->velocity[0] = vx; human_ent->velocity[1] = vy; human_ent->velocity[2] = vz; //move: #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Operation move_op;" << endl; #endif Operation move_op; #if !FINE_GRAINED_LISTS move_op->objtype = OP; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": move_op->set_parent(::move.asObjectPtr());" << endl; #endif move_op->set_parent(::move.asObjectPtr()); #endif // !FINE_GRAINED_LISTS #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": move_op->set_arg(human_ent.asObjectPtr());" << endl; #endif move_op->set_arg(human_ent.asObjectPtr()); //sight: #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Operation sight_op;" << endl; #endif Operation sight_op; #if !FINE_GRAINED_LISTS sight_op->objtype = OP; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": sight_op->set_parent(sight.asObjectPtr());" << endl; #endif sight_op->set_parent(sight.asObjectPtr()); #endif // !FINE_GRAINED_LISTS #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": sight_op->set_from(human_ent.asObjectPtr());" << endl; #endif sight_op->set_from(human_ent.asObjectPtr()); #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": sight_op->set_arg(move_op.asObjectPtr());" << endl; #endif sight_op->set_arg(move_op.asObjectPtr()); return sight_op; } int main(int argc, char** argv) { double i; TIME_ON; for(i=0; iobjtype=OBJECT; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": ent->set_parent(human.asObjectPtr());" << endl; #endif ent->set_parent(human.asObjectPtr()); #endif // !FINE_GRAINED_LISTS ent->pos[0] = i; ent->pos[1] = i-1.0; ent->pos[2] = i+1.0; ent->velocity[0] = i; ent->velocity[1] = i-1.0; ent->velocity[2] = i+1.0; //move: #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Operation move_op;" << endl; #endif Operation move_op; #if !FINE_GRAINED_LISTS move_op->objtype=OP; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": move_op->set_parent(move.asObjectPtr());" << endl; #endif move_op->set_parent(move.asObjectPtr()); #endif // !FINE_GRAINED_LISTS #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": move_op->set_arg(ent.asObjectPtr());" << endl; #endif move_op->set_arg(ent.asObjectPtr()); //sight: #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Operation sight_op;" << endl; #endif Operation sight_op; #if !FINE_GRAINED_LISTS sight_op->objtype=OP; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": sight_op->set_parent(sight.asObjectPtr());" << endl; #endif sight_op->set_parent(sight.asObjectPtr()); #endif // !FINE_GRAINED_LISTS #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": sight_op->set_from(ent.asObjectPtr());" << endl; #endif sight_op->set_from(ent.asObjectPtr()); #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": sight_op->set_arg(move_op.asObjectPtr());" << endl; #endif sight_op->set_arg(move_op.asObjectPtr()); #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": DONE iter" << endl; #endif } TIME_OFF("Plain creating of sight operation"); #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": NPC npc1;" << endl; #endif NPC npc1; double x,y,z; TIME_ON; for(i=0; iset_parent(human.asObjectPtr());" << endl; #endif #if !FINE_GRAINED_LISTS human_ent->set_parent(human.asObjectPtr()); #endif // !FINE_GRAINED_LISTS human_ent->id = npc1.getId(); human_ent->velocity[0] = i; human_ent->velocity[1] = i-1.0; human_ent->velocity[2] = i+1.0; //move: #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Operation move_op;" << endl; #endif Operation move_op; #if !FINE_GRAINED_LISTS move_op->objtype = OP; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": move_op->set_parent(move.asObjectPtr());" << endl; #endif move_op->set_parent(move.asObjectPtr()); #endif // !FINE_GRAINED_LISTS #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": move_op->set_arg(human_ent.asObjectPtr());" << endl; #endif move_op->set_arg(human_ent.asObjectPtr()); #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Operation res_sight = npc1.move(move_op);" << endl; #endif Operation res_sight = npc1.move(move_op); #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Operation res_move = res_sight->arg;" << endl; #endif Operation res_move = res_sight->arg; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": Entity res_ent = res_move->arg;" << endl; #endif Entity res_ent = res_move->arg; double *new_pos = res_ent->pos; x = new_pos[0]; y = new_pos[1]; z = new_pos[2]; #if DEBUG cout << endl << "DEBUG: " << __LINE__ << ": DONE iter" << endl; #endif } TIME_OFF("NPC movements"); cout<<"Resulting position: ("<