Jump to content
Josh

C++ entity structure

Recommended Posts

I'm considering replacing the C++ hooks system with an "Actor" class you can extend to add your own behavior in C++:

#pragma once
#include "../Leadwerks.h"

namespace Leadwerks
{
   class Entity;

   class Actor : public Object
   {
   public:
       Actor();
       virtual ~Actor();

       Entity* entity;

       virtual void SetEntity(Entity* entity);
       virtual void Attach();
       virtual void Detach();
       virtual void UpdateMatrix();
       virtual void UpdateWorld();
       virtual void UpdatePhysics();
       virtual void Draw();
       virtual void DrawEach(Camera* camera);
       virtual bool Overlap(Entity* entity);
       virtual void Collision(Entity* entity, const Vec3& position, const Vec3& normal, float speed);        
       virtual void PostRender(Context* context);
   };
}

 

This would be built into the engine, and your C++ projects would declare a new class like this:

class Rocket : public Actor
{
      virtual void UpdatePhysics()
      {
             this->entity->Move(velocity);
      }
}

 

Leadwerks would then automatically call your methods at various points in the program execution, just like it does with Lua scripts. The hooks system is kind of a relic of the Leadwerks 2 support for so many languages, and isn't really needed if we are just focusing on C++/Lua.

 

I'm thinking at the same time we can probably make a class method that gets triggered whenever a flowgraph input is activated.

 

If I replace the hooks system, then this does break existing code. What are your thoughts?

Link to post

I love the idea. You are starting to actually use C++ features! Why not keep the old hook system so it doesn't break anything but add this as well?

 

The biggest issue with this in C++ is attaching map entities up with C++ code. Something to help with that would be nice if possible. With C++ not really allowing reflection (boost can sort of get it) that makes it a little more difficult. Generally a factory pattern along with some configuration would be required. Right now you kind of have to still use Lua to set key/value to help you figure out that map entity should use this C++ class and then check that in C++ to figure out which class instance to create. Kind of clunky.

 

Something that might help not require Lua with this would be a key/value system built into the entity properties so people could add key/values that get attached to the entity via SetEntityValue() automatically by the engine when the map is loaded so it can be read in with C++. Now that entity can just be an entity with no Lua script attached and they can make their own key (Class) to use in C++ after the map is loaded to figure out what C++ class instance to make.

 

There are a bunch of ways to map a string to a class name but they require some config in C++: http://stackoverflow.com/questions/582331/is-there-a-way-to-instantiate-objects-from-a-string-holding-their-class-name

Link to post

You took my idea(s). :( [1] [2]

 

Joking aside, this would be great. I just ask for a proper way of spawning said objects into the editor and flowgraph communication support! I'd love to code gameplay stuff in C++ without the gotcha's it has now. I actually created a player C++ side but then noticed the system to spawn the entity at a fixed location broke somehow, so I had to translate the entire code to lua.

 

The hook systems are confusing and I only just figured out how to use them a few months ago. I'd say go with it. I'd love for C++ side of things to get some attention as it feels like a "use at your own risk" feature.

Link to post

Wow you really start to understand that C++ is not simple C with classes.

Now give us the improved terrain editor and multiple scripts and we are all happy.

 

And have a look at C++11/13 std::bind, std::function etc.

Link to post

Not if you use your own namespace, then you could write something like:

Cassius::Actor player;

 

But please dont use this ugly

using Namespace [theNamespace];

Link to post

You can do the map loading thing right now yourself. The only way I could make it simpler would be a pre-build step that automatically generates some code files each time your game is compiled. The executable would scan the "Source/Actors" folder for header files, then create a map loading hook something like this:

void LoadEntity(Entity* entity)
{
Actor* actor = NULL;
if (entity->GetActorClass()=="Rocket")
{
	actor = new Rocket(entity);
}
else if (entity->GetActorClass()=="Demon")
{
	actor = new Demon(entity);
}
else if (entity->GetActorClass()=="Portal")
{
	actor = new Portal(entity);
}
}

 

Auto-generating some C++ code in your project adds a lot of new possibilities, but it is a significant departure from the way we've always done things and should be thought about carefully.

Link to post

You can do it now but it's a little painful. If you don't want to use the name of the entity how do you tell c++ what clas instance to make for said entity? You need to attach a script to the entity so you can set some key value that you then read from c++. Kind of clunky, and requires you to make a script. Maybe like entities can have different values that you want to set in the editor vs code. How would you do that? Why would you want that? Well an rpg game may have an NPC actor class but in you editor you want to assign that specific instance of the NPC a unique name, health, armor, etc. You need to get that info from that entity in the editor to the C++ actor class. Lots of things to think about of the C++ side.

 

You are starting to see why C# is so valuable. Since it has reflection all of this stuff becomes easy without needing code generation. Not saying LE should switch but you understand why some engines use C#. If you go generation you could allow us to add key/values to an entity from its properties window so lua isn't needed. Then match the name of the key to a setter function that we must define.

 

So if my key is Name I should make a function to my NPC class to setName(string name);

Link to post

Interestingly, we could actually add reflection to every single class using the pre-processor method I described, but it's something that should be considered carefully.

Link to post

You could change how Leadwerks loads c++ code. Instead of building an application, leadwerks projects just build into a DLL.

 

Using something like http://man7.org/linux/man-pages/man3/dlopen.3.html

 

Pull pre-defined methods out (Declared in the map file) using

void *dlsym(void *handle, const char *name);

Your class could be declared as "Rocket",

 

the program would look for "Rocket_Init" static function which returns an Action object of instance Rocket

 

 

To re-iterate another point. I agree with Rick in that you should keep backwards compatibility with Hooks. I'm probably at least 1,000 hours into my game as far as development is concerned. I'd hate to spend time re-writing a lot of my code instead of working on new functionality. I like the new Action class idea. I just would want backwards compatibility so I can upgrade over time.

Link to post

You could change how Leadwerks loads c++ code. Instead of building an application, leadwerks projects just build into a DLL.

 

Using something like http://man7.org/linux/man-pages/man3/dlopen.3.html

 

Pull pre-defined methods out (Declared in the map file) using

void *dlsym(void *handle, const char *name);

Your class could be declared as "Rocket",

 

the program would look for "Rocket_Init" static function which returns an Action object of instance Rocket

 

 

To re-iterate another point. I agree with Rick in that you should keep backwards compatibility with Hooks. I'm probably at least 1,000 hours into my game as far as development is concerned. I'd hate to spend time re-writing a lot of my code instead of working on new functionality. I like the new Action class idea. I just would want backwards compatibility so I can upgrade over time.

That's true, and the hooks are also still needed for the editor, so I don't think there will be any changes made there.
Link to post

This would also be a way to manage widgets without callbacks. Attach a C++ actor to the widget, there's your new behavior.

Link to post

We still need a way to have entities in the editor better "tell" the c++ code what class object to create and possibly any other entity data to populate class data with without using Lua.

 

On a side note you aren't really adding reflection. The idea of reflection is doing all that stuff at runtime not compile time. You're doing code generation.

Link to post

Well, the editor could scan the "Source/Actors" folder for headers and add those classes to a list you can choose. I suppose some class members could even be exposed in the editor.

Link to post

Oh wow you are thinking of taking this even farther! That would be pretty cool. Scanning c header files seems a little iffy to me but if it works well it's easier on the user so they don't have any configuration. You mentioned auto generating c++ though and generally the users never should touch auto generated files but those files you create would be the specific actor files we need to add our stuff to. This would be very interesting. I'll have to put more thought into this if you're willing to entertain, for now, how a system like this could work and various ways of doing it.

Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

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.

×
×
  • Create New...