-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNodeFactory.h
More file actions
81 lines (64 loc) · 2.79 KB
/
Copy pathNodeFactory.h
File metadata and controls
81 lines (64 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once
/**
* @file NodeFactory.h
* @brief Type-erased factory for node-graph node types (create/deserialize/destroy).
*
* Parallel to ComponentFactory, but DELIBERATELY SEPARATE: node types are not
* components and must not leak into the prefab/ECS systems. Nodes are plain
* reflected structs (DEKI_NODE) with no common base class, so the factory stores
* void* create/destroy and a deserialize thunk keyed by the node type's name hash.
*
* Every node's generated .gen.cpp self-registers via REGISTER_RUNTIME_NODE
* (defined in DekiNode.h) at DLL load, so new node types come from module/project
* DLLs with no editor rebuild.
*/
#include "deki-nodegraph/NodeGraphApi.h"
#include <cstdint>
#include <cstddef>
#include <unordered_map>
namespace PrefabFormat {
class PrefabMsgPackParser;
using NodeCreateFn = void* (*)();
using NodeDeserializeFn = bool (*)(void* node, PrefabMsgPackParser& parser, uint32_t mapSize);
using NodeDestroyFn = void (*)(void* node);
struct NodeFactoryEntry {
NodeCreateFn create = nullptr;
NodeDeserializeFn deserialize = nullptr;
NodeDestroyFn destroy = nullptr;
};
/**
* @brief Hash-map factory for node types. O(1) lookup by type id (name hash).
*/
class DEKI_NODEGRAPH_API NodeFactory {
public:
static NodeFactory& Instance();
void Register(uint32_t typeId, NodeCreateFn create,
NodeDeserializeFn deserialize, NodeDestroyFn destroy) {
m_Entries[typeId] = { create, deserialize, destroy };
}
void Unregister(uint32_t typeId) { m_Entries.erase(typeId); }
// Create a default-constructed node of the given type, or nullptr if unknown.
void* Create(uint32_t typeId) {
auto it = m_Entries.find(typeId);
return (it != m_Entries.end() && it->second.create) ? it->second.create() : nullptr;
}
// Deserialize `node` (a pointer from Create) from a MessagePack map. Returns
// false if the type is unknown or has no deserialize thunk.
bool Deserialize(uint32_t typeId, void* node, PrefabMsgPackParser& parser, uint32_t mapSize) {
auto it = m_Entries.find(typeId);
return (it != m_Entries.end() && it->second.deserialize)
? it->second.deserialize(node, parser, mapSize) : false;
}
void Destroy(uint32_t typeId, void* node) {
auto it = m_Entries.find(typeId);
if (it != m_Entries.end() && it->second.destroy) it->second.destroy(node);
}
bool IsRegistered(uint32_t typeId) const { return m_Entries.count(typeId) > 0; }
size_t GetRegisteredCount() const { return m_Entries.size(); }
// Clear all entries (for plugin/module hot-reload teardown).
void Clear() { m_Entries.clear(); }
private:
NodeFactory() = default;
std::unordered_map<uint32_t, NodeFactoryEntry> m_Entries;
};
} // namespace PrefabFormat