Hello guys…
Happy today to provide you the latest version of ReactiveECS.jl (look at this post if you don’t know yet the package.). Adding some powerful features to fills all the remaining gaps. Without further ado, let’s look at the new features:
- Optimized Performances : With less types instabilities and better data representation
- Advanced Event System: Built on Notifyers.jl, supporting merging, filtering, one-shot listeners, and prioritized events.
- Hierarchical Relationships: Managed via NodeTree.jl with BFS/DFS traversal.
- Profiling Tools: Built-in debugging and performance visualization.
- Refined API: For a more straight forward utilisation
Example code
using ReactiveECS
# This will create a new component
# And set boilerplates for us
# The constructor is just the name passed here plus the suffix "Component"
@component Health begin
hp::Int
end
@component Transform begin
x::Float32
y::Float32
end
@component Physic begin
velocity::Float32
end
@system PhysicSystem begin
delta::Float32
end
@system RenderSystem
function ReactiveECS.run!(world, sys::PhysicSystem, data)
E = world[sys] # Our data
indices::Vector{Int} = data.value # The indices of the entities requested by the system
L = length(indices)
transforms = E.Transform # A struct array of transform components
physics = E.Physic # A struct array of physic components
x_pos = transforms.x # A vector of all the x fields of the transform components
velo = physics.velocity
dt::Float32 = sys.delta
@inbounds for i in indices
x_pos[i] += velo[i]*dt
end
return transforms # This data will be passed to the system listening to this one
end
function ReactiveECS.run!(world, ::RenderSystem, pos)
for i in eachindex(pos)
t = pos[i]
println("Rendering entity at position ($(t.x), $(t.y))")
end
end
physic_sys = PhysicSystem()
render_sys = RenderSystem()
ecs = ECSManager()
subscribe!(ecs, physic_sys, (TransformComponent, PhysicComponent))
listen_to(physic_sys,render_sys)
# Creating 4 entity
# We pass as keywork argument the component of the entity
create_entity!(ecs; Health = HealthComponent(100), Transform = TransformComponent(1.0,2.0))
e1 = create_entity!(ecs; Health = HealthComponent(150), Transform = TransformComponent(1.0,2.0))
# This entity will have e1 as parent
e2 = create_entity!(ecs,e1; Health = HealthComponent(50), Transform = TransformComponent(-5.0,0.0), Physic = PhysicComponent(1.0))
e3 = create_entity!(ecs; Health = HealthComponent(50), Transform = TransformComponent(-5.0,0.0), Physic = PhysicComponent(1.0))
# We launch the system. Internally, it's creating an asynchronous task
run_system!(physic_sys)
run_system!(render_sys)
N = 3
for i in 1:N
println("FRAME $i")
# We dispatch data and each system will execute his `run!` function
dispatch_data(ecs)
blocker(ecs) # Will make the process wait for all systems to finish
yield()
sleep(0.016)
end
I will be glad to hear your feedback and enhancement !!
The oackage is still young and could hepl some contributions.