Hi
I will explain my question on MobAnimationState of SiO2 bullet-char demo as an example.
In a networking game where we have multiple scenes, each client wants to listen for entities related to the scene it’s avatar is attached to.
I modified MobAnimationState based on my networked game, and I doubt if the way I am using to filter MobilityContainer and ActionContainer is right and efficient or is there a better way ?
Mobility and CharacterAction entities are buffed (parented) to mob entities and mob entities are buffed to a scene. I want to only get Mobility and CharacterAction entities which are happening in the scene that player is but there is no direct component on these entities to indicate to which scene they are belong. So to filter them I can see two ways :
1- Add a new SceneID component to each of those Mobility and CharacterAction entities then filter directly based on scene id. But then you need to update the SceneID component when character attaches to another scene.
2- Use a second filter, First find all mobs which are in the specified scene (where client avatar is attached) then filter Mobility and CharacterAction entities based on those mob ids. (I am using this approach in client side app states) .
I created a MobAnimationContainer which find all mobs in the specified scene
private void onSceneChanged(SceneChangeEvent event) {
if (isEnabled()) {
mobAnimations.setFilter(Filters.fieldEquals(Buff.class, "target", event.getSceneId()));
}
}
then set a filter on MobilityContainer and ActionContainer.
private class MobAnimationContainer extends EntityContainer<MobAnimation> {
Map<EntityId, ComponentFilter<Buff>> filters = new HashMap<>();
public MobAnimationContainer(EntityData ed) {
super(ed, Filters.fieldEquals(Buff.class, "target", EntityId.NULL_ID), Buff.class, BodyPosition.class);
}
@Override
protected void setFilter(ComponentFilter filter) {
super.setFilter(filter);
}
@Override
protected MobAnimation[] getArray() {
return super.getArray();
}
@Override
protected MobAnimation addObject(Entity entity) {
filters.put(entity.getId(), Filters.and(Buff.class,
Filters.fieldEquals(Buff.class, "state", DefaultBuffStates.ENABLED),
Filters.fieldEquals(Buff.class, "target", entity.getId())));
resetFilters();
MobAnimation result = new MobAnimation(entity.getId());
return result;
}
@Override
protected void updateObject(MobAnimation mobAnimation, Entity entity) {
}
@Override
protected void removeObject(MobAnimation t, Entity entity) {
filters.remove(entity.getId());
resetFilters();
}
public void resetFilters() {
if (!filters.isEmpty()) {
mobilities.setFilter(Filters.or(Buff.class, filters.values().toArray(new ComponentFilter[filters.size()])));
actions.setFilter(Filters.or(Buff.class, filters.values().toArray(new ComponentFilter[filters.size()])));
}
}
}
and this is how MobilityContainer and ActionContainer look like
@SuppressWarnings("unchecked")
private class MobilityContainer extends EntityContainer<BuffedComponent<Mobility>> {
public MobilityContainer(EntityData ed) {
super(ed, Filters.fieldEquals(Buff.class, "target", EntityId.NULL_ID), Buff.class, Mobility.class);
}
@Override
protected void setFilter(ComponentFilter filter) {
super.setFilter(filter);
}
@Override
protected BuffedComponent<Mobility> addObject(Entity e) {
Buff p = e.get(Buff.class);
Mobility m = e.get(Mobility.class);
addMobility(p.getTarget(), m);
return new BuffedComponent<>(p.getTarget(), m);
}
@Override
protected void updateObject(BuffedComponent<Mobility> object, Entity e) {
}
@Override
protected void removeObject(BuffedComponent<Mobility> object, Entity e) {
removeMobility(object.parentId, object.value);
}
}
///
@SuppressWarnings("unchecked")
private class ActionContainer extends EntityContainer<BuffedComponent<CharacterAction>> {
public ActionContainer(EntityData ed) {
super(ed, Filters.fieldEquals(Buff.class, "target", EntityId.NULL_ID), Buff.class, CharacterAction.class);
}
@Override
protected void setFilter(ComponentFilter filter) {
super.setFilter(filter);
}
@Override
protected BuffedComponent<CharacterAction> addObject(Entity e) {
Buff p = e.get(Buff.class);
CharacterAction a = e.get(CharacterAction.class);
addAction(p.getTarget(), a);
return new BuffedComponent<>(p.getTarget(), a);
}
@Override
protected void updateObject(BuffedComponent<CharacterAction> object, Entity e) {
}
@Override
protected void removeObject(BuffedComponent<CharacterAction> object, Entity e) {
removeAction(object.parentId, object.value);
}
}
Is this the right way and efficient way to do it ?