#include "timer.h"

#include <iostream>
#include <cassert>

using namespace std;

class Object {
public:
  int id;
  Object *parent;
  int objtype;
};

class Entity : public Object {
public:
  Object *loc;
  double pos[3];
  double velocity[3];
};

class Operation : public Object {
public:
  Object *from, *to;
  Object* arg;
};

enum {
  OBJECT,
  OP
};

Entity human;
Operation move;
Operation sight;

class NPC
{
public:
  NPC() : id(123) {x=y=z = vx=vy=vz = 0.0;}
  Operation *move(const Operation *op);
  int getId() {return id;}
private:
  int id;
  double x,y,z;
  double vx,vy,vz;
};

Operation *NPC::move(const Operation *op)
{
  double *new_vel = ((Entity*)op->arg)->velocity;
  vx = new_vel[0];
  vy = new_vel[1];
  vz = new_vel[2];

  x += vx;
  y += vy;
  z += vz;

  //human:
  static Entity human_ent;
  human_ent.parent = &human;
  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:
  static Operation move_op;
  move_op.objtype = OP;
  move_op.parent = &::move;
  move_op.arg = &human_ent;
  
  //sight:
  static Operation sight_op;
  sight_op.objtype = OP;
  sight_op.parent = &sight;
  sight_op.from = &human_ent;
  sight_op.arg = &move_op;

  return &sight_op;
}

int main(int argc, char** argv)
{
  double i;
  TIME_ON;
  for(i=0; i<10000000.0; i+=1.0) {
    //human:
    Entity ent;
    ent.objtype=OBJECT;
    ent.parent=&human;
    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:
    Operation move_op;
    move_op.objtype=OP;
    move_op.parent=&move;
    move_op.arg=&ent;
    
    //sight:
    Operation sight_op;
    sight_op.objtype=OP;
    sight_op.parent=&sight;
    sight_op.from=&ent;
    sight_op.arg=&move_op;
  }
  TIME_OFF("Plain creating of sight operation");


  NPC npc1;
  double x,y,z;
  TIME_ON;
  for(i=0; i<10000000.0; i+=1.0) {
    //human:
    Entity human_ent;
    human_ent.parent = &human;
    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:
    Operation move_op;
    move_op.objtype = OP;
    move_op.parent = &move;
    move_op.arg = &human_ent;

    Operation *res_sight = npc1.move(&move_op);
    Operation *res_move = (Operation*)(res_sight->arg);
    Entity *res_ent = (Entity*)res_move->arg;
    double *new_pos = res_ent->pos;
    x = new_pos[0];
    y = new_pos[1];
    z = new_pos[2];
  }
  TIME_OFF("NPC movements");
  cout<<"Resulting position: ("<<x<<","<<y<<","<<z<<")"<<endl;

  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1