Skip to content

Commit

Permalink
added more tests to the abstractcomponent interface
Browse files Browse the repository at this point in the history
  • Loading branch information
louisponet committed May 7, 2023
1 parent 8c62cd3 commit 7d66bca
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 145 deletions.
7 changes: 6 additions & 1 deletion src/Overseer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -53,4 +53,9 @@ export prepare, singleton, valid_entities

# Components
export swap_order!





end # module
56 changes: 4 additions & 52 deletions src/component.jl
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
100 changes: 8 additions & 92 deletions test/test_components.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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
Expand Down

0 comments on commit 7d66bca

Please sign in to comment.