Josh @ Dreamland
|
|
Reply #15 Posted on: November 03, 2013, 09:35:06 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
Yes, where M is a small constant. Using a bit set, it drops to O(N × M/64) = O(N × M), assuming you can compact all the combinations together in one word. I'm not fundamentally opposed to a bitset, but I don't particularly care for RTTI.
Using queues trades checks for memory. Instead of iterating the smallest queue of objects and checking that (A) all component bits are set or (B) the entity is in all the correct queues, we just iterate the queue with the correct combination. This is good when the number of components needed in a single combination is large, but the number of necessary unique combinations is small.
In the general case, it's terrible, as the number of combinations grows exponentially in the number of behaviors. You'd want to use queues when you need to iterate all tanks which use tank logic and have tank physics and a position, and all ninjas which use ninja logic and have ninja physics and a position, but no other combinations. In this case, you'd have as many as four checks depending on which bits were assigned to which component, but you'd only need two additional queues to which such tanks and ninjas could add themselves, thus saving all checks and iterating in O(N), N being the number of matches.
Again, these queues are only possible when this information is known at compile time. It's fine if the tank and ninja objects can remove these behaviors at runtime, as long as we can create the checks to manage those queues when this happens at compile time.
Knowing combinations at compile time helps in the completely dynamic case, too, as it enables you to reduce the number of checks to O(N × M/64), where M is the number of behaviors in your combination instead of the total number of behaviors.
|
|
« Last Edit: November 03, 2013, 09:41:35 pm by Josh @ Dreamland »
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #17 Posted on: November 06, 2013, 07:48:35 pm |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
In a dynamic bitset, [snip]entity.components | system.required_components[/snip] is O(N). One OR for each 64 bits. So only one OR is required if you have less than 65 components.
Typically the number of components you need in a combination will be small. If not, you might want to rethink how you're developing your system. A function depending directly on some thirty classes isn't very attractive, to say the least.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
Ideka
|
|
Reply #18 Posted on: November 29, 2013, 12:44:45 am |
|
|
Joined: Apr 2011
Posts: 85
|
I don't know, one OR for each 64 bits sounds good to me. By the way what did you mean by this? The point was that his system is no more of a revolution to me than Java people constantly spouting [snip=java]if (entity instanceof SomeComponent)[/snip] or C# people doing the same with [snip]if (entity is SomeComponent)[/snip]. I get that you're attached to this idea; I don't get why you don't see the remarkable similarities between it and multiple inheritance. You're looking at the small picture of what it allows; the big picture is this:
Operation X Subtype A ---Operation 1 ---Operation 2 ---Operation 3 Subtype B ---Operation 1 ---Operation 2 ---Operation 3 Subtype C ---Operation 1 ---Operation 2 ---Operation 3 Operation Y Subtype A, as well Subtype D ---Operation 1 ---Operation 2 ---Operation 3 Operation Z Subtype B, as well Subtype E ---Operation 1 ---Operation 2 ---Operation 3 Subtype F ---Operation 1 ---Operation 2 ---Operation 3
I didn't get what you meant at the time and forgot to ask.
|
|
|
Logged
|
|
|
|
Josh @ Dreamland
|
|
Reply #19 Posted on: November 29, 2013, 10:35:17 am |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
I was pointing out that using multiple inheritance does not stop you from constructing methods that work with instances of each "component" class. You were showing that inheritance is not what you want by pointing out that class have functions instead of functions working with classes. It works either way. Java functions take advantage of functions requiring some interface all the time, and it doesn't matter what you hand the function as long as it implements that interface. Yes, an interface will have functions, but that doesn't mean it can't work like the component system.
In other words, while it's more correct to put the doTankAI method in the tank interface, there's nothing stopping you from putting it in a non-member function, which is necessary if you want a doNinjaTankAI method.
So in that outline, Operation Y might be doNinjaTankAI, Subtype A might be Tank, Subtype D might be Ninja, and their operations 1-3 might be getTankHealth, getNinjaHealth, fireCannon, throwStars, whatever.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|
Josh @ Dreamland
|
|
Reply #21 Posted on: December 12, 2013, 11:00:46 am |
|
|
Prince of all Goldfish
Location: Pittsburgh, PA, USA Joined: Feb 2008
Posts: 2950
|
That doesn't really concern ENIGMA's implementation, as the expectation would be that ENIGMA handles it for you.
I'll point out that ENIGMA's event system, which is not component-based, functions the same way.
|
|
|
Logged
|
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble "I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
|
|
|
|