Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Feather Kit - A C++ Game Framework  (Read 40309 times)

0 Members and 1 Guest are viewing this topic.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Feather Kit - A C++ Game Framework
« Reply #15 on: January 23, 2014, 09:20:20 am »
Nice to see some public stuff about FeatherKit. Keep it going. :)

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #16 on: January 28, 2014, 12:18:46 am »
Quote from: therocode
I look over the old code and see if I can come up with a nice way to fix it. Feel free to post your ideas on how to do this the best way possible. :) Depending on things I actually might remove the aligned entity backend if I can't figure out a way to do what I wanted to do with it in a good way. Is is quite a special case component. Although the idea is nice.

I personally think that it would be a good idea for you to go learn about type erasure, then redesign the whole system.

Also, it would make things a lot simpler if the "EntityBackend" type wasn't runtime configurable. That way, the full static type of both the attributes and their respective containers could be known, potentially allowing the registration/query code to be as straight forward as:

std::map<..., std::shared_ptr<void>> m_attributeArrays;
// ...
template<typename T>
void EntityManager::registerAttribute(const std::string& name)
{
    // 'attributeArrays' is a map containing type erased AttributeArray objects.
    m_attributeArrays[name] = std::make_shared<AttributeArray<T>>(name, this);
}

template<typename T>
T& EntityManager::getAttribute(const std::string& name, const EntityId id)
{
    // cast back to known static type.
    void* vp = m_attributeArrays[[name].get();
    return static_cast<AttributeArray<T>*>(vp)->get(id);
}
 

If you do go for a full redesign, you could consider looking up attributes by type rather than strings. That would allow the attribute arrays to be accessed by an integer index into a vector (which is hella faster than string keys into a map). Like so:

inline unsigned nextTypeID()
{
    static unsigned id = 0;
    return id++;
}

template<typename T>
unsigned TypeID()
{
    static const unsigned id = nextID();
    return id;
}

// ...
std::vector<std::shared_ptr<void>> m_attributeArrays;
// ...

template<typename T>
void EntityManager::registerAttribute(const std::string& name)
{
    // 'attributeArrays' is a vector containing type erased AttributeArray objects.
    const auto index = TypeID<T>();
    if (index >= m_attributeArrays.size()) {
        auto ptr = std::make_shared<AttributeArray<T>>(name, this);
        m_attributeArrays.resize(1 + index);
        m_attributeArrays[index] = ptr;
    }
}

template<typename T>
T& EntityManager::getAttribute(const EntityId id)
{
    // cast back to known static type.
    void* vp = m_attributeArrays[TypeID<T>()].get();
    return static_cast<AttributeArray<T>*>(vp)->get(id);
}
 

You could also keep the old string mapping around as a 'slow path' to ease serialization and such.

Because types will be registered at the granularity of attributes (versus, say, components), there would have to be some mechanism in place to allow multiple attributes of the same type to be registered independently. It could be as simple as matching the actual attribute type with a tag type:

template<typename T, typename Tag>
struct Attribute
{
    using value_type = T;
    using tag_type = Tag;
};

template<typename T>
typename T::value_type EntityManager::getAttribute(const EntityId id);

struct HealthTag {};
using Health = Attribute<int, HealthTag>;

//...

int health = entManager.getAttribute<Health>(id);
 

Hopefully, all that was more helpful than it was confusing.  ;)
« Last Edit: January 28, 2014, 12:38:04 am by Lee R »

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #17 on: January 28, 2014, 11:17:49 am »
Nice to see some public stuff about FeatherKit. Keep it going. :)

Thanks, mate! :)

I personally think that it would be a good idea for you to go learn about type erasure, then redesign the whole system.

...

Hopefully, all that was more helpful than it was confusing.  ;)

Nope, not confusing at all, but quite inspirational!

I read about type erasure and learnt a few new things about it which is nice, thanks. I've never known the term although I am familliar with many of the practices it leads to, but reading about it as a concept is nice. :)

Having a type based system instead of string based system indeed has its benefits with the compile time processing and type safety, but on the other hand it has its own drawbacks. For once, now when the system uses strings, it is trivial to read entity templates from JSON files where the strings are directly corresponding to an actual attribute. That is useful since content designers can define things purely in data files without fiddling with, and recompiling the code. This can of course be achieved with programmers creating a predefined lookup-table where strings correspond to a type, but it is less neat so it is a trade-off.

Another approach I am investigating to solve the current issue of not bieng able to store types that has custom value semantics is to store the attributes in std::shared_ptr<void> which will be able to delete them properly. Then a simple cast with a template getter function can retrieve the original value. This would get rid of the current issues.

I am not sure yet which approach I'll use, but feel free to come with more suggestions/ideas about it. :) And thanks for taking your time.

Oh btw, there is a built in way of getting an index representing a unique type instead of using a static incrementing counter:
std::type_index index = std::type_index(typeid(AttributeType));
 

Cheers!

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #18 on: January 28, 2014, 07:47:20 pm »
Quote from: therocode
Having a type based system instead of string based system indeed has its benefits with the compile time processing and type safety, but on the other hand it has its own drawbacks. For once, now when the system uses strings, it is trivial to read entity templates from JSON files where the strings are directly corresponding to an actual attribute. That is useful since content designers can define things purely in data files without fiddling with, and recompiling the code. This can of course be achieved with programmers creating a predefined lookup-table where strings correspond to a type, but it is less neat so it is a trade-off. [...]

I'm not sure I see the problem. In my last post, I did say that the string mapping could be kept around to ease serialization and such. I mean, the string data must be mapped to real C++ types at some point, else it's nothing but meaningless junk taking up space.

Does this address the use case you have in mind (the concept, rather than exact implementation)?
using LoadFunc = std::function<
    void(EntityID, std::string)
>;
std::map<std::string, LoadFunc> m_loaders;

// ...

template<typename T>
void EntityManager::registerAttribute(const std::string& name)
{
    // ...same as before...

    m_loaders[name] = [this](EntityID id, std::string data) {
        std::stringstream ss(std::move(data));
        ss >> getAttribute<T>(id);
    };
}

void EntityManager::loadAttribute(EntityID id, std::string name, std::string data)
{
    m_loaders[name](id, std::move(data));
}
 

EDIT: Okay, I think I understand your use case better now. You actively want the ability to load meaningless junk. That is, user defined attributes for which the compiled executable has no specialized code. Then, while waiting for a programmer to implement their logic, a level designer could get on with placing objects containing said attributes. If that's the case, then a fully typed entity system could still work. You'd simply define a 'EditorAttribute' which would suck up all unknown attributes. The editor system would look for object with said EditorAttribute and display it's contents as if they were first class attributes. If, on the other hand, the idea is to have the logic be implemented in script files, while the above idea would still work (e.g. through a ScriptVars arrtibute), you would probably be better off back with the old string based system (depending on the amount of data that gets stuffed into the ScriptVars attributes).

Quote
Another approach I am investigating to solve the current issue of not bieng able to store types that has custom value semantics is to store the attributes in std::shared_ptr<void> which will be able to delete them properly. Then a simple cast with a template getter function can retrieve the original value. This would get rid of the current issues.

This is essentially what I suggested in my last post. It's pretty much the same idea, whether it's individual attribute objects that are type erased or entire arrays of them.

Quote
Oh btw, there is a built in way of getting an index representing a unique type instead of using a static incrementing counter:
std::type_index index = std::type_index(typeid(AttributeType));
 

The code I presented for mapping a type to an integer has the additional property that for the first type queried, the returned value will be 0; for the second type queried it will be 1, and so on. This makes it suitable for use in as the index into a vector. Resizing a vector to accommodate the returned value of the code you presented could (and likely would) result in gobs of memory being wasted. This besides the fact that I don't think the std::type_index class defines a conversion to integer.
« Last Edit: January 29, 2014, 12:53:11 am by Lee R »

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #19 on: January 29, 2014, 09:36:04 am »
Okay, I think I understand your use case better now. You actively want the ability to load meaningless junk. That is, user defined attributes for which the compiled executable has no specialized code. Then, while waiting for a programmer to implement their logic, a level designer could get on with placing objects containing said attributes. If that's the case, then a fully typed entity system could still work. You'd simply define a 'EditorAttribute' which would suck up all unknown attributes. The editor system would look for object with said EditorAttribute and display it's contents as if they were first class attributes. If, on the other hand, the idea is to have the logic be implemented in script files, while the above idea would still work (e.g. through a ScriptVars arrtibute), you would probably be better off back with the old string based system (depending on the amount of data that gets stuffed into the ScriptVars attributes).

[...]

Yes, that is right. Such use cases is what I have in mind. I am not entiry sure what you mean with a 'EditorAttribute' which would suck up all unknown attributes, but I have an idea on an implementation that I kind of like. It would work like this:

The entity manager has such a function:
eManager.registerAttribute<int>("Health");

After this line, "Health" is a valid attribute and the manager remembers the type of it.

You then create entities like so:
eManager.registerAttribute<int>("Health");
eManager.registerAttribute<float>("Weight");

WeakEntityPtr entity1 = eManager.createEntity({"Health", "Weight"});
WeakEntityPtr entity2 = eManager.createEntity({"Health"});
WeakEntityPtr entity3 = eManager.createEntity({"Weight"});

The parameter is an std::vector<std::string>. Exceptions are thrown if the attributes are not valid. WeakentityPtr is a typedef for std::weak_ptr<Entity>

Entity attributes are then accessed like so:
eManager.setAttribute<int>(entityId, "Health", 45);
int health = eManager.getAttribute<int>(entityId, "Health");

And in a similar sense to what you described before, the manager remembers what type the attributes where registered with, which makes it easy to add type safety. Behind the scenes, it stores the attributes in a copy-safe type erased way such as std::shared_ptr<void> or whatever is suitable. That way it can handle any type and it also has type safety. As a shorthand you can also call .setAttribute<int>("Health", 45) directry on an entity.


However, this is quite tedious to use since you have to provide an std::vector of std::string every time you create an entity. So there will be a utility class (which was previously functionality in the EntityManager, causing messiness) called EntityFactory or something along those lines. The entity factory takes the entity manager as a reference upon creation and provides an API to register entity templates with default value setters. These templates can be loaded from JSON files. So you can have this JSON file:
{
    "player":
    {
        "position":"900.0f,100.0f", "velocity":"", "acceleration":"", "maxvelocity":"5.5f", "maxacceleration":"1.0f", "hitbox":"24.0f,24.0f", "collisiontype":"solid", "collisiongroup":"player"
    }
}

This file defines one entity template but can define more as well. Every template has a name ("player") and a bunch of associated attributes. The attributes are pairs of their name and default value when the template is instantiated.

To use the attributes, they have to be registered in the entity manager using the registerAttribute<>() function, and to put a default value, a default-setting function must be registered using entityFactory.registerDefaultSetter(). If a default setter is not needed, the default value can be left empty in the file. Example on how to register a default-setter for a glm::vec2 for position:

entityFactory.registerDefaultSetter("position",
[] (const std::string attribute&, const std::vector<std::string>& arguments, fea::WeakEntityPtr entity) {
entity.lock()->setAttribute<glm::vec2>(attribute, glm::vec2(std::stof(arguments[0]), std::stof(arguments[1])));
});

Sorry for the messy lambda code but I wanted to keep it short in the forum post. :D

Then to finally instantiate an entity template, you would do something like:
WeakEntityPtr entity = entityFactory.instantiate("player");

I might also look into making the system template based so that it is optional if you want strings as identifiers for the attributes or if you'd prefer a numerical type or anything else. That way you could use enums if you care about strings being low performance to compare.

That's it.

To me this API seems quite straight-forward and it seems reasonably type-safe and exception safe. But that's easy to say without another persons perspective haha. So are there in your opinion any serious drawbacks or limitations with a system like that? Thanks again for your feedback and ideas. :)

edit: Forgot to reply to this bit:

The code I presented for mapping a type to an integer has the additional property that for the first type queried, the returned value will be 0; for the second type queried it will be 1, and so on. This makes it suitable for use in as the index into a vector. Resizing a vector to accommodate the returned value of the code you presented could (and likely would) result in gobs of memory being wasted. This besides the fact that I don't think the std::type_index class defines a conversion to integer.

True, useful if it should be stored indexed in a vector. I guess I just personally prefer to use an unordered_map for such storage so that I don't need to worry about managing indices.
« Last Edit: January 29, 2014, 07:45:37 pm by therocode »

Rexou

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Feather Kit - A C++ Game Framework
« Reply #20 on: January 29, 2014, 01:15:49 pm »
Hi there, i've been reading this topic since its creation but haven't been able to give your framework a real try like i wished i could but i wanted to say that what i saw in the sources seems to be very useful, well organized and cool. Well done !

I've already tried the messaging part and looked at the examples for the basics but I can't wait to see tutorials on your entity system / Emscripten / other advanced parts.

I wanted to ask how would you do a class listening to several events/messages using your API ? I have created a working example but it's obviously not fun to maintain if we're listening for more than a dozen of messages.

Here's the code of my sample http://codepad.org/anuJSWAQ
Basically just a macro helping me to create the different structures & typedefs for the Message tag/data in Event.hpp and a HeroPet class containing 2 vectors<std::function>> filled in the ctor (one for each Message type). In the handleMessages functions i iterate over the two callback_vectors to call the associated functions and that's pretty much it.

I am not in a hurry so take your time it's ok if i have to wait for the documentation to be completed hehe.

Keep it up  ;) !

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #21 on: January 29, 2014, 02:28:46 pm »
Hi there, i've been reading this topic since its creation but haven't been able to give your framework a real try like i wished i could but i wanted to say that what i saw in the sources seems to be very useful, well organized and cool. Well done !

...

Ah, thanks a lot. :)

Interesting to see a macro to define message types, that is clever. Maybe I could incorporate such a message creation macro in the actual framework haha.

Regarding your sample, if it is done like that it would be not fun to maintain indeed. But it seems to me like you are mixing two techniques. Messaging and callbacks. Whenever I have used the messaging system, I don't use it to call callbacks, but I let the final object that is meant to react to the message actually receive the message. So in your example, I would skip the callbacks alltogether and just have the prints in the handleMessage functions.

Here is an example on how I have used the messagebus to subscribe to many messages (sorry if the code is messy, it was written during a game jam haha):
Header file: http://pallkars.net/gitweb/?p=tobbegame.git;a=blob;f=src/playerhandler.h;h=53f5ca63889daaee2f5bd5065e4de2c7a2085dd6;hb=HEAD
Source file: http://pallkars.net/gitweb/?p=tobbegame.git;a=blob;f=src/playerhandler.cpp;h=ae91e9abbf660911442a4a939488855d8c79d12b;hb=HEAD

But yeah, I'll definitely consider providing some macros for the message typing you have to do. It seems really potentially handy!

Not sure if that answers your question, feel free to ask more if you need more clarifications. :)

Rexou

  • Newbie
  • *
  • Posts: 9
    • View Profile
    • Email
Re: Feather Kit - A C++ Game Framework
« Reply #22 on: January 29, 2014, 03:48:24 pm »
Interesting to see a macro to define message types, that is clever. Maybe I could incorporate such a message creation macro in the actual framework haha.

Actually I didn't even know we could create empty std::tuples before that macro (it would be impossible to use this macro for messages without parameters) I just wanted to test my memory about preprocessor tricks
but im glad if i can contribute !

Regarding your sample, if it is done like that it would be not fun to maintain indeed. But it seems to me like you are mixing two techniques. Messaging and callbacks. Whenever I have used the messaging system, I don't use it to call callbacks, but I let the final object that is meant to react to the message actually receive the message. So in your example, I would skip the callbacks all together and just have the prints in the handleMessage functions.

Yep, it seems to be the legit way to handle messages and after reflexion about this, it could probably be done by splitting these handleMessages functions into subfunctions, you're right there is no need for callbacks there !

Here is an example on how I have used the messagebus to subscribe to many messages (sorry if the code is messy, it was written during a game jam haha):

Ok so it's also registration through inheritance and one function per message type, I don't think we can do better if we want to keep compile-time dispatching.

But yeah, I'll definitely consider providing some macros for the message typing you have to do. It seems really potentially handy!

Not sure if that answers your question, feel free to ask more if you need more clarifications. :)

No more questions for now, I'll keep reading the sources during my free time, thanks for the answers !

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #23 on: February 03, 2014, 11:16:46 am »

Actually I didn't even know we could create empty std::tuples before that macro (it would be impossible to use this macro for messages without parameters) I just wanted to test my memory about preprocessor tricks
but im glad if i can contribute !

Ah, the macro worked fine for me without parameters. I have added such a macro to the Message class now. Thanks for the tip. :)

Ok so it's also registration through inheritance and one function per message type, I don't think we can do better if we want to keep compile-time dispatching.

No more questions for now, I'll keep reading the sources during my free time, thanks for the answers !

Yep that is true.

Alright, no problems!

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #24 on: February 10, 2014, 04:26:55 am »
Okay so this is a bit of a late reply, but hey :P

Quote from: therocode
Quote from: Lee R
Okay, I think I understand your use case better now. You actively want the ability to load meaningless junk. That is, user defined attributes for which the compiled executable has no specialized code. Then, while waiting for a programmer to implement their logic, a level designer could get on with placing objects containing said attributes. If that's the case, then a fully typed entity system could still work. You'd simply define a 'EditorAttribute' which would suck up all unknown attributes. The editor system would look for object with said EditorAttribute and display it's contents as if they were first class attributes. If, on the other hand, the idea is to have the logic be implemented in script files, while the above idea would still work (e.g. through a ScriptVars arrtibute), you would probably be better off back with the old string based system (depending on the amount of data that gets stuffed into the ScriptVars attributes).

[...]

Yes, that is right. Such use cases is what I have in mind. I am not entiry sure what you mean with a 'EditorAttribute' which would suck up all unknown attributes [...]

It's seems like the use case you have in mind is actually quite a bit simpler than that. You just want the ability to load values for known attributes from a JSON file. That's trivial to achieve even with a fully type based system and it takes no more effort than for the new system you've described (i.e. no need for an 'EditorAttribute' or the like). Because this:

Quote from: therocode
The entity manager has such a function:
eManager.registerAttribute<int>("Health");

Provides the entity manager with both the static type of the attribute, and its string identifier. This is exactly the same information that a type based system would need in order for it to satisfy the use case. The code in my earlier post shows what that could look like:
http://en.sfml-dev.org/forums/index.php?topic=14193.msg100008#msg100008

Quote from: therocode
You then create entities like so:
eManager.registerAttribute<int>("Health");
eManager.registerAttribute<float>("Weight");

WeakEntityPtr entity1 = eManager.createEntity({"Health", "Weight"});
WeakEntityPtr entity2 = eManager.createEntity({"Health"});
WeakEntityPtr entity3 = eManager.createEntity({"Weight"});

The parameter is an std::vector<std::string>. [...]

Perhaps std::set<std::string> would makes more sense here?

Quote from: therocode
Example on how to register a default-setter for a glm::vec2 for position:

entityFactory.registerDefaultSetter("position",
[] (const std::string attribute&, const std::vector<std::string>& arguments, fea::WeakEntityPtr entity) {
entity.lock()->setAttribute<glm::vec2>(attribute, glm::vec2(std::stof(arguments[0]), std::stof(arguments[1])));
});

This could just be a matter of taste, but I feel like it would become quite tedious having to provide the 'default-setter' function for the same type, whenever that type is registered in the entity factory as an attribute (e.g. both position and velocity being vec2, and having to provide same setter function for both, individually). That being in addition to having to register both with the entity manager. It would be nice if, for example, the 'glm::vec2' type is registered along with its 'default-setter', not as an attribute, but as a primitive which can then be mapped to a name to form a new attribute.

I realise that it's probably not entirely obvious what I mean, so I went ahead and wrote a reference implementation to demonstrate the idea (which you're free to ignore ;)):

http://codepad.org/kBtU0puv

As an example of usage:

int main()
{
    fea::EntityManager manager;
    fea::EntityFactory producer(manager);

    producer.addPrimitive("vec2", [](const fea::Params& params) {
        return glm::vec2{ std::stof(params[0]), std::stof(params[1]) };
    });

    producer.map("position", "vec2");
    producer.map("velocity", "vec2");

    fea::Template moveable = {
        { "position", { "0.0, 0.0" } },
        { "velocity", { "0.0, 0.0" } }
    };

    producer.addTemplate("moveable", moveable);
    auto entity = producer.instantiate("moveable").lock();

    glm::vec2 position = entity.getAttribute<glm::vec2>("position");
    glm::vec2 velocity = entity.getAttribute<glm::vec2>("velocity");

    return 0;
}
 

There's a few things you might find interesting about this:

- Note that the user no longer explicitly registers anything with the entity manager itself. The entity factory handles all that under the covers (i.e. there is no registration code missing here, this is a complete example).

- The 'default-setter' function has been reduced to a simple parser; it doesn't concern itself with entities or managers or even attributes. It simply parses the arguments and returns an object of the appropriate type (which the entity factory will automatically deduce).

- Entity templates are parsed as soon as they're added to the system and stored as what I call 'proto entities'. This saves the system from having to re-parse (as in your current system) the strings of a template every time one is instantiated. The point here is that one could add sophisticated error handling to the parser function (previously 'default-setter') and not have to worry about any performance overhead since it will only ever been invoked once per template, rather than once per instantiation.

- This system satisfies the use case quoted at the top of this post; One could create entirely new attributes inside JSON files (in addition to simply being able to provide the values of known attributes).
- The code requires no modification to your existing EntityManager, except that it assumes the 'createEntity' function accepts an std::set<std::string>.

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #25 on: February 10, 2014, 07:46:59 pm »
O_O

I was just wondering about how could I store entities with any kind of attributes. (because it's often game specific)

This sounds like to be interesting!

I'll probably use that in the next version of my framework.

But I've already implemented this system for my state system.

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #26 on: February 11, 2014, 08:00:33 am »
Long post

Hello again!

Thanks a lot for your post! It makes very much sense and I agree that this is a good approach to the EntityFactory class. :)

I like the idea of registering primitives and their setters rather than types. I guess I hadn't really thought about doing that but it makes more sense and removes quite a bit of overhead from the usage which is good.

Also, deducting primitive type from the return type of the lambda is very elegant hehe.

Another hilight I like is reducing the default setter to purely a parser. That makes it easier to understand and follows the principle of single responsibility better and overall seems like a more clean design!

Am I allowed to assimilate your example code with minor changes? In that case, do you wish to be credited in comments at the top of the file?

If not, then I'll code something similar up myself probably.

Thanks a lot for your suggestions, it is appreciated!

O_O

I was just wondering about how could I store entities with any kind of attributes. (because it's often game specific)

In my system I use std::shared_ptr<void>.
« Last Edit: February 11, 2014, 08:02:08 am by therocode »

Lolilolight

  • Hero Member
  • *****
  • Posts: 1232
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #27 on: February 11, 2014, 11:51:57 am »
I like the idea by using a template to store one of more attributes for the entities. (It avoid to have a to use too much inheritance, in the case of the game have a lot of different entities. (weapons, caracters rĂ´les, skills objects, etc...)

But I don't see where is the utility to use a template to move the entities. (for exemple)

Combinate the inheritance (to store the common entities attributes) and the templates (to store specific attributes)  shouldn't it better ?

I really like combinates many techniques in a framework and taking advantages of each techniques. (And I think the most sotisticated frameworks should work like that)

If someone see an utility to use a template to do transformations on entities can he explain me because I don't very understand.
« Last Edit: February 11, 2014, 11:54:27 am by Lolilolight »

Lee R

  • Jr. Member
  • **
  • Posts: 86
    • View Profile
Re: Feather Kit - A C++ Game Framework
« Reply #28 on: February 11, 2014, 05:03:38 pm »
Quote from: therocode
Am I allowed to assimilate your example code with minor changes? In that case, do you wish to be credited in comments at the top of the file?

Sure. You may do whatever you like with it. I don't require any credit.

Quote from: Lolilolight
But I don't see where is the utility to use a template to move the entities. (for exemple)

It was just an example to show the process. Perhaps I should have used names like 'foo' and 'bar'. Although having said that, you have picked up on something:

Quote from: Lolilolight
Combinate the inheritance (to store the common entities attributes) and the templates (to store specific attributes)  shouldn't it better ?

I did originally implement a mechanism for the templates to be combined (i.e. inherit from one another), hence the name 'moveable' in the example. I removed that mechanism for a number of reasons, but left the example as-is. However, combining language level inheritance with an entity system is a big mistake. That is exactly what they're designed to avoid.
« Last Edit: February 11, 2014, 05:06:52 pm by Lee R »

therocode

  • Full Member
  • ***
  • Posts: 125
    • View Profile
    • Development blog
Re: Feather Kit - A C++ Game Framework
« Reply #29 on: February 13, 2014, 06:12:40 am »
Sure. You may do whatever you like with it. I don't require any credit.

Thanks!

I have now assimilated the code and it works fine. I also added an overload of the addPrimitive function which lets you add data types without providing a parser function like so:

factory.addDataType<float>("float");

In such a case, the type is provided using the template argument.

Thanks again! :) It will be interesting to use this in production code.