using Godot; using System.Collections.Generic; namespace Rokojori { [Tool] [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/SensorManager.svg")] public partial class SensorManager: Node { [Export] public bool initializeOnReady = true; [Export] public Sensor[] sensors; [Export] public SensorGroup[] sensorGroups; [Export] public bool processSensors = false; [Export] public Node[] autoScanForSensors; List runners = new List(); List inputers = new List(); Dictionary sensorToRunner = new Dictionary(); public override void _Ready() { if ( ! initializeOnReady ) { return; } CreateRunners(); } public override void _Input( InputEvent ev ) { inputers.ForEach( ( inp )=> { inp._Input( ev ); } ); } public override void _Process( double delta ) { if ( Engine.IsEditorHint() || ! processSensors ) { return; } runners.ForEach( r => r.Update( (float) delta ) ); } public void Register( Sensor s, SensorInputHandler sih ) { var sensorRunner = sensorToRunner[ s ]; if ( sensorRunner.listeners.Contains( sih ) ) { return; } sensorRunner.listeners.Add( sih ); } public void Unregister( Sensor s, SensorInputHandler sih ) { var sensorRunner = sensorToRunner[ s ]; sensorRunner.listeners.Remove( sih ); } public static void Register( SensorInputHandler handler, params Sensor[] sensors ) { var sm = Unique.Get(); foreach ( var s in sensors ) { if ( s == null ) { continue; } ( handler as Node ).LogInfo( "Registrating" ); sm.Register( s, handler ); } } public static void Unregister( SensorInputHandler handler, params Sensor[] sensors ) { var sm = Unique.Get(); foreach ( var s in sensors ) { if ( s == null ) { continue; } ( handler as Node ).LogInfo( "Unregistrating" ); sm.Unregister( s, handler ); } } HashSet sensorsSet = new HashSet(); void AddSensor( Sensor s ) { if ( s == null || sensorsSet.Contains( s ) ) { return; } AddSensorsFrom( s ); sensorsSet.Add( s ); runners.Add( new SensorRunner( s ) ); } HashSet objects = new HashSet(); void AddSensorsFrom( object obj ) { if ( obj == null || objects.Contains( obj ) ) { return; } objects.Add( obj ); var sensors = ReflectionHelper.GetDataMemberValues( obj ); sensors.ForEach( s => { AddSensor( s ); } ); var sensorArrays = ReflectionHelper.GetDataMemberValues( obj ); sensorArrays.ForEach( s => { for ( int i = 0; i < s.Length; i++ ) { AddSensor( s[ i ] ); } } ); var resources = ReflectionHelper.GetDataMemberValues( obj ); resources.ForEach( r => AddSensorsFrom( r ) ); } void CreateRunners() { if ( sensors == null ) { sensors = new Sensor[]{}; } if ( sensorGroups == null ) { sensorGroups = new SensorGroup[]{}; } foreach ( var s in sensors ) { AddSensor( s ); } foreach ( var g in sensorGroups ) { foreach ( var s in g.sensors ) { AddSensor( s ); } } foreach ( var n in autoScanForSensors ) { Nodes.ForEach( n, cn=> AddSensorsFrom( cn ) ); } runners.ForEach( r => { sensorToRunner[ r.sensor ] = r; if ( r.sensor is iOnInputSensor oi ) { inputers.Add( oi ); } } ); this.LogInfo( "Created runners:", runners.Count ); } } }