Polyphase Game Engine
Loading...
Searching...
No Matches
Node.h
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <vector>
5
6#include "PolyphaseAPI.h"
7#include "Object.h"
8#include "Assertion.h"
9#include "EngineTypes.h"
10#include "Property.h"
11#include "Stream.h"
12#include "Factory.h"
13#include "Maths.h"
14#include "NetDatum.h"
15#include "NetFunc.h"
16#include "ScriptUtils.h"
17#include "ScriptAutoReg.h"
18#include "Signals.h"
19#include "Assets/StaticMesh.h"
20
21#include "Bullet/btBulletCollisionCommon.h"
22
23#include <unordered_map>
24#include <unordered_set>
25
26class Node;
27class Scene;
28class World;
29class Script;
30
31#define DECLARE_NODE(Class, Parent) \
32 DECLARE_FACTORY(Class, Node); \
33 DECLARE_OBJECT(Class, Parent); \
34 DECLARE_SCRIPT_LINK(Class, Parent, Node) \
35 typedef Parent Super;
36
37#define DEFINE_NODE(Class, Parent) \
38 DEFINE_FACTORY(Class, Node); \
39 DEFINE_OBJECT(Class); \
40 DEFINE_SCRIPT_LINK(Class, Parent, Node);
41
42typedef std::unordered_map<std::string, NetFunc> NetFuncMap;
43
44// Can also use a lambda for Traverse() and ForEach() functions
45typedef bool(*NodeTraversalFP)(Node*);
46
47// Forward declarations so we can use these in the Node class below
48template<typename T = Node>
50
51template<typename T = Node>
53
54#if 0
55struct NodeNetData
56{
57 std::vector<NetDatum> mReplicatedData;
58 NetId mNetId = INVALID_NET_ID;
59 NetHostId mOwningHost = INVALID_HOST_ID;
60 bool mReplicate = false;
61 bool mReplicateTransform = false;
62 bool mForceReplicate = false;
63};
64#endif
65
67{
68public:
69
74
75 // Linear-scan lookup for a registered node factory by class name. Returns
76 // nullptr if no factory matches. Used by the editor's "Add Node" menu
77 // categorization (PolyphaseEngineAPI::SetNodeCategory threads through here).
78 static Factory* FindFactory(const char* className);
79
80 static NodePtr Construct(const std::string& name);
81 static NodePtr Construct(TypeId typeId);
82 static void Destruct(Node* node);
83
84 Node();
85 virtual ~Node();
86
87 virtual void Create();
88 virtual void Destroy();
89 void DestroyDeferred();
90 void Doom(); // Alias for DestroyDeferred
91
92 virtual void SaveStream(Stream& stream, Platform platform);
93 virtual void LoadStream(Stream& stream, Platform platform, uint32_t version);
94
95 virtual void Copy(Node* srcNode, bool recurse);
96 virtual void Render(PipelineConfig pipelineConfig);
97
98 virtual void Awake();
99 virtual void Start();
100 virtual void Stop();
101 virtual void PrepareTick(std::vector<NodePtrWeak>& outTickNodes, bool game, bool recurse);
102 virtual void Tick(float deltaTime);
103 virtual void EditorTick(float deltaTime);
104 uint32_t GetLastTickedFrame() const;
105 virtual void Render();
106 virtual void OnInstanced();
107
108 virtual VertexType GetVertexType() const;
109
110 virtual void GatherProperties(std::vector<Property>& outProps) override;
111
112 virtual void GatherReplicatedData(std::vector<NetDatum>& outData);
113 virtual void GatherNetFuncs(std::vector<NetFunc>& outFuncs);
114
115 void GatherPropertyOverrides(std::vector<Property>& outOverrides);
116 void ApplyPropertyOverrides(const std::vector<Property>& overs);
117
118 virtual void BeginOverlap(Primitive3D* thisComp, Primitive3D* otherComp);
119 virtual void EndOverlap(Primitive3D* thisComp, Primitive3D* otherComp);
120 virtual void OnCollision(
121 Primitive3D* thisComp,
122 Primitive3D* otherComp,
123 glm::vec3 impactPoint,
124 glm::vec3 impactNormal,
125 btPersistentManifold* manifold);
126
127 NodeId GetNodeId() const;
128
129 uint64_t GetPersistentUuid() const;
130 void SetPersistentUuid(uint64_t uuid);
131 void EnsurePersistentUuid();
132
133 void EmitSignal(const std::string& name, const std::vector<Datum>& args);
134 void ConnectSignal(const std::string& name, Node* listener, SignalHandlerFP func);
135 void ConnectSignal(const std::string& name, Node* listener, const ScriptFunc& func);
136 void DisconnectSignal(const std::string& name, Node* listener);
137
138 void RenderShadow();
139 void RenderSelected(bool renderChildren);
140
141 Node* CreateChild(TypeId nodeType);
142 Node* CreateChild(const char* typeName);
143 Node* CreateChildClone(Node* srcNode, bool recurse);
144 NodePtr Clone(bool recurse, bool instantiateLinkedScene = true, bool resolveNodePaths = false);
145 void DestroyAllChildren();
146
147 Node* GetRoot();
148 bool IsWorldRoot() const;
149 Node* GetSubRoot();
150
151 template<class NodeClass>
152 NodeClass* CreateChild()
153 {
154 return (NodeClass*)CreateChild(NodeClass::GetStaticType());
155 }
156
157 template<class NodeClass>
159 {
160 return ResolvePtr<NodeClass>(CreateChild(NodeClass::GetStaticType()));
161 }
162
163 template<class NodeClass>
164 NodeClass* CreateChild(const char* name)
165 {
166 NodeClass* ret = (NodeClass*)CreateChild(NodeClass::GetStaticType());
167 ret->SetName(name);
168 return ret;
169 }
170
171 template<class NodeClass>
173 {
174 NodeClass* ret = (NodeClass*)CreateChild(NodeClass::GetStaticType());
175 ret->SetName(name);
176 return ResolvePtr<NodeClass>(ret);
177 }
178
179 bool IsDestroyed() const;
180 bool IsPendingDestroy() const;
181 bool IsDoomed() const;
182
183 bool HasStarted() const;
184 bool HasAwoken() const;
185
186 void EnableTick(bool enable);
187 bool IsTickEnabled() const;
188
189 virtual void SetWorld(World* world, bool subRoot);
190 World* GetWorld();
191
192 void SetScene(Scene* scene);
193 Scene* GetScene();
194
195 uint8_t GetTargetScreen() const { return mTargetScreen; }
196 void SetTargetScreen(uint8_t screen) { mTargetScreen = screen; }
197
198 std::vector<NetDatum>& GetReplicatedData();
199
200 void SetNetId(NetId id);
201 NetId GetNetId() const;
202
203 NetHostId GetOwningHost() const;
204 void SetOwningHost(NetHostId hostId, bool setAsPawn = false);
205
206 void SetReplicate(bool replicate);
207 bool IsReplicated() const;
208 void SetReplicateTransform(bool repTransform);
209 bool IsTransformReplicated() const;
210
211 void ForceReplication();
212 void ClearForcedReplication();
213 bool NeedsForcedReplication();
214
215 virtual bool CheckNetRelevance(Node* playerNode);
216 bool IsAlwaysRelevant() const;
217 void SetAlwaysRelevant(bool alwaysRelevant);
218
219 bool HasTag(const std::string& tag);
220 void AddTag(const std::string& tag);
221 void RemoveTag(const std::string& tag);
222
223 void SetName(const std::string& newName);
224 const std::string& GetName() const;
225 virtual void SetActive(bool active);
226 bool IsActive(bool recurse = false) const;
227 virtual void SetVisible(bool visible);
228 bool IsVisible(bool recurse = false) const;
229 void SetTransient(bool transient);
230 virtual bool IsTransient() const;
231 void SetPersistent(bool persistent);
232 bool IsPersistent() const;
233
234 void SetDefault(bool isDefault);
235 bool IsDefault() const;
236
237 void SetUserdataCreated(bool created);
238 bool IsUserdataCreated() const;
239
240 virtual const char* GetTypeName() const;
241 virtual DrawData GetDrawData();
242
243 virtual bool IsNode3D() const;
244 virtual bool IsWidget() const;
245 virtual bool IsPrimitive3D() const;
246 virtual bool IsLight3D() const;
247
248 Node* GetParent();
249 const Node* GetParent() const;
250 const std::vector<NodePtr>& GetChildren() const;
251
252 virtual void Attach(Node* parent, bool keepWorldTransform = false, int32_t index = -1);
253 void Detach(bool keepWorldTransform = false);
254 void AddChild(Node* child, int32_t index = -1);
255 void RemoveChild(Node* child);
256 void RemoveChild(int32_t index);
257
258 template<typename T>
259 void AddChild(const SharedPtr<T>& child, int32_t index = -1)
260 {
261 AddChild(child.Get(), index);
262 }
263
264 template<typename T>
265 void RemoveChild(const SharedPtr<Node>& child)
266 {
267 RemoveChild(child.Get());
268 }
269
270 int32_t FindChildIndex(const std::string& name) const;
271 int32_t FindChildIndex(Node* child) const;
272 Node* FindChild(const std::string& name, bool recurse) const;
273 Node* FindChildWithTag(const std::string& name, bool recurse) const;
274 Node* FindDescendant(const std::string& name);
275 Node* FindAncestor(const std::string& name);
276 bool HasAncestor(Node* node);
277 Node* GetChild(int32_t index) const;
278 Node* GetChildByType(TypeId type) const;
279 uint32_t GetNumChildren() const;
280 int32_t FindParentNodeIndex() const;
281
282 void SetHitCheckId(uint32_t id);
283 uint32_t GetHitCheckId() const;
284
285 bool IsLateTickEnabled() const;
286 void EnableLateTick(bool enable);
287
288 Script* GetScript();
289 void SetScriptFile(const std::string& fileName);
290
291 bool DoChildrenHaveUniqueNames() const;
292 void BreakSceneLink();
293 bool IsSceneLinked(bool ignoreInPie = true) const;
294 bool IsSceneLinkedChild(bool ignoreInPie = true);
295 bool IsForeign() const;
296
297 bool HasAuthority() const;
298 bool IsOwned() const;
299 bool IsLocallyControlled() const;
300
301 Datum GetField(const std::string& key);
302 void SetField(const std::string& name, const Datum& value);
303 Datum GetField(int32_t key);
304 void SetField(int32_t key, const Datum& value);
305 Datum CallFunction(const std::string& name, const std::vector<Datum>& args = {});
306
307 NetFunc* FindNetFunc(const char* name);
308 NetFunc* FindNetFunc(uint16_t index);
309
310 void InvokeNetFunc(const char* name);
311 void InvokeNetFunc(const char* name, Datum param0);
312 void InvokeNetFunc(const char* name, Datum param0, Datum param1);
313 void InvokeNetFunc(const char* name, Datum param0, Datum param1, Datum param2);
314 void InvokeNetFunc(const char* name, Datum param0, Datum param1, Datum param2, Datum param3);
315 void InvokeNetFunc(const char* name, Datum param0, Datum param1, Datum param2, Datum param3, Datum param4);
316 void InvokeNetFunc(const char* name, Datum param0, Datum param1, Datum param2, Datum param3, Datum param4, Datum param5);
317 void InvokeNetFunc(const char* name, Datum param0, Datum param1, Datum param2, Datum param3, Datum param4, Datum param5, Datum param6);
318 void InvokeNetFunc(const char* name, Datum param0, Datum param1, Datum param2, Datum param3, Datum param4, Datum param5, Datum param6, Datum param7);
319 void InvokeNetFunc(const char* name, const std::vector<Datum>& params);
320
321 static void ProcessPendingDestroys();
322
323 static void RegisterNetFuncs(Node* node);
324
325 static void Deleter(Node* node);
326
327 const WeakPtr<Node>& GetSelfPtr() const { return mSelf; }
328
329 template<typename T>
330 T* FindChild(const std::string& name, bool recurse)
331 {
332 T* ret = nullptr;
333 Node* child = FindChild(name, recurse);
334 if (child != nullptr)
335 {
336 ret = child->As<T>();
337 }
338
339 return ret;
340 }
341
342 template<typename T>
343 void Traverse(T func, bool inverted = false)
344 {
345 bool traverseChildren = true;
346
347 if (!inverted)
348 {
349 traverseChildren = func(this);
350 }
351
352 if (traverseChildren)
353 {
354 if (inverted)
355 {
356 for (int32_t i = int32_t(mChildren.size()) - 1; i >= 0; --i)
357 {
358 mChildren[i]->Traverse(func, inverted);
359 }
360 }
361 else
362 {
363 for (uint32_t i = 0; i < mChildren.size(); ++i)
364 {
365 mChildren[i]->Traverse(func, inverted);
366 }
367 }
368 }
369
370 if (inverted)
371 {
372 func(this);
373 }
374 }
375
376 template<typename T>
377 bool ForEach(T func, bool inverted = false)
378 {
379 bool cont = true;
380
381 if (!inverted)
382 {
383 cont = func(this);
384 }
385
386 if (cont)
387 {
388 if (inverted)
389 {
390 for (int32_t i = int32_t(mChildren.size()) - 1; i >= 0; --i)
391 {
392 cont = mChildren[i]->ForEach(func, inverted);
393
394 if (!cont)
395 {
396 break;
397 }
398 }
399 }
400 else
401 {
402 for (uint32_t i = 0; i < mChildren.size(); ++i)
403 {
404 cont = mChildren[i]->ForEach(func, inverted);
405
406 if (!cont)
407 {
408 break;
409 }
410 }
411 }
412 }
413
414 if (cont && inverted)
415 {
416 cont = func(this);
417 }
418
419 return cont;
420 }
421
422 template<class NodeClass>
424 {
425 // Code copied across other Construct() functions
426 NodeClass* newNode = (NodeClass*)Node::CreateInstance(NodeClass::GetStaticType());
427 SharedPtr<NodeClass> newNodePtr;
428
429 if (newNode != nullptr)
430 {
431 newNodePtr.Set(newNode, nullptr);
432 newNodePtr.SetDeleter([](NodeClass* node) { Node::Deleter(node); });
433 newNodePtr->mSelf = PtrStaticCast<Node>(newNodePtr);
434 newNodePtr->Create();
435 }
436
437 return newNodePtr;
438 }
439
440protected:
441
442 static bool HandlePropChange(Datum* datum, uint32_t index, const void* newValue);
443
444 static bool OnRep_OwningHost(Datum* datum, uint32_t index, const void* newValue);
445
446 void TickCommon(float deltaTime);
447
448 virtual void SetParent(Node* parent);
449 void ValidateUniqueChildName(Node* newChild);
450
451 void SendNetFunc(NetFunc* func, uint32_t numParams, const Datum** params);
452
453 static std::unordered_map<TypeId, NetFuncMap> sTypeNetFuncMap;
454 static std::unordered_set<NodePtrWeak> sPendingDestroySet;
456
457 std::string mName;
458
459 World* mWorld = nullptr;
462 std::vector<NodePtr> mChildren;
463 std::unordered_map<std::string, Node*> mChildNameMap;
464 std::unordered_map<std::string, Signal> mSignalMap;
465 std::string mScriptFile;
466 uint32_t mLastTickedFrame = 0;
467 bool mActive = true;
468 bool mVisible = true;
469 bool mTransient = false;
470 bool mPersistent = false;
471 bool mDefault = false;
472 bool mUserdataCreated = false;
473 bool mHasStarted = false;
474 bool mHasAwoken = false;
475 bool mDestroyed = false;
476 bool mTickEnabled = true;
477 bool mLateTick = false;
478
479 // Merged from Actor
481 uint8_t mTargetScreen = 0; // 0 = Top Screen, 1 = Bottom Screen
482 std::vector<std::string> mTags;
484 uint64_t mPersistentUuid = 0;
485
486 // Network Data
487 // This is only about 44 bytes, so right now, we will keep this data as direct members of Node.
488 // But if we need to save data, then consider allocating a NodeNetData struct only if replicated.
489 // Leaving these as direct members will improve cache performance too.
490 std::vector<NetDatum> mReplicatedData;
493 bool mReplicate = false;
494 bool mReplicateTransform = false;
495 bool mForceReplicate = false;
496 bool mAlwaysRelevant = true;
497
498 Script* mScript = nullptr;
499 //NodeNetData* mNetData = nullptr;
500
501#if EDITOR
502public:
503 // TODO-NODE: Either remove mExposeVariable, or make sure it works with Scenes.
504 // Could consider moving this up to Node if it would be useful from avoiding FindChild() calls in Start().
505 bool ShouldExposeVariable() const;
506 void SetExposeVariable(bool expose);
507 bool AreAllChildrenHiddenInTree() const;
508
509 uint32_t mHitCheckId = 0;
510 bool mExposeVariable = false;
511 bool mHiddenInTree = false;
512#endif
513};
514
515// Eventually, if we move the mSelf pointer into Object, we will have to
516// move these functions also (and make them take Object* param)
517//
518// Defensive: if `node`'s mSelf has been stomped so it no longer points back
519// at `node` (most often a dangling Node* from a previous world/addon load
520// whose memory got reused), Lock() will crash inside IsValid when it
521// dereferences the dangling mPointer. Gate the Lock with a self-consistency
522// check and return null on mismatch so callers see "couldn't resolve" instead
523// of an access violation. Callers that care surface a user-visible error
524// (see Node::AddChild for the editor alert).
525template<typename T>
527{
528 if (node == nullptr)
529 {
530 return nullptr;
531 }
532
533 const NodePtrWeak& selfWeak = node->GetSelfPtr();
534 if (selfWeak.GetPointerRaw() != node || selfWeak.GetRefCount() == nullptr)
535 {
536 return nullptr;
537 }
538
539 NodePtr nodePtr = selfWeak.Lock();
540 return PtrStaticCast<T>(nodePtr);
541}
542
543template<typename T>
545{
546 if (node == nullptr)
547 {
548 return WeakPtr<T>();
549 }
550
551 const NodePtrWeak& selfWeak = node->GetSelfPtr();
552 if (selfWeak.GetPointerRaw() != node || selfWeak.GetRefCount() == nullptr)
553 {
554 return WeakPtr<T>();
555 }
556
557 return PtrStaticCast<T>(selfWeak);
558}
#define INVALID_HOST_ID
Definition Constants.h:44
#define INVALID_NODE_ID
Definition Constants.h:42
#define INVALID_NET_ID
Definition Constants.h:41
uint32_t NetId
Definition EngineTypes.h:72
Platform
Definition EngineTypes.h:31
uint8_t NetHostId
Definition EngineTypes.h:502
uint32_t TypeId
Definition EngineTypes.h:71
uint32_t NodeId
Definition EngineTypes.h:73
World * GetWorld(int32_t index)
Definition Engine.cpp:1106
PipelineConfig
Definition GraphicsTypes.h:66
std::unordered_map< std::string, NetFunc > NetFuncMap
Definition Node.h:42
bool(* NodeTraversalFP)(Node *)
Definition Node.h:45
SharedPtr< T > ResolvePtr(Node *node)
Definition Node.h:526
WeakPtr< T > ResolveWeakPtr(Node *node)
Definition Node.h:544
Export macros for Polyphase Engine symbols.
#define POLYPHASE_API
Definition PolyphaseAPI.h:31
void(* SignalHandlerFP)(Node *, const std::vector< Datum > &)
Definition Signals.h:11
VertexType
Definition Vertex.h:7
Definition AssetRef.h:18
Definition Datum.h:169
Definition Factory.h:62
Definition Node.h:67
std::vector< NetDatum > mReplicatedData
Definition Node.h:490
SceneRef mScene
Definition Node.h:480
DECLARE_FACTORY(Node, Node)
SharedPtr< NodeClass > CreateChildSp(const char *name)
Definition Node.h:172
std::string mScriptFile
Definition Node.h:465
void Traverse(T func, bool inverted=false)
Definition Node.h:343
NodePtrWeak mParent
Definition Node.h:460
NodeClass * CreateChild(const char *name)
Definition Node.h:164
std::vector< NodePtr > mChildren
Definition Node.h:462
std::string mName
Definition Node.h:457
static std::unordered_map< TypeId, NetFuncMap > sTypeNetFuncMap
Definition Node.h:453
static SharedPtr< NodeClass > Construct()
Definition Node.h:423
NodePtrWeak mSelf
Definition Node.h:461
void SetTargetScreen(uint8_t screen)
Definition Node.h:196
DECLARE_FACTORY_MANAGER(Node)
static std::unordered_set< NodePtrWeak > sPendingDestroySet
Definition Node.h:454
DECLARE_OBJECT(Node, Object)
static NodeId sNextNodeId
Definition Node.h:455
SharedPtr< NodeClass > CreateChildSp()
Definition Node.h:158
bool ForEach(T func, bool inverted=false)
Definition Node.h:377
static void Deleter(Node *node)
Definition Node.cpp:146
std::unordered_map< std::string, Node * > mChildNameMap
Definition Node.h:463
void AddChild(const SharedPtr< T > &child, int32_t index=-1)
Definition Node.h:259
std::unordered_map< std::string, Signal > mSignalMap
Definition Node.h:464
DECLARE_SCRIPT_LINK_BASE(Node)
uint8_t GetTargetScreen() const
Definition Node.h:195
T * FindChild(const std::string &name, bool recurse)
Definition Node.h:330
NodeClass * CreateChild()
Definition Node.h:152
const WeakPtr< Node > & GetSelfPtr() const
Definition Node.h:327
std::vector< std::string > mTags
Definition Node.h:482
void RemoveChild(const SharedPtr< Node > &child)
Definition Node.h:265
Definition Object.h:13
virtual void GatherProperties(std::vector< Property > &props)
Definition Object.h:41
T * As() const
Definition Object.h:52
Definition Primitive3d.h:46
Definition Scene.h:36
Definition ScriptFunc.h:10
Definition Script.h:29
Definition SmartPointer.h:33
void SetDeleter(typename RefCount< T >::DeleterFP deleteFunc)
Definition SmartPointer.h:234
void Set(T *pointer, RefCount< T > *refCount)
Definition SmartPointer.h:156
T * Get() const
Definition SmartPointer.h:247
Definition Stream.h:21
Definition SmartPointer.h:312
RefCount< T > * GetRefCount() const
Definition SmartPointer.h:531
SharedPtr< T > Lock() const
Definition SmartPointer.h:492
const T * GetPointerRaw() const
Definition SmartPointer.h:551
Definition World.h:24
Definition EngineTypes.h:206
Definition NetFunc.h:33