Class PlacementInjectorSystem
- Namespace
- GridPlacement.GDScript
- Assembly
- MoonBark.GridPlacement.GDScript.dll
Dependency injection system for the Grid Building Plugin.\n\nThis system automatically handles: 1. Dependency Injection: Wires the PlacementContainer into all nodes that implement resolve_placement_dependencies(p_config: PlacementContainer) 2. Automatic Validation: Validates the complete setup after injection and reports any configuration issues via the container's logger\n\nNo manual validation calls are required - the injector handles everything automatically after dependency injection is complete.\n\n[b]Modes[/b]\n\n[b]Global mode[/b] (default, no [code]scope_root[/code]): injects the entire scene tree. Connects to [code]tree.node_added[/code] to catch dynamically added nodes. Falls back to [code][tree.root][/code] when [code]injection_roots[/code] is empty. Session auto-registration with the host is enabled by default.\n\n[b]Scoped mode[/b] ([code]scope_root[/code] set via [code]set_session_scope()[/code]): injects only the subtree under [code]scope_root[/code]. Does NOT connect to the global [code]node_added[/code] signal. The controller/bootstrap is responsible for explicitly registering the session with the host (see [code]host_created[/code] signal). This is the preferred path for split-screen, per-controller, and explicit code-built setups.\n\n[b]Responsibility Boundaries[/b]\n\n- [code]PlacementSession[/code]: owns mutable state, config, contexts, logger (SSOT) - [code]GridPlacementHost[/code]: owns stateless runtime services and dispatch - [code]PlacementInjectorSystem[/code]: wires scene-authored nodes around a session subtree; does NOT own the container, the session, or runtime logic\n\n[b]Setup Requirements:[/b] - Assign a PlacementContainer resource to this injector - Ensure PlacementLevelContext and PlacementOwner are properly configured before the injector runs (usually in _ready() methods) - The injector will automatically validate after injection and log any issues\n\nUsage Example: gdscript # In your scene node: func resolve_placement_dependencies(p_config: PlacementContainer) -> void: _composition_container = p_config _logger = p_config.get_logger() # No validation call needed - injector handles it automatically \n\n[i]Nodes that implement resolve_placement_dependencies(p_config: PlacementContainer) will be injected automatically by this system.[/i]
class PlacementInjectorSystem extends PlacementSystemBase
Fields
INJECTION_META_KEY
const INJECTION_META_KEY: String = "gb_injection_meta"
RESOLVE_METHOD
const RESOLVE_METHOD: StringName = "resolve_placement_dependencies"
RESOLVE_METHOD_LEGACY
@deprecated Legacy 5.0 name. Nodes implementing only this method still get injected: the injector dispatches to it when the canonical method is absent.
const RESOLVE_METHOD_LEGACY: StringName = "resolve_gb_dependencies"
ORPHAN_MESSAGE
const ORPHAN_MESSAGE: String = "[ORPHANED NODE]"
Properties
session
Optional [PlacementSession] — when set, the injector creates a minimal [PlacementContainer] that delegates through the session. This is the preferred path for code-built/explicit setups.\n\n6.0.0-S Phase 5: when the injector creates a [GridPlacementHost] host, this session is auto-registered with the host's per-controller session registry (single-player convenience; controllers can register additional sessions for split-screen).
@export var session: PlacementSession
composition_container
Container services as the single source of truth for settings within it's scope for systems and other nodes concerned with grid building operations. [br][br]\n\n[b]Dependencies are injected out of this container by the PlacementInjectorSystem[/b]
@export var composition_container: PlacementContainer
injection_roots
Debug settings for logging and warnings. Note: runtime validation is intentionally NOT auto-run on _ready() because other game-level dependencies (GB level context, PlacementOwner, etc.) may not be fully settled. Call run_validation() from your world/initializer script after those dependencies are created and injected. Root nodes for injection. These nodes and any children node added will be injected by the PlacementInjectorSystem. Use this for scoping injection. If left empty, all nodes in the scene tree will be injected.
@export var injection_roots: Array[Node] = []
scope_root
Optional explicit scope root for session-scoped injection.
@export var scope_root: Node
auto_register_host_session
When [code]true[/code] (default), the injector automatically registers its session with the host's per-controller registry as a single-player convenience. Set to [code]false[/code] in scoped mode and connect to the [code]host_configured[/code] signal for explicit controller-owned registration.
@export var auto_register_host_session: bool = true
roots
var roots = get_injection_roots()
issues
var issues = composition_container.get_runtime_issues()
container_issues
var container_issues = composition_container.get_runtime_issues()
ok
var ok = validate_runtime()
issues
var issues = composition_container.get_runtime_issues()
issues
var issues = composition_container.get_runtime_issues()
was_injected
var was_injected: bool = inject_node(p_node)
message
var message: String = "[scope-child_entered_tree] added=%s injected=%s" % [p_node, was_injected]
system
var system = PlacementInjectorSystem.new(container)
container
var container = PlacementContainer.new()
injector
var injector = from_session(p_parent, p_session)
rule_count
var rule_count = 0
existing
var existing = p_node.get_meta(INJECTION_META_KEY)
meta
var meta = p_node.get_meta(INJECTION_META_KEY)
node_path
var node_path = p_node.get_path() if p_node.is_inside_tree() else ORPHAN_MESSAGE
msg
var msg = "[PlacementInjectorSystem] Node exiting: %-25s at %s" % [p_node.name, node_path]
bound_cb
var bound_cb = meta["_child_entered_cb"]
meta
var meta = p_node.get_meta(INJECTION_META_KEY)
meta
var meta = p_node.get_meta(INJECTION_META_KEY)
bound_cb
var bound_cb = meta["_child_entered_cb"]
bound_exit_cb
var bound_exit_cb = meta["_tree_exiting_cb"]
meta
var meta = p_node.get_meta(INJECTION_META_KEY)
meta
var meta = p_node.get_meta(INJECTION_META_KEY)
bound_exit_cb
var bound_exit_cb = meta["_tree_exiting_cb"]
tree
var tree = get_tree()
issues
var issues = composition_container.get_runtime_issues()
host_session
var host_session: PlacementSession = self.session
host
var host = GridPlacementHost.new()
roots
var roots = get_injection_roots()
placement_system
var placement_system = find_placement_system()
ps
var ps = root.find_child("PlacementSystem", true, false) as PlacementSystem
Methods
get_injection_roots
func get_injection_roots() -> Array[Node]:
Returns
validate_runtime
func validate_runtime() -> bool:
Returns
run_validation
func run_validation() -> bool:
Returns
get_editor_issues
func get_editor_issues() -> Array[String]:
Returns
get_runtime_issues
func get_runtime_issues() -> Array[String]:
Returns
is_scoped
func is_scoped() -> bool:
Returns
create_with_injection
static func create_with_injection(p_parent : Node, container: PlacementContainer) -> PlacementInjectorSystem:
Parameters
p_parentcontainer
Returns
from_session
static func from_session(p_parent: Node, p_session: PlacementSession) -> PlacementInjectorSystem:
Parameters
p_parentp_session
Returns
from_session_scoped
static func from_session_scoped(p_parent: Node, p_session: PlacementSession, p_scope_root: Node) -> PlacementInjectorSystem:
Parameters
p_parentp_sessionp_scope_root
Returns
set_session_scope
func set_session_scope(p_scope_root: Node, p_session: PlacementSession = null) -> void:
Parameters
p_scope_rootp_session
Returns
resolve_placement_dependencies
func resolve_placement_dependencies(p_config : PlacementContainer) -> void:
Parameters
p_config
Returns
inject_node
func inject_node(p_node: Node) -> bool:
Parameters
p_node
Returns
inject_recursive
func inject_recursive(p_node: Node) -> void:
Parameters
p_node
Returns
set_injection_meta
func set_injection_meta(p_node : Node) -> void:
Parameters
p_node
Returns
remove_injection_meta
func remove_injection_meta(p_node: Node) -> void:
Parameters
p_node
Returns
find_placement_system
func find_placement_system() -> PlacementSystem:
Returns
Events
initial_injection_completed
Emits when the initial scene injection is completed
signal initial_injection_completed()
node_injected
Emit whenever a node is injected
signal node_injected(node : Node)
host_configured
Emitted when the injector creates a [GridPlacementHost] host from its session. Controllers in scoped mode should connect to this signal to explicitly register their session with the host.
signal host_configured(host: GridPlacementHost)