From 7d66bca1216d3986faa71dd3822c25eb0eaf6e55 Mon Sep 17 00:00:00 2001 From: louisponet Date: Sun, 7 May 2023 15:21:28 +0200 Subject: [PATCH] added more tests to the abstractcomponent interface --- src/Overseer.jl | 7 ++- src/component.jl | 56 ++-------------------- test/test_components.jl | 100 ++++------------------------------------ 3 files changed, 18 insertions(+), 145 deletions(-) diff --git a/src/Overseer.jl b/src/Overseer.jl index c62d772..8f27a5a 100644 --- a/src/Overseer.jl +++ b/src/Overseer.jl @@ -42,7 +42,7 @@ include("group.jl") include("system.jl") include("ledger.jl") include("iteration.jl") - +include("interfaces.jl") export AbstractLedger, Ledger, System, Stage, Component, PooledComponent, Entity, entity, last_entity export @component, @pooled_component @@ -53,4 +53,9 @@ export prepare, singleton, valid_entities # Components export swap_order! + + + + + end # module diff --git a/src/component.jl b/src/component.jl index 0b8c93f..f599529 100644 --- a/src/component.jl +++ b/src/component.jl @@ -1,62 +1,14 @@ -using Test - -struct TestCompData - t::Int -end - -# AbstractComponent Interface -""" -Tests whether an [`AbstractComponent`](@ref) satisfies the interface. -""" -function test_abstractcomponent_interface(::Type{T}) where {T<:AbstractComponent} - c = T{TestCompData}() - - @test eltype(c) <: TestCompData - if hasfield(T, :indices) - @test c.indices isa Indices - else - @test indices_iterator(c) isa IndicesIterator - @test reverse_indices_iterator(c) isa ReverseIndicesIterator - end - - @test isempty(c) - @test length(c) == 0 - c[Entity(1)] = TestCompData(1) - c[Entity(2)] = TestCompData(1) - @test Entity(2) in c - @test length(c) == 2 == size(c)[1] == length(c.indices) == length(data(c)) - - @test c[Entity(2)] isa TestCompData - - @test entity(c, 1) isa EntityState{Tuple{T{TestCompData}}} - @test pop!(c, Entity(2)) == TestCompData(1) - @test pop!(c) == EntityState(Entity(1), TestCompData(1)) - @test isempty(c) - - c[Entity(1)] = TestCompData(1) - c[Entity(2)] = TestCompData(2) - - # Needed for order swapping - data(c)[1], data(c)[2] = data(c)[2], data(c)[1] - @test c[Entity(2)] == TestCompData(1) - @test c[Entity(1)] == TestCompData(2) - - c[Entity(1)], c[Entity(2)] = c[Entity(2)], c[Entity(1)] - @test c[Entity(1)] == TestCompData(1) - @test c[Entity(2)] == TestCompData(2) - - @test iterate(c)[1] isa TestCompData - empty!(c) - @test isempty(c) -end - ## AbstractComponent Interface: For new components that have a standard component underneath, just overload `component` to point to it +# Run the Overseer.test_abstractcomponent_interface on your new component type component(c::AbstractComponent) = MethodError(component, c) @inline data(c::AbstractComponent) = data(component(c)) @inline indices(c::AbstractComponent) = indices(component(c)) @inline data_index(c::AbstractComponent, args...) = data_index(component(c), args...) + +Base.Ref(c::AbstractComponent, e::AbstractEntity) = Ref(c, data_index(c,e)) + """ in(entity, component) diff --git a/test/test_components.jl b/test/test_components.jl index 3a1a79a..43dff4b 100644 --- a/test/test_components.jl +++ b/test/test_components.jl @@ -20,98 +20,9 @@ end end for CT in (Component, PooledComponent) - @testset "Interface: $CT" begin - @testset "AbstractComponent interface" begin Overseer.test_abstractcomponent_interface(CT) end - - entities1 = [[Entity(i) for i in 2:2:10]; [Entity(i) for i in 134:274:7592]] - - c = CT{Test1}() - - @testset "Creation and in" begin - for e in entities1 - c[e] = eltype(c)(e.id) - end - for e in entities1 - @test in(e, c) - end - end - - @testset "Basic iteration" begin - it = @entities_in(c) - @test iterate(it)[1] == EntityState(Entity(2), (c[Entity(2)],)) - s = 0 - for e in it - s += e.p - end - @test s == sum(x->c[x].p, eachindex(c)) - - c[EntityState(Entity(2), (c[Entity(2)],))] = Test1(321) - @test c[EntityState(Entity(2), (c[Entity(2)],))] == Test1(321) - - c[Entity(2)] = Test1(2) - - @suppress begin - show(EntityState(Entity(2), (c[Entity(2)],))) - end - - t = EntityState(Entity(2), (c[Entity(2)],)) - t.p = 4 - @test c[t].p == 4 - @test c[Entity(2)].p == 4 - t.p = 2 - end - - @testset "Basic map, filter" begin - @test map(e -> e.p, c) == map(e -> c[e].p, eachindex(c)) - @test filter(e -> e.p < 5, c) == c[filter(e -> c[e].p < 5, eachindex(c))] - @test map(e -> e.p, @entities_in(c)) == map(e -> c[e].p, eachindex(c)) - @test filter(e -> e.p < 5, @entities_in(c)) == filter(e -> e.p < 5, collect(@entities_in(c))) - end - - @testset "Component manipulation" begin - @test pop!(c, Entity(10)) == Test1(10) - - @test length(c) == length(entities1) - 1 - @test c[1] == Test1(2) - - c[Entity(13)] = Test1(50) - @test c[Entity(13)] == Test1(50) - - pop!(c, Entity(13)) - @test !in(Entity(13), c) - - # swap_ordering - c[Entity(12)] = Test1() - - @test_throws BoundsError swap_order!(c, Entity(14), Entity(15)) - @test_throws BoundsError swap_order!(c, Entity(13), Entity(14)) - - e1 = Entity(134) - e2 = Entity(8) - orig1 = c[e1] - orig2 = c[e2] - - orig_id1 = c.indices[e1.id] - orig_id2 = c.indices[e2.id] - - swap_order!(c, e1, e2) - @test c[e2] == orig2 - @test c[e1] == orig1 - - @test c.indices[e2.id] == orig_id1 - @test c.indices[e1.id] == orig_id2 - - es = map(x->x.e, @entities_in(c)) - cur = c[es] - pvec = reverse(es) - permute!(c, pvec) - @test reverse(cur) == c[es] - - empty!(c) - @test isempty(c) - end - end + Overseer.test_abstractcomponent_interface(CT) end + for (CT1, CT2) in ((Component, PooledComponent, Component, PooledComponent), (Component, PooledComponent, PooledComponent, Component)) @testset "Combined: $CT1, $CT2" begin entities1 = [Entity(i) for i in 2:2:10] @@ -121,13 +32,18 @@ for (CT1, CT2) in ((Component, PooledComponent, Component, PooledComponent), (Co c1 = CT1{Test1}() c2 = CT1{Test2}() c3 = CT2{Test3}() - c4 = CT2{Test4}() + c4 = CT2{Test4}() + + for (c, es) in zip((c1, c2, c3, c4), (entities1, entities2, entities3, entities4)) for e in es c[e] = eltype(c)() end end + @suppress begin + show(EntityState(Entity(2), (c1[Entity(2)],))) + end for (c, es) in zip((c1, c2, c3, c4), (entities1, entities2, entities3, entities4)) for e in es