Class: EcsRails::Registry
- Inherits:
-
Object
- Object
- EcsRails::Registry
- Defined in:
- lib/ecs_rails/registry.rb
Overview
Records which components each entity declares. See RFC-0002.
The registry is a process-wide singleton (EcsRails.registry) populated by the
component DSL (RFC-0004) at class-load time, and read by generators,
delegation and — later — systems.
Reload safety is the whole design constraint. In development Rails does not mutate a reloaded class in place: it removes the constant and autoloads a brand-new Class object under the same name. A registry that held class objects would pin the old, orphaned constants forever, and every lookup would hand back classes the rest of the app has already forgotten. So nothing here stores a Class: entries are keyed by class name, and names are resolved back to live constants via #constantize at read time.
Defined Under Namespace
Classes: Declaration
Instance Method Summary collapse
-
#clear! ⇒ self
Resets the registry.
-
#components_for(entity_class) ⇒ Array<Declaration>
The declarations for an entity, in declaration order.
-
#entities_for(component_class) ⇒ Array<Class<EcsRails::Entity>>
Every entity class declaring this component, as live class objects.
-
#initialize ⇒ Registry
constructor
A new instance of Registry.
-
#register(entity_class:, component_class:, options: {}) ⇒ Declaration
Records one declaration.
-
#restore(snapshot) ⇒ self
Replaces the declarations with a previously taken #snapshot.
-
#snapshot ⇒ Hash
An opaque snapshot of the current declarations, for save/restore around a block that mutates the registry — chiefly tests that
clear!the process-wide singleton and would otherwise wipe declarations that host/app classes made at load time.
Constructor Details
#initialize ⇒ Registry
Returns a new instance of Registry.
86 87 88 |
# File 'lib/ecs_rails/registry.rb', line 86 def initialize clear! end |
Instance Method Details
#clear! ⇒ self
Resets the registry. Used between tests and by the Railtie’s to_prepare.
161 162 163 164 |
# File 'lib/ecs_rails/registry.rb', line 161 def clear! @declarations = {} self end |
#components_for(entity_class) ⇒ Array<Declaration>
The declarations for an entity, in declaration order.
Resolution is lazy, so this never raises for a stale entry; asking the returned Declaration for #component_class does. That is deliberate: a dangling name means the registry has drifted out of sync with the app, and silently dropping the entry would make generators emit an incomplete schema and delegation quietly stop working. #clear! is the supported way to drop entries, and the Railtie calls it on every reload.
Only the entity’s own declarations — inheritance is walked on read by DSL#component_declarations, not copied down here.
138 139 140 141 |
# File 'lib/ecs_rails/registry.rb', line 138 def components_for(entity_class) declarations = @declarations[name_for(entity_class)] declarations ? declarations.dup : [] end |
#entities_for(component_class) ⇒ Array<Class<EcsRails::Entity>>
Every entity class declaring this component, as live class objects.
148 149 150 151 152 153 154 155 156 |
# File 'lib/ecs_rails/registry.rb', line 148 def entities_for(component_class) component_name = name_for(component_class) @declarations.each_value.with_object([]) do |declarations, entities| declarations.each do |declaration| entities << declaration.entity_class if declaration.component_class_name == component_name end end end |
#register(entity_class:, component_class:, options: {}) ⇒ Declaration
Records one declaration. Returns the Declaration.
Raises DuplicateComponent if this entity already declares this component —
per ADR-0005 a component appears at most once per entity, and RFC-0004
relies on the raise to catch a doubled component line at class-load time.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/ecs_rails/registry.rb', line 104 def register(entity_class:, component_class:, options: {}) entity_name = name_for(entity_class) component_name = name_for(component_class) declarations = (@declarations[entity_name] ||= []) if declarations.any? { |declaration| declaration.component_class_name == component_name } raise DuplicateComponent, "#{entity_name} already declares #{component_name}" end declaration = Declaration.new( entity_class_name: entity_name, component_class_name: component_name, options: ) declarations << declaration declaration end |
#restore(snapshot) ⇒ self
Replaces the declarations with a previously taken #snapshot.
183 184 185 186 |
# File 'lib/ecs_rails/registry.rb', line 183 def restore(snapshot) @declarations = snapshot.transform_values(&:dup) self end |
#snapshot ⇒ Hash
An opaque snapshot of the current declarations, for save/restore around a
block that mutates the registry — chiefly tests that clear! the
process-wide singleton and would otherwise wipe declarations that
host/app classes made at load time. Declaration is frozen and holds only
strings, so a shallow dup of the arrays is a safe, cheap copy.
174 175 176 |
# File 'lib/ecs_rails/registry.rb', line 174 def snapshot @declarations.transform_values(&:dup) end |