1using System.Numerics;
2
3namespace Fjord.Scenes;
4
5public class Entity
6{
7 internal SceneKeyboard Keyboard;
8 internal SceneMouse Mouse;
9 internal SceneInput Input;
10 internal Scene Parent;
11 internal string name;
12 internal bool excludeFromInspector = false;
13
14 internal List<Component> Components = new();
15
16 internal Entity()
17 {
18 name = this.GetType().Name;
19 Keyboard = new("")!;
20 Mouse = new("")!;
21 Input = new("")!;
22 Parent = default(Scene)!;
23 }
24
25 public Entity(Scene parent)
26 {
27 this.name = this.GetType().Name;
28 this.Parent = parent;
29 this.Keyboard = parent.Keyboard;
30 this.Mouse = parent.Mouse;
31 this.Input = parent.Input;
32
33 this.Components.Add(new Transform());
34 }
35
36 public Entity Name(string name)
37 {
38 this.name = name;
39 return this;
40 }
41
42 public Entity ExcludeFromInspector(bool exclude)
43 {
44 this.excludeFromInspector = exclude;
45 return this;
46 }
47
48 public Entity Add(Component component)
49 {
50 component.Keyboard = Keyboard;
51 component.Mouse = Mouse;
52 component.Input = Input;
53 component.ParentEntity = this;
54 component.ParentScene = this.Parent;
55 this.Components.Add(component);
56 try {
57 this.Components[this.Components.Count - 1].AwakeCall();
58 } catch(Exception e) {
59 Debug.Log(LogLevel.Error, $"Component \"{this.Components[this.Components.Count - 1].GetType().Name}\" awake crashed!");
60 Debug.Log(LogLevel.Message, e.ToString());
61 }
62 return this;
63 }
64
65 public void Remove<T>()
66 {
67 Component? comp = this.Components.Find((comp) => comp.GetType() == typeof(T));
68 if(comp != null) {
69 try {
70 comp.SleepCall();
71 } catch(Exception e) {
72 Debug.Log(LogLevel.Error, $"Component \"{comp.GetType().Name}\" sleep crashed!");
73 Debug.Log(LogLevel.Message, e.ToString());
74 }
75 this.Components.Remove(comp);
76 }
77 }
78
79 public T Get<T>()
80 {
81 var scene = Components.Find((comp) => comp.GetType() == typeof(T));
82 if (scene != null)
83 return (T)(dynamic)scene;
84 else
85 throw new Exception($"Component '{typeof(T)}' doesn't exist in entity");
86 }
87
88 public bool TryGet<T>(out T component)
89 {
90 var scene = Components.Find((comp) => comp.GetType() == typeof(T));
91 if (scene != null) {
92 component = (T)(dynamic)scene;
93 return true;
94 } else {
95 component = default(T)!;
96 return false;
97 }
98 }
99
100 public float DistanceTo(Entity e)
101 {
102 return Helpers.PointDistance(Get<Transform>().Position, e.Get<Transform>().Position);
103 }
104
105 public float DistanceTo(Transform e)
106 {
107 return Helpers.PointDistance(Get<Transform>().Position, e.Position);
108 }
109
110 public float DistanceTo(Vector2 e)
111 {
112 return Helpers.PointDistance(Get<Transform>().Position, e);
113 }
114
115 public float DirectionTo(Entity e)
116 {
117 return Helpers.PointDirection(Get<Transform>().Position, e.Get<Transform>().Position);
118 }
119
120 public float DirectionTo(Transform e)
121 {
122 return Helpers.PointDirection(Get<Transform>().Position, e.Position);
123 }
124
125 public float DirectionTo(Vector2 e)
126 {
127 return Helpers.PointDirection(Get<Transform>().Position, e);
128 }
129
130 internal void AwakeCall()
131 {
132 foreach(Component comp in Components)
133 {
134 comp.AwakeCall();
135 }
136 }
137
138 internal void SleepCall()
139 {
140 foreach(Component comp in Components)
141 {
142 comp.SleepCall();
143 }
144 }
145
146 internal void UpdateCall()
147 {
148 foreach(Component comp in Components)
149 {
150 comp.UpdateCall();
151 }
152 }
153}