diff options
| -rw-r--r-- | app/ECS/base_component.rb | 17 | ||||
| -rw-r--r-- | app/ECS/component_manager.rb | 20 | ||||
| -rw-r--r-- | app/ECS/components/00_test_component.rb | 16 | ||||
| -rw-r--r-- | app/ECS/components/01_based.rb | 16 | ||||
| -rw-r--r-- | app/ECS/entity_manager.rb | 61 | ||||
| -rw-r--r-- | app/ECS/system_manager.rb | 6 | ||||
| -rw-r--r-- | app/ECS/systems/00_movement.rb | 22 | ||||
| -rw-r--r-- | app/ECS/systems/01_flying.rb | 17 | ||||
| -rw-r--r-- | app/ECS/test.rb | 18 | ||||
| m--------- | sprites/non-free | 0 |
10 files changed, 193 insertions, 0 deletions
diff --git a/app/ECS/base_component.rb b/app/ECS/base_component.rb new file mode 100644 index 0000000..a40ef52 --- /dev/null +++ b/app/ECS/base_component.rb @@ -0,0 +1,17 @@ +class ECS + class BaseComponent + class <<self + def data + @data ||= {} + end + + def add(entity_id, **args) + data[entity_id] = new(**args) + end + + def delete(entity_id) + data.delete entity_id + end + end + end +end diff --git a/app/ECS/component_manager.rb b/app/ECS/component_manager.rb new file mode 100644 index 0000000..e64bc21 --- /dev/null +++ b/app/ECS/component_manager.rb @@ -0,0 +1,20 @@ +require_relative './base_component' +Dir[File.join(__dir__, 'components', '*.rb')].sort.each { |file| require file } + +class ECS + class Components + class <<self + def entity_destroyed(entity_id) + constants.each do |component| + component.delete(entity_id) unless (component.id & ECS::Entity.signatures[entity_id]).zero? + end + end + + def entity_created(entity_id) + constants.each do |component| + const_get(component.to_s).add(entity_id) unless (const_get(component.to_s).id & ECS::Entity.signatures[entity_id]).zero? + end + end + end + end +end diff --git a/app/ECS/components/00_test_component.rb b/app/ECS/components/00_test_component.rb new file mode 100644 index 0000000..0906fc8 --- /dev/null +++ b/app/ECS/components/00_test_component.rb @@ -0,0 +1,16 @@ +class ECS + class Components + class TestComponent < ECS::BaseComponent + def self.id + @id = '0001'.to_i(2) + end + + attr_accessor :x, :y + + def initialize(x: 0, y: 0) + @x = x + @y = y + end + end + end +end diff --git a/app/ECS/components/01_based.rb b/app/ECS/components/01_based.rb new file mode 100644 index 0000000..fe564ca --- /dev/null +++ b/app/ECS/components/01_based.rb @@ -0,0 +1,16 @@ +class ECS + class Components + class Based < ECS::BaseComponent + def self.id + @id = '0010'.to_i(2) + end + + attr_accessor :x, :y + + def initialize(x: 0, y:0) + @x = x + @y = y + end + end + end +end diff --git a/app/ECS/entity_manager.rb b/app/ECS/entity_manager.rb new file mode 100644 index 0000000..06f73cd --- /dev/null +++ b/app/ECS/entity_manager.rb @@ -0,0 +1,61 @@ +class ECS + class Entity + attr_accessor :id + + def initialize(signature = 0) + @id = ECS::Entity.generate_new_id + self.class.all.push self + self.class.signatures.push signature + ECS::Components.entity_created(@id) + end + + class <<self + # All entities that exist + def all + @all ||= [] + end + + def id_queue + @id_queue ||= [] + end + + def generate_new_id + if id_queue.empty? + all.size + else + id_queue.shift + end + end + + # What components a given entity uses + def signatures + @signatures ||= [] + end + + def destroy_entity(entity_id) + if all[entity_id].nil? + puts 'Entity can not be destroyed, id out of bounds' + elsif entity_id < all.size - 1 + ECS::Components.constants.each do |constant| + unless (signatures[entity_id] & ECS::Components::const_get(constant).id).zero? + ECS::Components::const_get(constant).delete(entity_id) + end + end + all[entity_id] = nil + signatures[entity_id] = nil + id_queue.push entity_id + elsif entity_id == all.size - 1 + ECS::Components.constants.each do |constant| + unless (signatures[entity_id] & ECS::Components::const_get(constant).id).zero? + ECS::Components::const_get(constant).delete(entity_id) + end + end + all.pop + signatures.pop + else + puts 'Unknown error with destroy_entity, entity not destroyed' + end + end + end + end +end diff --git a/app/ECS/system_manager.rb b/app/ECS/system_manager.rb new file mode 100644 index 0000000..53aa46b --- /dev/null +++ b/app/ECS/system_manager.rb @@ -0,0 +1,6 @@ +Dir[File.join(__dir__, 'systems', '*.rb')].sort.each { |file| require file } + +class ECS + class Systems + end +end diff --git a/app/ECS/systems/00_movement.rb b/app/ECS/systems/00_movement.rb new file mode 100644 index 0000000..ced0343 --- /dev/null +++ b/app/ECS/systems/00_movement.rb @@ -0,0 +1,22 @@ +class ECS + class Systems + class Movement + def self.run + ECS::Components::TestComponent.data.each do |key, data| + puts "Entity ID: #{key}" + unless (ECS::Components::Based.id - ECS::Entity.signatures[key]).zero? + unless (ECS::Components::Based.id & ECS::Entity.signatures[key]).zero? + puts "Based Data: " + puts "eks: #{ECS::Components::Based.data[key].x += 2}" + puts "why: #{ECS::Components::Based.data[key].y += 2}" + end + end + puts "Movement:" + puts "x: #{data.x += 1}" + puts "y: #{data.y += 1}" + puts "---" + end + end + end + end +end diff --git a/app/ECS/systems/01_flying.rb b/app/ECS/systems/01_flying.rb new file mode 100644 index 0000000..493e999 --- /dev/null +++ b/app/ECS/systems/01_flying.rb @@ -0,0 +1,17 @@ +class ECS + class Systems + class Based + def self.run + ECS::Components::Based.data.each do |key, data| + if ECS::Components::Based.id == ECS::Entity.signatures[key] + puts "Entity ID: #{key}" + puts "ONLY Based Data: " + puts "eks: #{ECS::Components::Based.data[key].x += 3}" + puts "why: #{ECS::Components::Based.data[key].y += 3}" + puts "---" + end + end + end + end + end +end diff --git a/app/ECS/test.rb b/app/ECS/test.rb new file mode 100644 index 0000000..2ab5be1 --- /dev/null +++ b/app/ECS/test.rb @@ -0,0 +1,18 @@ +require_relative './entity_manager.rb' +require_relative './component_manager.rb' +require_relative './system_manager.rb' + +move = '0001'.to_i(2) +base = '0010'.to_i(2) +both = '0011'.to_i(2) +ECS::Entity.new(move) +ECS::Entity.new(base) +ECS::Entity.new(both) + +3.times do + ECS::Systems.constants.each do |constant| + puts "|----#{constant.to_s.upcase}----|" + ECS::Systems::const_get(constant).run + end + #ECS::Entity.destroy_entity(ECS::Entity.all.last.id) unless ECS::Entity.all.empty? +end diff --git a/sprites/non-free b/sprites/non-free -Subproject c267467bc90f06bc770962a5000c02680daa8f9 +Subproject 93a45d7807376400c7d6a46f2516df2b1ea3334 |
