-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBTBuildGraph.h
More file actions
177 lines (146 loc) · 4.08 KB
/
Copy pathBTBuildGraph.h
File metadata and controls
177 lines (146 loc) · 4.08 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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#pragma once
#include <mathematics/vector2.hpp>
#include "BTBuildNode.h"
#include "ReflectionYml.h"
struct BTBuildGraph
{
public:
static consteval auto reflect()
{
using Self = BTBuildGraph;
return meta::schema<Self>(
meta::field<&Self::NodeList>);
}
std::unordered_map<HashedGuid, BTBuildNode*> Nodes;
BTBuildNode* SelectedNode{ nullptr };
std::vector<BTBuildNode> NodeList;
BTBuildGraph()
{
NodeList.reserve(200); // 초기 노드 리스트 크기 예약
BTBuildNode rootNode;
rootNode.ID = make_guid();
rootNode.Type = BehaviorNodeType::Sequence; // 기본적으로 Sequence로 설정
rootNode.Name = "RootSequence";
rootNode.IsRoot = true; // 루트 노드로 설정
rootNode.Position = math::vector2(0, 0); // 초기 위치 설정
NodeList.push_back(rootNode);
Nodes[rootNode.ID] = &NodeList.back();
SelectedNode = &NodeList.back(); // 루트 노드를 선택된 노드로 설정
}
~BTBuildGraph()
{
NodeList.clear();
Nodes.clear();
}
BTBuildNode* CreateNode(const BehaviorNodeType type, std::string_view name, math::vector2 pos = { 0, 0 })
{
BTBuildNode node;
node.ID = make_guid();
node.Type = type;
node.Name = std::string(name);
node.IsRoot = false; // 기본적으로 루트가 아님
node.Position = pos; // 초기 위치 설정
NodeList.push_back(node);
Nodes[node.ID] = &NodeList.back();
return Nodes[node.ID];
}
void AddChildNode(BTBuildNode* childNode)
{
if (nullptr == SelectedNode) return;
const auto& selectedNodeType = SelectedNode->Type;
auto& selectedNodeChildContainer = SelectedNode->Children;
const auto& childNodeID = childNode->ID;
const auto& selectedNodeID = SelectedNode->ID;
auto& childNodeParentID = childNode->ParentID;
if (BT::IsDecoratorNode(selectedNodeType) && 0 < selectedNodeChildContainer.size()) return; // Decorator 노드는 자식이 최대 1개만 허용됨
selectedNodeChildContainer.push_back(childNodeID);
childNodeParentID = selectedNodeID;
SelectedNode = childNode; // 새로 추가한 노드를 선택된 노드로 설정
}
void PickNode(const HashedGuid& id)
{
if(Nodes.find(id) != Nodes.end())
{
SelectedNode = Nodes[id];
}
}
void DeleteNode(const HashedGuid& id)
{
auto it = Nodes.find(id);
if (it != Nodes.end())
{
BTBuildNode* node = it->second;
if (node->IsRoot) return; // 루트 노드는 삭제할 수 없음
// 모든 링크 제거
for (auto& [otherId, otherNode] : Nodes)
{
if (otherNode->ParentID == id)
{
otherNode->ParentID = HashedGuid(); // 부모 ID 초기화
}
std::erase_if(otherNode->Children,
[&id](const HashedGuid& childId) { return childId == id; }); // 자식 ID 제거
}
node->Children.clear(); // 자식 노드 목록 초기화
// 노드 삭제
NodeList.erase(std::remove_if(NodeList.begin(), NodeList.end(),
[&id](const BTBuildNode& node) { return node.ID == id; }), NodeList.end());
Nodes.erase(it);
}
}
void Clear()
{
NodeList.clear();
Nodes.clear();
BTBuildNode rootNode;
rootNode.ID = make_guid();
rootNode.Type = BehaviorNodeType::Sequence; // 기본적으로 Sequence로 설정
rootNode.Name = "RootSequence";
rootNode.IsRoot = true; // 루트 노드로 설정
rootNode.Position = math::vector2(0, 0); // 초기 위치 설정
NodeList.push_back(rootNode);
Nodes[rootNode.ID] = &NodeList.back();
SelectedNode = &NodeList.back(); // 루트 노드를 선택된 노드로 설정
}
void CleanUp()
{
NodeList.clear();
Nodes.clear();
SelectedNode = nullptr;
}
void DeserializeSingleNode(const YAML::Node& node)
{
BTBuildNode out;
Meta::Deserialize(&out, node);
NodeList.push_back(out);
Nodes[out.ID] = &NodeList.back();
if (out.IsRoot)
{
SelectedNode = &NodeList.back(); // 루트 노드를 선택된 노드로 설정
}
}
HashedGuid GetRootID() const
{
for (auto& [id, node] : Nodes)
{
if (node->IsRoot)
return id;
}
return HashedGuid();
}
std::vector<std::string> GetRegisteredKey() const
{
// 빌드 메뉴에서 사용할 노드 타입 목록 반환 :
// 스크립트가 필요한 Action 노드 및 Condition 노드는 외부에서 따로 처리함.
return {
"Sequence",
"Selector",
"WeightedSelector",
"Parallel",
"Inverter",
"ConditionDecorator",
"Action",
"Condition",
};
}
};