#include "timer.h"
#include <iostream>
#include <cassert>
#include <stdlib.h>
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 T>
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<T> *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<T>;
}
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<ObjectData> *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<ObjectData> *p) { \
if(a!=p) { \
if(a) ::decRef(a); \
if(p) p->incRef(); \
a = p; \
} \
}
setFoo(parent);
FreeList<ObjectData> *parent;
int objtype;
};
FreeList<ObjectData> *FreeList<ObjectData>::begin = NULL;
int FreeList<ObjectData>::data_type = OBJECT_DATA;
class EntityData : public ObjectData {
public:
EntityData() : loc(NULL) { type = ENTITY_DATA; }
void freeObjectPtr() {
ObjectData::freeObjectPtr();
freeFoo(loc);
}
setFoo(loc);
FreeList<ObjectData> *loc;
double pos[3];
double velocity[3];
};
FreeList<EntityData> *FreeList<EntityData>::begin = NULL;
int FreeList<EntityData>::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<ObjectData> *from, *to;
FreeList<ObjectData> *arg;
};
FreeList<OperationData> *FreeList<OperationData>::begin = NULL;
int FreeList<OperationData>::data_type = OPERATION_DATA;
inline void decRef(FreeList<ObjectData> *ptr)
{
switch(ptr->data.type) {
case OBJECT_DATA:
ptr->decRef();
break;
case ENTITY_DATA:
((FreeList<EntityData> *)ptr)->decRef();
break;
case OPERATION_DATA:
((FreeList<OperationData> *)ptr)->decRef();
break;
default:
cout << "Unknown object class: " << ptr->data.type;
}
}
template <class T>
class SmartPtr
{
public:
FreeList<T> *ptr;
SmartPtr() {
ptr = FreeList<T>::alloc();
#if DEBUG
cout << "SmartPtr(): this: " << this << " ptr: " << ptr << endl;
#endif
}
SmartPtr(const SmartPtr<T>& a) {
#if DEBUG
cout << "SmartPtr(): this: " << this << " ptr: " << ptr << " a: " << &a << " a.ptr: " << a.ptr << endl;
#endif
ptr = a.get();
incRef();
}
// FreeList<ObjectData>* -> SmartPtr<EntityData>
SmartPtr(const FreeList<ObjectData>*a_ptr)
throw (IncompatibleDataTypeException) {
#if DEBUG
cout << "SmartPtr(const FreeList<ObjectData>*a_ptr): this: " << this
<< "a_ptr: " << a_ptr
<< " FreeList<T>::data_type: " << FreeList<T>::data_type
<< " a_ptr->data.type: " << a_ptr->data.type << endl;
#endif
int type = FreeList<T>::data_type;
if(type != a_ptr->data.type)
throw IncompatibleDataTypeException(type, a_ptr->data.type);
ptr = (FreeList<T>*)a_ptr;
incRef();
}
~SmartPtr() {
#if DEBUG
cout << "~SmartPtr(): this: " << this << " ptr: " << ptr << endl;
#endif
decRef();
}
void decRef() {
ptr->decRef();
}
void incRef() {
ptr->incRef();
}
// SmartPtr<EntityData> -> FreeList<ObjectData>*
FreeList<ObjectData>* asObjectPtr() {
#if DEBUG
cout << "asObjectPtr(): this: " << this << " ptr: " << ptr << endl;
#endif
//recipient should takes care of this: incRef();
return (FreeList<ObjectData>*)get();
}
SmartPtr& operator=(const SmartPtr<T>& 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<T>* get() const {
return ptr;
}
};
typedef SmartPtr<ObjectData> Object;
typedef SmartPtr<EntityData> Entity;
typedef SmartPtr<OperationData> 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<ObjectData> *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<ObjectData> *obj_ptr = test_obj_ptr();" << endl;
FreeList<ObjectData> *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; i<MAX_ITER; i+=1.0) {
//human:
#if DEBUG
cout << endl << "DEBUG: " << __LINE__ << ": Entity ent;" << endl;
#endif
Entity ent;
#if !FINE_GRAINED_LISTS
ent->objtype=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; i<MAX_ITER; i+=1.0) {
//human:
#if DEBUG
cout << endl << "DEBUG: " << __LINE__ << ": Entity human_ent;" << endl;
#endif
Entity human_ent;
#if DEBUG
cout << endl << "DEBUG: " << __LINE__ << ": human_ent->set_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: ("<<x<<","<<y<<","<<z<<")"<<endl;
return 0;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1