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

[Question] What is the point of OnEntityUpdated? #44

Closed
JamesMcMahon opened this issue Sep 26, 2015 · 7 comments
Closed

[Question] What is the point of OnEntityUpdated? #44

JamesMcMahon opened this issue Sep 26, 2015 · 7 comments
Labels

Comments

@JamesMcMahon
Copy link
Contributor

Hello again,

I have another question about the design of Entitas. What is the intended use of OnEntityUpdated? I understand what it is actually can be used for but I am unclear about its intended purpose, given that Entitas use a faux immutable paradigm that fires on Add or Remove on any entity change.

Here is the implementation that I am refering to in Group.cs:

public void UpdateEntity(Entity entity, int index, IComponent previousComponent, IComponent newComponent) {
    if (_entities.Contains(entity)) {
        if (OnEntityRemoved != null) {
            OnEntityRemoved(this, entity, index, previousComponent);
        }
        if (OnEntityAdded != null) {
            OnEntityAdded(this, entity, index, newComponent);
        }
        if (OnEntityUpdated != null) {
            OnEntityUpdated(this, entity, index, previousComponent, newComponent);
        }
    }
}

So I get that if you want to cover your bases and have a catch all method for both adds and removes you could use update. But the CreateGameBoardCacheSystem class in the MatchOne example makes me think I may be missing something.

snip:

    var gameBoardElements = pool.GetGroup(Matcher.AllOf(Matcher.GameBoardElement, Matcher.Position));
    gameBoardElements.OnEntityAdded += onGameBoardElementAdded;
    gameBoardElements.OnEntityUpdated += onGameBoardElementUpdated;
    gameBoardElements.OnEntityRemoved += onGameBoardElementRemoved;
}

void onGameBoardElementAdded(Group group, Entity entity, int index, IComponent component) {
    var grid = _pool.gameBoardCache.grid;
    var pos = entity.position;
    grid[pos.x, pos.y] = entity;
    _pool.ReplaceGameBoardCache(grid);
}

void onGameBoardElementUpdated(Group group, Entity entity, int index, IComponent previousComponent, IComponent newComponent) {
    var prevPos = previousComponent as PositionComponent;
    var newPos = (PositionComponent)newComponent;
    var grid = _pool.gameBoardCache.grid;
    grid[prevPos.x, prevPos.y] = null;
    grid[newPos.x, newPos.y] = entity;
    _pool.ReplaceGameBoardCache(grid);
}

void onGameBoardElementRemoved(Group group, Entity entity, int index, IComponent component) {
    var pos = component as PositionComponent;
    if (pos == null) {
        pos = entity.position;
    }
    var grid = _pool.gameBoardCache.grid;
    grid[pos.x, pos.y] = null;
    _pool.ReplaceGameBoardCache(grid);
}

Maybe this is just a poor usage choice in the example project but it looks like it would be redundant to use OnEntityUpdated here as both OnEntityRemoved and OnEntityAdded have already been called at this point.

I was using this example as a basis for some of my own systems and I saw this oddity and wanted to make sure I wasn't missing behavior.

@JamesMcMahon
Copy link
Contributor Author

Another possible oddity, for Matchers instead of OnEntityUpdate it's OnEntityAddedOrRemoved. If these methods represent the same functionality they should probably have the same method name.

@sschmid
Copy link
Owner

sschmid commented Oct 2, 2015

I think you're right. In this case we can remove

gameBoardElements.OnEntityUpdated += onGameBoardElementUpdated

since replacing a component will also call OnEntityRemoved and OnEntityAdded. So it's redundant... I'll remove it from the example.

@sschmid
Copy link
Owner

sschmid commented Oct 2, 2015

OnEntityAddedOrRemoved means it triggers when added OR when removed from the group.
To recap:

Adding a component to an entity might result in the entity being added to a group. This will trigger OnEntityAdded

Replacing the component will trigger OnEntityRemoved, OnEntityAdded, OnEntityUpdated

Removing the component will trigger OnEntityRemoved

Usually reactive systems are interested in changes in the group thus triggering OnEntityAdded. In my experience it's a rare case when you actually want to trigger OnEntityAddedOrRemoved, meaning reacting on any change in the group, e.g AccelerateSystem.cs

@JamesMcMahon
Copy link
Contributor Author

Makes sense. I appreciate the explanation.

@ifshuaishuai
Copy link

I noticed OnEntityUpdated not function well when i change value in Unity inspector, when value changed, previousComponent is equals to newComponent.Same as OnEntityRemoved, when OnEntityRemoved's event is called, component's value(string type) has already be changed.I don't know if it is an issue.

@sschmid
Copy link
Owner

sschmid commented Feb 29, 2016

I think you're right. The entity inspector just calls entity.ReplaceComponent() without using the componentPool and providing both the previous and the new component like the generated methods do.
I'll work on a fix.
Thanks for letting me know! :)

@raveneer
Copy link

I destroyed my entity than entity's last component removed.
after long testing, I understand the mechanism (casting component Arg to removed component)
this is very confusing...
how about adding simple event?
like

Group.OnEntityRemoved(Entity entity);

have a good day.

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

4 participants