// // Node C# sugar // // Authors: // Miguel de Icaza (miguel@xamarin.com) // // Copyrigh 2015 Xamarin INc // using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Reflection; namespace Urho { internal partial class NodeHelper { [DllImport (Consts.NativeImport, CallingConvention=CallingConvention.Cdecl)] internal extern static IntPtr urho_node_get_components(IntPtr node, int code, int recursive, out int count); } public partial class Node { static Node[] ZeroArray = new Node[0]; public Node[] GetChildrenWithComponent (bool recursive = false) where T: Component { Runtime.ValidateRefCounted(this); var stringhash = Runtime.LookupStringHash (typeof (T)); int count; var ptr = NodeHelper.urho_node_get_components (handle, stringhash.Code, recursive ? 1 : 0, out count); if (ptr == IntPtr.Zero) return ZeroArray; var res = new Node[count]; for (int i = 0; i < count; i++){ var node = Marshal.ReadIntPtr(ptr, i * IntPtr.Size); res [i] = Runtime.LookupObject (node); } if (Component.IsDefinedInManagedCode()) //is not really efficient, but underlying Urho3D knows nothing about components defined in C# return res.Where(c => c.GetComponent() != null).ToArray(); return res; } public T CreateComponent (StringHash type, CreateMode mode = CreateMode.Replicated, uint id = 0) where T:Component { Runtime.ValidateRefCounted(this); var ptr = Node_CreateComponent (handle, type.Code, mode, id); return Runtime.LookupObject (ptr); } public void RemoveComponent () { Runtime.ValidateRefCounted(this); var stringHash = Runtime.LookupStringHash (typeof (T)); RemoveComponent (stringHash); } public T CreateComponent (CreateMode mode = CreateMode.Replicated, uint id = 0) where T:Component { Runtime.ValidateRefCounted(this); var component = Activator.CreateInstance(); AddComponent(component, id, mode); return component; } /// /// Add a pre-created component. /// public void AddComponent (Component component, uint id = 0) { Runtime.ValidateRefCounted(this); AddComponent (component, id, CreateMode.Replicated); } /// /// Create a child scene node (with specified ID if provided). /// public Node CreateChild (string name = "", uint id = 0, CreateMode mode = CreateMode.Replicated) { Runtime.ValidateRefCounted(this); return CreateChild (name, mode, id); } /// /// Add a child scene node at a specific index. If index is not explicitly specified or is greater than current children size, append the new child at the end. /// public void AddChild(Node node) { Runtime.ValidateRefCounted(this); AddChild(node, uint.MaxValue); } /// /// Move the scene node in the chosen transform space. /// public void Translate(Vector3 delta) { Runtime.ValidateRefCounted(this); Translate(delta, TransformSpace.Local); } public T GetComponent (bool recursive = false) where T : Component { Runtime.ValidateRefCounted(this); return (T)Components.FirstOrDefault(c => c is T); } } }