Skip to content
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

Groups & AnyOf unexpected behaviour. #378

Closed
vaudevillian opened this issue Apr 12, 2017 · 3 comments
Closed

Groups & AnyOf unexpected behaviour. #378

vaudevillian opened this issue Apr 12, 2017 · 3 comments
Labels

Comments

@vaudevillian
Copy link

I was updating from 0.36.0 to 0.40.0 yesterday and now one system seems to not work as intended.
Maybe it has something to do with the change of flag components without any variables, but maybe I just misunderstood the AnyOf concept. I try to explain:

I have a few ReactiveSystems that should trigger if "either component A or component B has been added" (AnyOf). It's not necessary that both components have been added (AllOf).
Now Component A is a flag that gets (re)added all the time while Component B stays the same for most of the time.

I traced the code and when Component A gets removed, the any-of matcher will output "true" in Group::HandleEntity. This wont lead to an "OnEntityRemoved" and hence wont lead to an "OnEntityAdded" as soon as Component A gets re-added. That doesn't sound incorrect so far, yet it does lead to a different behaviour than I was used to before I upgraded to 0.40.0.

What I am expecting is that the ReactiveSystem triggers as soon as one of both components gets added, independently if the other component exists or not. But this doesn't seemed to be the case right now and I'm imaginging, that it did work with 0.36.0. When I read the source code I came to the conclusion that I might understood the AnyOf concept kind of wrong. Did I?

@vaudevillian
Copy link
Author

vaudevillian commented Apr 12, 2017

Addition:
By just adding
public bool value;
to the component it does work again as expected. So I assume it has something to do with empty components.

Another Addition:
It only works when components get replaced. By merely adding a component the ReactiveSystems wont trigger.

@sschmid
Copy link
Owner

sschmid commented Apr 20, 2017

Hey, I'm not aware of any changes from 0.36.0 to 0.40.0. It should behave the same.
Maybe two notes, one on flag components and one on AnyOf as a trigger:

1. Flag Components:

Setting a flag component multiple times to a value, e.g.

entity.isMovable = true;
entity.isMovable = true;
entity.isMovable = true;

won't trigger if the entity was already movable. See Match-One - GameMovableComponent

Only changes will trigger. Not changing the value by setting it to what it already is is not considered a change.

2. AnyOf as a trigger in ReactiveSystem

tl;dr; don't use it, use this:

instead of

// DON'T DO THIS

protected override Collector<GameEntity> GetTrigger(IContext<GameEntity> context) {
    return context.CreateCollector(GameMatcher.AnyOf(GameMatcher.Asset, GameMatcher.Destroyed));
}

do this

protected override Collector<GameEntity> GetTrigger(IContext<GameEntity> context) {
    return new Collector<GameEntity>(
        new [] {
            context.GetGroup(GameMatcher.Asset),
            context.GetGroup(GameMatcher.Destroyed)
        },
        new [] {
            GroupEvent.Removed,
            GroupEvent.Added
        }
    );
}

We often call this a multi reactive system, because it reacts to multiple things, e.g. when Asset gets removed OR Destroyed has been added.

I'm pretty sure, that is what you want to achieve when you use AnyOf. The thing with AnyOf is, that's it might be confusing. It works correctly, but most likely not as you expect.
Example:
Trigger AnyOf(A, B)

What you expect:

  • A gets added - will trigger
  • B gets added - will trigger

What actually happens

  • A gets added - will trigger
  • B gets added - won't trigger

Why? Because the entity is already in the group AnyOf(A, B) so adding B won't affect group belonging and therefore won't trigger.

Summary:
Be alarmed when using AnyOf as a trigger and consider using the multi reactive approach which will work as expected + gives you additional control about the group event (added / removed)

I hope that helps

@vaudevillian
Copy link
Author

Hi,

first of all: thanks for your time. This is quite complicated and it took myself some time to get back into the topic. During the time I was using those multi reactive systems, which worked fine so far.
Yet I came back and checked what you said about AnyOf groups and tried to understand.

Theoretically I totally understand, but thats not exactly how it seems to happen sometimes.

What actually happens

A gets added - will trigger
B gets added - won't trigger

That is not true if you do replace components. In Context::updateGroupsComponentReplaced will be called "UpdateEntity" instead of "HandleEntity", which itself doesnt consider the matcher.
And since flag components doesnt replace they behave differently from replaceable components. Maybe thats the reason why I misunderstood the AnyOf concepts at the beginning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

No branches or pull requests

2 participants