Jump to content

Per object programming with C++


bkornienko
 Share

Recommended Posts

I'm not 100% sure what you are asking but it seems like you're asking can we have the same Lua script like behavior in C++ where maybe 1 class is the same as a Lua script and you assign said class to an entity?

 

If that's the case then there is a way to do it. The engine callback functions in a Lua script have C++ callback equivalents. However those are global C function callbacks that will pass in an LE entity of the entity that's being called for. If you store an instance of the C++ class you want loaded for each entity "inside" the LE entity itself (using SetUserData() function that LE entities have). Then inside the C callbacks you can get that C++ class instance with (GetUserData() function from the passed in entity) and then call it's specific class method that matches that callback.

 

 

If you look at the bottom of this page (http://www.leadwerks.com/werkspace/page/api-reference/_/entity/) the Hooks section. This shows you the global C hook functions that match the callbacks in Lua scripts.

 

Every LE entity derives from Object (http://www.leadwerks.com/werkspace/page/api-reference/_/object/object-r25) and here you can see there is a SetUserData() function and GetUserData() function. You can create a pointer of an instance of a class and pass it in and get it out with those functions. There is also an AddHook() function that allows you to add those hooks I mentioned above to any entity. That means the engine will automatically call the C hook callback for that entity when it should.

 

So now create a base class (that's like your Lua script) and have virtual functions that match all the possible hooks like:

 

class MyBaseObject
{
protected:
  Entity* entity;
public:
  void MyBaseObject(Entity* e) : entity(e) {}
  virtual void UpdateWorld(){}
  virtual void PostRender(){}
  // etc
};

 

 

Now create specific classes that derive from this. These would be just like the specific Lua scripts you create on the Lua side. So for example:

 

class Player : public MyBaseObject
{
public:
  void Player(Entity* e) : MyBaseObject(e) {}
  virtual void UpdateWorld() { /* do player specific update stuff*/ }
  // override all the virtuals you care about
};

 

 

Now when you load the map you need to loop over all the world->entities and somehow identify what entity should get what C++ class instance.

 


foreach(e in world->entities)

{
  if(e->GetKeyValue("name") == "player")
  {
    // create a new instance of this class and "attach" it to the LE entity
     e->SetUserData((void*)new Player(e));

     // assign all the callbacks to the entity here
     e->AddHook(Entity::UpdateWorldHook, (void)UpdateWorldCallback);
  }
}


void UpdateWorldCallback(Entity* e)
{
  // pull out the user data we stored in this entity and cast it back to the base class
  MyGameObject* obj = (MyGameObject*)e->GetUserData();

  // if the cast worked then call that specific objects virtual function UpdateWorld(). Now in our example we'll be in Player class UpdateWorld() function.
  if(obj != NULL)
  {
     obj->UpdateWorld();
  }
}

 

 

Some of this is pseudo code but it shows the idea on how to mimic Lua script behavior in C++. You create all the global C callbacks/hooks. Inside them you cast the entity's user data to your base class that has all the virtual functions. Then you call that specific virtual function. Then you have to figure out a method after the world is loaded how to tell which C++ class you should create for what LE entity that was loaded in the map. One way is to do it by the name you give the entity in the editor like in my example. Since you can name things the same in the LE editor you can treat this name more like the C++ class you want to load. My example had an if statement to check that and that could get really long so a better way would be to have some kind of factory pattern where you are registering C++ class to a string name and then you are just matching those up when looping over the world entities that were loaded.

 

Hope that made sense. It's a little setup to do on the C++ side of things but if you need specific help I can provide more help in an IM or something. I've done this setup in the past and it's worked out well.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...