| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- using System;
- using System.Linq;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using static System.Reflection.IntrospectionExtensions;
- namespace AtomicEngine
- {
- public partial class Scene : Node
- {
- internal override void PostNativeUpdate()
- {
- SubscribeToEvent<NodeAddedEvent>(this, e =>
- {
- //Log.Info($"Node ADDED: {e.Node.Name}");
- });
- SubscribeToEvent<NodeRemovedEvent>(this, e =>
- {
- //Log.Info($"Node REMOVED: {e.Node.Name}");
- });
- SubscribeToEvent<CSComponentLoadEvent>(this, HandleCSComponentLoad);
- SubscribeToEvent<ComponentAddedEvent>(this, HandleComponentAdded);
- SubscribeToEvent<ComponentRemovedEvent>(this, HandleComponentRemoved);
- // Update variable timestep logic
- SubscribeToEvent<SceneUpdateEvent>(this, HandleSceneUpdate);
- // Update scene subsystems. If a physics world is present, it will be updated, triggering fixed timestep logic updates
- SubscribeToEvent<SceneSubsystemUpdateEvent>(this, HandleSceneSubsystemUpdate);
- // Update transform smoothing
- SubscribeToEvent<UpdateSmoothingEvent>(this, HandleUpdateSmoothing);
- // Post-update variable timestep logic
- SubscribeToEvent<ScenePostUpdateEvent>(this, HandleScenePostUpdate);
- }
- // Update variable timestep logic
- void HandleSceneUpdate(SceneUpdateEvent e)
- {
- // Handle Start
- if (cscomponentStart.Count > 0)
- {
- var started = new List<CSComponent>();
- foreach (var csc in cscomponentStart.ToList())
- {
- if (!csc.IsEnabled())
- {
- continue;
- }
- // mark as started whether or not a Start method exists
- csc.started = true;
- started.Add(csc);
- CSComponentInfo info;
- if (CSComponentCore.csinfoLookup.TryGetValue(csc.GetType(), out info))
- {
- if (info.StartMethod != null)
- {
- info.StartMethod.Invoke(csc, null);
- }
- }
- }
- foreach (var csc in started)
- {
- cscomponentStart.Remove(csc);
- }
- }
- // Handle Scene Update
- Object[] args = new Object[1] { e.TimeStep };
- foreach (var item in cscomponents.ToList())
- {
- var info = item.Key;
- var UpdateMethod = info.UpdateMethod;
- if (UpdateMethod == null)
- continue;
- foreach (var csc in item.Value.ToList())
- {
- if (!csc.Started || !csc.IsEnabled())
- continue;
- UpdateMethod.Invoke(csc, args);
- }
-
- }
- }
- // Update scene subsystems. If a physics world is present, it will be updated, triggering fixed timestep logic updates
- void HandleSceneSubsystemUpdate(SceneSubsystemUpdateEvent e)
- {
- }
- // Update transform smoothing
- void HandleUpdateSmoothing(UpdateSmoothingEvent e)
- {
- }
- // Post-update variable timestep logic
- void HandleScenePostUpdate(ScenePostUpdateEvent e)
- {
- Object[] args = new Object[1] { e.TimeStep };
- foreach (var item in cscomponents)
- {
- var info = item.Key;
- var PostUpdateMethod = info.PostUpdateMethod;
- if (PostUpdateMethod == null)
- continue;
- foreach (var csc in item.Value)
- {
- if (!csc.Started || !csc.IsEnabled())
- continue;
- PostUpdateMethod.Invoke(csc, args);
- }
- }
- }
- void HandlePhysicsPreStep(PhysicsPreStepEvent e)
- {
- Object[] args = new Object[1] { e.TimeStep };
- foreach (var item in cscomponents)
- {
- var info = item.Key;
- var PhysicsPreStepMethod = info.PhysicsPreStepMethod;
- if (PhysicsPreStepMethod == null)
- continue;
- foreach (var csc in item.Value)
- {
- if (!csc.Started || !csc.IsEnabled())
- continue;
- PhysicsPreStepMethod.Invoke(csc, args);
- }
- }
- }
- void HandlePhysicsPostStep(PhysicsPostStepEvent e)
- {
- Object[] args = new Object[1] { e.TimeStep };
- foreach (var item in cscomponents)
- {
- var info = item.Key;
- var PhysicsPostStepMethod = info.PhysicsPostStepMethod;
- if (PhysicsPostStepMethod == null)
- continue;
- foreach (var csc in item.Value)
- {
- if (!csc.Started || !csc.IsEnabled())
- continue;
- PhysicsPostStepMethod.Invoke(csc, args);
- }
- }
- }
- void HandleComponentRemoved(ComponentRemovedEvent e)
- {
- Component component;
- try
- {
- // will throw if component isn't a known native
- component = e.Component;
- }
- catch
- {
- return;
- }
- if (component.GetType() == typeof(PhysicsWorld) || component.GetType() == typeof(PhysicsWorld2D))
- {
- UnsubscribeFromEvent<PhysicsPreStepEvent>();
- UnsubscribeFromEvent<PhysicsPostStepEvent>();
- }
- if (component.GetType().GetTypeInfo().IsSubclassOf(typeof(CSComponent)))
- {
- var csc = (CSComponent)component;
- CSComponentInfo info;
- if (!CSComponentCore.csinfoLookup.TryGetValue(csc.GetType(), out info))
- {
- return;
- }
- cscomponentStart.Remove(csc);
- List<CSComponent> cslist;
- if (!cscomponents.TryGetValue(info, out cslist))
- {
- return;
- }
- cslist.Remove(csc);
- }
- }
- void HandleCSComponentLoad(CSComponentLoadEvent e)
- {
- var scriptMap = e.scriptMap;
- // Get the NativeInstance as an IntPtr, otherwise we would be wrapping as a CSComponent
- IntPtr csnative = scriptMap.GetVoidPtr("NativeInstance");
- IntPtr fieldValues = IntPtr.Zero;
- if (scriptMap.Contains("FieldValues"))
- fieldValues = scriptMap.GetVoidPtr("FieldValues");
- CSComponentInfo csinfo;
- if (!CSComponentCore.componentCache.TryGetValue(e.ClassName, out csinfo))
- {
- return;
- }
- NativeCore.NativeContructorOverride = csnative;
- var component = (CSComponent)Activator.CreateInstance(csinfo.Type);
- NativeCore.VerifyNativeContructorOverrideConsumed();
- if (fieldValues != IntPtr.Zero)
- csinfo.ApplyFieldValues(component, fieldValues);
- AddCSComponent(component);
- }
- void AddCSComponent(CSComponent csc)
- {
- CSComponentInfo info;
- if (!CSComponentCore.csinfoLookup.TryGetValue(csc.GetType(), out info))
- {
- Log.Error("Scene.HandleComponentAdded - unable to get CSComponentInfo");
- return;
- }
- List<CSComponent> cslist;
- if (!cscomponents.TryGetValue(info, out cslist))
- {
- cslist = cscomponents[info] = new List<CSComponent>();
- }
- if (cslist.Contains(csc))
- {
- throw new InvalidOperationException("Scene.HandleComponentAdded - CSComponent already added to component list");
- }
- cslist.Add(csc);
- if (cscomponentStart.Contains(csc))
- {
- throw new InvalidOperationException("Scene.HandleComponentAdded CSComponent already added to start list");
- }
- if (csc.started)
- {
- throw new InvalidOperationException("Scene.HandleComponentAdded CSComponent already started");
- }
- cscomponentStart.Add(csc);
- }
- void HandleComponentAdded(ComponentAddedEvent e)
- {
- Component component;
- try
- {
- // will throw if component isn't a known native
- component = e.Component;
- }
- catch
- {
- return;
- }
-
- // Check null (CSComponent) or other abstract component
- if (component == null)
- {
- return;
- }
- // Log.Info($"Component {component.TypeName} ADDED From Node {e.Node.Name}");
- if (component.GetType() == typeof(PhysicsWorld) || component.GetType() == typeof(PhysicsWorld2D))
- {
- SubscribeToEvent<PhysicsPreStepEvent>(component, HandlePhysicsPreStep);
- SubscribeToEvent<PhysicsPostStepEvent>(component, HandlePhysicsPostStep);
- }
- // CSComponent
- if (component.GetType().GetTypeInfo().IsSubclassOf(typeof(CSComponent)))
- {
- var csc = (CSComponent)component;
- AddCSComponent(csc);
- }
- }
- Dictionary<CSComponentInfo, List<CSComponent>> cscomponents = new Dictionary<CSComponentInfo, List<CSComponent>>();
- List<CSComponent> cscomponentStart = new List<CSComponent>();
- }
- }
|