New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature Request, Multi type system #528
Comments
If anyone doesn't have any complaints against this proposal I'd love to give the implementation a go |
I like the idea. Would APIs like Potentially this will trigger an extra array allocation when assigning a string to |
option would be keep |
Highlights;
Part 1: How it should effect API@bendmorris To clarify some things The argument for multiple types is so that an element can label itself as more than one type. This would allow for accessing all entities which are a part of a group.
The problem with APIs like Entity.collide is an interesting situation. I prefer to not introduce breaking changes with this added feature and I would like for unnecessary allocations to be avoided if possible. As an immediate implementation, it would make sense to change the signature to accept either a string or an EntityType abstract. As a possible solution for removing unnecessary allocation and removing the performance loss of runtime type-checking, we could turn the function into a macro which inlines a call to the old I guess that means it will become an improved version of collideTypes with compile-time benefits. Part 2: The problem with Lineage VS GroupsOriginal IntentionMy original intention for this "Multi Type" system was actually for describing type-lineage in a way that doesn't require constantly updating the lineage from the root object or some elevated location. It's simple for inheriting instances to track this. That's where my proposal of a "multi-type" system was more akin to entities belonging to multiple groups, and not an idea not related to lineage. So the real problem, I never considered, was how do we correctly define a relationship that represents type lineage and a group of types seamlessly? Why lineage doesn't work this wayBecause my original intentions were to describe type relations(lineage), and not a group of types, the currently proposed way simply doesn't have a concrete way of defining what the base type is. When it comes to lineage there is a multi-directional relation from any type that is not the root type. However, if you were to use this system for describing an entity for belong to a group of unrelated types - it's usable. My intention was originally to add the ability to retrieve a type and its descending types if any. So here's exactly the problem that arises when you try solving that problem via just including an inherited type in a group of types.
Solving the problem (Type inheritance with Type Groups)This problem is tricky because type inheritance and having a group of types are two different functionalities that work together. I originally theorized two ways of solving this problem, then the first solution just seemed too obvious to suggest an alternative option. Solution Expands on the original proposition and should integrate seamlessly with HXP as is. The current proposition enables us to conveniently have an entity associate itself under multiple, unrelated, groups. We can say that an entity's type is an array of strings, plainly put. Or we can abstract it so that it can be either an array of strings or a single string - but that's not the highlight here. We can go one level further and instead of making it an array of strings, we can make it an array of EntityTypes. EntityType will be an abstract which is used as a string. Macro approach: This EntityType system will need to abstract a little bit further past constructing relations at compile time by also being able to convert types(strings) to flattened arrays of all their extended children. This will make using the references easier to interface with. The implementation revolving storing and removing entities by type will most likely need to be updated to account for types actually being arrays of strings. Based on how I imagined the references working, though, anything that's actually retrieving by type should be mostly unchanged. Naive approach: The rest is more or less the same. Extra Note: |
Upon further discussion in the Discord, we have come up with the following alternative. It uses enums (and could probably be modified to use abstract enums) to recursively describe an actual SolidType
enum SolidType
{
Base(name:String);
Inherited(name:String, ancestors:Array<SolidType>);
} This describes a tree structure given that the user plays nice and doesn't do circular inheritance (there are of course ways to check that this is the case, possibly via macro). This could also theoretically be made into a typed enum with a Type groupingIn addition to this modification, the field The usual mechanic of allowing either a SolidType or an array of SolidType remains, much like at the moment SolidType handles single Strings and arrays of String. Type inheritanceType inheritance is allowed trivially from the construction of Storage and traversalAs previously mentionned, To do so, we use a function that returns whether a certain type inherits from another. using Lambda;
function typeInherits(from:SolidType, ref:String) : Bool
{
switch(from)
{
case Base(name):
return name == ref;
case Inherited(name, ancestors):
return name == ref || ancestors.exists(x => findType(x, ref));
}
} This can be safely used in places where string equality is used, while making sure that for loops aren't broken, but instead return values are accumulated. Worthy of note, and made obvious by this example, is the fact that types do not need to be addressed using their enum constructor. Namely, all of the various |
Reason:
Unless I'm mistaken, entities can only have one type. This is perfectly fine and can work with any project, but coming from other engines where being able to easily associate an instance with more than one "group/type" is a real life-improvement. Even something as simple as being able to get elements by inheritance could save some extra overhead on custom project levels.
Request:
My proposal is a feature which enables entities the ability to associate themselves with more than one type.
Applications:
Potential Suggestions:
My generalized approach, to prevent legacy code from being broken and to reduce end user complexity, will be done by defining an entity's type as an abstract data type. An abstract type that can work with strings, or an array of strings.
Use:
Things to keep in mind:
The text was updated successfully, but these errors were encountered: