Skip to content

Commit

Permalink
add_yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
konovod committed Dec 27, 2023
1 parent 0e22a96 commit 1fabc6c
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 5 deletions.
29 changes: 29 additions & 0 deletions spec/yaml_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,32 @@ it "load world from yaml" do
world2.query(Supported).first.getSupported.should eq Supported.new(1, 2)
world2.query(Unsupported).should be_empty
end

it "add entities from yaml" do
world1 = ECS::World.new
world1.new_entity.add(Supported.new(1, 2))
world1.new_entity.add(Unsupported.new(3, 4))
yaml = world1.to_yaml
world2 = ECS::World.new
world2.new_entity.add(Supported.new(10, 20))
world2.add_yaml(yaml)
world2.query(Supported).to_a.map(&.getSupported).should eq [Supported.new(10, 20), Supported.new(1, 2)]
world2.query(Unsupported).should be_empty
end

record WithLink < ECS::YAMLComponent, link : ECS::Entity

it "keep links to entities" do
world1 = ECS::World.new
ent1 = world1.new_entity
ent2 = world1.new_entity
ent3 = world1.new_entity
ent2.add(Supported.new(1, 2))
ent1.add(WithLink.new(ent3))
ent3.add(WithLink.new(ent2))
yaml = world1.to_yaml
world2 = ECS::World.new
world2.new_entity.add(Supported.new(10, 20))
world2.add_yaml(yaml)
world2.query(WithLink).first.getWithLink.link.getWithLink.link.getSupported.should eq Supported.new(1, 2)
end
21 changes: 20 additions & 1 deletion src/myecs.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ module ECS
# :nodoc:
COMP_INDICES = {} of Component.class => Int32

# :nodoc:
WORLD_BEING_LOADED = {} of Fiber => ECS::World

# Component - container for user data without / with small logic inside.
# All components should be inherited from `ECS::Component`
@[Packed]
Expand Down Expand Up @@ -116,6 +119,16 @@ module ECS
@world.check_gc_entity @id
end

def to_cannon_io(io)
io.write_bytes self.id
io
end

def self.from_cannon_io(io) : self
id = io.read_bytes(EntityID)
self.new(WORLD_BEING_LOADED[Fiber.current], id)
end

macro finished
{% for obj in Component.all_subclasses %}
{% obj_name = obj.id.split("::").last.id %}
Expand Down Expand Up @@ -708,7 +721,13 @@ module ECS
def decode(io)
@free_entities = Cannon.decode(io, typeof(@free_entities))
@count_components = Cannon.decode(io, typeof(@count_components))
@pools.each &.decode(io)
raise "recurrent deserialization is not supported" if WORLD_BEING_LOADED.has_key?(Fiber.current)
WORLD_BEING_LOADED[Fiber.current] = self
begin
@pools.each &.decode(io)
ensure
WORLD_BEING_LOADED.delete Fiber.current
end
end
end

Expand Down
25 changes: 21 additions & 4 deletions src/yaml.cr
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ module ECS
struct Entity
def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)
name = String.new(ctx, node)
storage = ctx.read_alias(FakeNode.new("_ecs_storage"), EntitiesHash)
# storage = ctx.read_alias(FakeNode.new("_ecs_storage"), EntitiesHash)
object_id, _ = ctx.@anchors["_ecs_storage"]
storage = Pointer(Void).new(object_id).as(EntitiesHash)
storage.storage[name]
end

Expand Down Expand Up @@ -157,16 +159,31 @@ module ECS

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)
world = self.new
storage = EntitiesHash.new(world)
ctx.record_anchor(FakeNode.new("_ecs_storage"), storage)
names = EntitiesHash.new(world)
ctx.record_anchor(FakeNode.new("_ecs_storage"), names)
stubs = Hash(String, Array(YAMLComponent)).new(ctx, node)
stubs.each do |k, v|
ent = storage.storage[k]
ent = names.storage[k]
v.each do |comp|
ent.add(comp)
end
end
world
end

def add_yaml(io, names : EntitiesHash? = nil)
names = EntitiesHash.new(self) unless names
ctx = YAML::ParseContext.new
node = YAML::Nodes.parse(io).nodes.first
ctx.record_anchor(FakeNode.new("_ecs_storage"), names)
stubs = Hash(String, Array(YAMLComponent)).new(ctx, node)
stubs.each do |k, v|
ent = names.storage[k]
v.each do |comp|
ent.add(comp)
end
end
self
end
end
end

0 comments on commit 1fabc6c

Please sign in to comment.