summaryrefslogtreecommitdiffhomepage
path: root/app/ECS
diff options
context:
space:
mode:
authorrealtradam <[email protected]>2021-05-14 05:48:50 -0400
committerrealtradam <[email protected]>2021-05-14 05:48:50 -0400
commit6a2996ceae968029be26ed7ebae8785dcfe877d2 (patch)
treef3d4d405f7e032fcabbb9711f75e266282d98295 /app/ECS
parent57bd7ec9da14b3e7e338184568a273ce602e1557 (diff)
downloadtypemon-code-6a2996ceae968029be26ed7ebae8785dcfe877d2.tar.gz
typemon-code-6a2996ceae968029be26ed7ebae8785dcfe877d2.zip
added ECS system
Diffstat (limited to 'app/ECS')
-rw-r--r--app/ECS/base_component.rb17
-rw-r--r--app/ECS/component_manager.rb20
-rw-r--r--app/ECS/components/00_test_component.rb16
-rw-r--r--app/ECS/components/01_based.rb16
-rw-r--r--app/ECS/entity_manager.rb61
-rw-r--r--app/ECS/system_manager.rb6
-rw-r--r--app/ECS/systems/00_movement.rb22
-rw-r--r--app/ECS/systems/01_flying.rb17
-rw-r--r--app/ECS/test.rb18
9 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