I have components for default pool and also "Core" pool
I am getting these mixed up in reactive systems.
Entitieswith the wrong components get returned in Execute()
I am not sure if this is a bug or am I using the matcher incorrectly.
I want the reactive system to process events of adding of entities that have Core component
ConsumeProgress on them selves. The error occurs in foreach loop then using .consumeProgress
components of returned entity since returned entities do not have ConsumeProgress components.
Seems to me like returned entities only have component from the "default" pool with the same
componentId (index) as the requested component in "core" pool.
public class ConsumeProgressSystem : IReactiveSystem, IEnsureComponents
{
public TriggerOnEvent trigger { get { return CoreMatcher.ConsumeProgress.OnEntityAdded();} }
public IMatcher ensureComponents { get { return CoreMatcher.ConsumeProgress; } }
public void Execute(List<Entity> entities)
{
foreach (var e in entities)
{
// Using brake at this point shows that I got entities
// with ProgressListener components and no ConsumeProgress
// So it fails at this point and drops out an error:
// InvalidCastException: Cannot cast from source type to destination type.
var targetEntity = e.consumeProgress.Target;
targetEntity.ReplaceProgress(
targetEntity.progress.progress - e.consumeProgress.Amount);
}
}
}
// <auto-generated>
public static class ComponentIds {
public const int ProgressListener = 0; //these are the components that I DO get
public const int TotalComponents = 1;
public static readonly string[] componentNames = {
"ProgressListener"
};
public static readonly System.Type[] componentTypes = {
typeof(ProgressListenerComponent)
};
}
// <auto-generated>
public static class CoreComponentIds {
public const int ConsumeProgress = 0; //these are the components I WANT to get
public const int Position = 1;
public const int Progress = 2;
public const int Resource = 3;
public const int Tick = 4;
public const int UIPosition = 5;
public const int UIResource = 6;
public const int UIView = 7;
public const int View = 8;
public const int TotalComponents = 9;
public static readonly string[] componentNames = {
"ConsumeProgress",
"Position",
"Progress",
"Resource",
"Tick",
"UIPosition",
"UIResource",
"UIView",
"View"
};
public static readonly System.Type[] componentTypes = {
typeof(ConsumeProgressComponent),
typeof(PositionComponent),
typeof(ProgressComponent),
typeof(ResourceComponent),
typeof(TickComponent),
typeof(UIPositionComponent),
typeof(UIResourceComponent),
typeof(UIViewComponent),
typeof(ViewComponent)
};
}
Can you show me how you create ConsumeProgressSystem. It seems to me you just used the wrong pool for that
e.g.
pool.CreateSystem<ConsumeProgressSystem>();
// vs
corePool.CreateSystem<ConsumeProgressSystem>();
If that's the case the system will actually trigger when ProgressListener is added. That's why you get InvalidCastException. Internally, both have the same component index, so you basically observing a component with index 0.
Ah yes, @sschmid's response gave me a proper direction to the cause of the issue, although it was not exactly the described case. I was incorrectly adding entities with default pool component (ProgressListener) to a different core pool. That lead to matching that component as another one (ConsumeProgress) with the same component index in core pool.
It would be nice if we could we warned when adding different pool components to entities in another pool.
[Core]
public class CoreStuffComponent : IComponent
{
public float x;
}
public class DefaultPoolStuffComponent : IComponent
{
public float x;
}
// this should be fine
Pools.core.CreateEntity().AddCoreStuff(3f);
// but this should throw some warnings
Pools.core.CreateEntity().AddDefaultPoolStuff(3f);
We can consider this issue fixed. Explained, actually.
Thanks @sschmid