diff --git a/Entitas/Entitas/Interfaces/IMatcher.cs b/Entitas/Entitas/Interfaces/IMatcher.cs index 09d87be6b..4aaf82ed7 100644 --- a/Entitas/Entitas/Interfaces/IMatcher.cs +++ b/Entitas/Entitas/Interfaces/IMatcher.cs @@ -1,7 +1,10 @@ namespace Entitas { + public delegate bool MatcherFilter(Entity entity); + public interface IMatcher { int[] indices { get; } + IMatcher Where(MatcherFilter filter); bool Matches(Entity entity); } } diff --git a/Entitas/Entitas/Matcher/Matcher.cs b/Entitas/Entitas/Matcher/Matcher.cs index 40f9d77f9..b2d7fb71f 100644 --- a/Entitas/Entitas/Matcher/Matcher.cs +++ b/Entitas/Entitas/Matcher/Matcher.cs @@ -23,6 +23,8 @@ public int[] indices { int[] _anyOfIndices; int[] _noneOfIndices; + MatcherFilter _filter; + Matcher() { } @@ -46,11 +48,17 @@ public INoneOfMatcher NoneOf(params IMatcher[] matchers) { return NoneOf(mergeIndices(matchers)); } + public IMatcher Where(MatcherFilter filter) { + _filter = filter; + return this; + } + public bool Matches(Entity entity) { var matchesAllOf = _allOfIndices == null || entity.HasComponents(_allOfIndices); var matchesAnyOf = _anyOfIndices == null || entity.HasAnyComponent(_anyOfIndices); var matchesNoneOf = _noneOfIndices == null || !entity.HasAnyComponent(_noneOfIndices); - return matchesAllOf && matchesAnyOf && matchesNoneOf; + var passesFilter = _filter == null || _filter(entity); + return matchesAllOf && matchesAnyOf && matchesNoneOf && passesFilter; } int[] mergeIndices() { diff --git a/Tests/Tests/Entitas/describe_Matcher.cs b/Tests/Tests/Entitas/describe_Matcher.cs index 5ef85976c..829031234 100644 --- a/Tests/Tests/Entitas/describe_Matcher.cs +++ b/Tests/Tests/Entitas/describe_Matcher.cs @@ -424,6 +424,29 @@ void when_creating_matcher() { mX.GetHashCode().should_be(mY.GetHashCode()); }; }; + + context["when filtering"] = () => { + + IMatcher m = null; + + before = () => m = Matcher.AllOf(CID.ComponentD).Where(entity => { + var component = (NameAgeComponent)entity.GetComponent(CID.ComponentD); + return component.age > 30; + }); + + it["only contains entities passing the filter condition"] = () => { + var e1 = this.CreateEntity(); + var nameAge1 = new NameAgeComponent { name = "Max", age = 42 }; + e1.AddComponent(CID.ComponentD, nameAge1); + + var e2 = this.CreateEntity(); + var nameAge2 = new NameAgeComponent { name = "Jack", age = 24 }; + e2.AddComponent(CID.ComponentD, nameAge2); + + m.Matches(e1).should_be_true(); + m.Matches(e2).should_be_false(); + }; + }; } static IMatcher allOfAB() {