1#include "Library/Yaml/ParameterObj.h"
2
3#include "Library/Base/StringUtil.h"
4#include "Library/Yaml/ByamlIter.h"
5#include "Library/Yaml/ParameterBase.h"
6
7namespace al {
8ParameterObj::ParameterObj() = default;
9
10void ParameterObj::pushBackListNode(ParameterBase* param) {
11 if (!mTailParam) {
12 mRootParam = param;
13 mTailParam = param;
14 return;
15 }
16 mTailParam->setNext(param);
17 mTailParam = param;
18}
19
20void ParameterObj::tryGetParam(const ByamlIter& iter) {
21 const ByamlIter* i = &iter;
22 ByamlIter iterEntry;
23
24 if (!mKey.isEmpty()) {
25 iter.tryGetIterByKey(iter: &iterEntry, key: mKey.cstr());
26 i = &iterEntry;
27 if (!iterEntry.isValid())
28 return;
29 }
30
31 for (ParameterBase* paramEntry = mRootParam; paramEntry; paramEntry = paramEntry->getNext())
32 paramEntry->tryGetParam(*i);
33
34 for (ParameterArray* arrayEntry = mParamArray; arrayEntry; arrayEntry = arrayEntry->getNext())
35 arrayEntry->tryGetParam(iter: *i);
36}
37
38void ParameterObj::addArray(ParameterArray* array, const sead::SafeString& key) {
39 array->setKey(key);
40
41 if (!mParamArray) {
42 mParamArray = array;
43 return;
44 }
45
46 ParameterArray* arrayEntry = mParamArray;
47 while (arrayEntry->getNext())
48 arrayEntry = arrayEntry->getNext();
49 arrayEntry->setNext(array);
50}
51
52bool ParameterObj::isEqual(const ParameterObj& obj) const {
53 ParameterBase* paramEntry = mRootParam;
54 ParameterBase* param = obj.getRootParam();
55
56 if (!paramEntry) {
57 if (param)
58 return false;
59 } else {
60 // BUG: Also succeeds if paramEntry != null and param == null
61 while (paramEntry && param) {
62 if (!paramEntry->isEqual(*param))
63 return false;
64 paramEntry = paramEntry->getNext();
65 param = param->getNext();
66 }
67 }
68
69 ParameterArray* arrayEntry = mParamArray;
70 ParameterArray* array = obj.getParamArray();
71 if (!arrayEntry) {
72 if (array)
73 return false;
74 } else {
75 if (!array)
76 return false;
77 while (arrayEntry && array) {
78 if (!arrayEntry->isEqual(array: *array))
79 return false;
80 arrayEntry = arrayEntry->getNext();
81 array = array->getNext();
82 }
83 }
84 return true;
85}
86
87void ParameterObj::copy(const ParameterObj& obj) {
88 ParameterBase* paramEntry = mRootParam;
89 ParameterBase* param = obj.getRootParam();
90
91 if (paramEntry)
92 while (paramEntry && param) {
93 paramEntry->copy(*param);
94 paramEntry = paramEntry->getNext();
95 param = param->getNext();
96 }
97
98 ParameterArray* array = obj.getParamArray();
99 ParameterArray* arrayEntry = mParamArray;
100 if (arrayEntry)
101 while (arrayEntry && array) {
102 arrayEntry->copy(array: *array);
103 arrayEntry = arrayEntry->getNext();
104 array = array->getNext();
105 }
106}
107
108void ParameterObj::copyLerp(const ParameterObj& objA, const ParameterObj& objB, f32 rate) {
109 ParameterBase* paramEntry = mRootParam;
110 ParameterBase* paramA = objA.getRootParam();
111 ParameterBase* paramB = objB.getRootParam();
112
113 if (paramEntry) {
114 if (rate <= 0.0f) {
115 while (paramEntry && paramA) {
116 paramEntry->copy(*paramA);
117 paramEntry = paramEntry->getNext();
118 paramA = paramA->getNext();
119 }
120 } else if (rate >= 1.0f) {
121 while (paramEntry && paramB) {
122 paramEntry->copy(*paramB);
123 paramEntry = paramEntry->getNext();
124 paramB = paramB->getNext();
125 }
126 } else {
127 while (paramEntry && paramA && paramB) {
128 paramEntry->copyLerp(*paramA, *paramB, rate);
129 paramEntry = paramEntry->getNext();
130 paramA = paramA->getNext();
131 paramB = paramB->getNext();
132 }
133 }
134 }
135
136 ParameterArray* arrayB = objB.getParamArray();
137 ParameterArray* arrayA = objA.getParamArray();
138 ParameterArray* arrayEntry = mParamArray;
139 while (arrayEntry && arrayA && arrayB) {
140 arrayEntry->copyLerp(arrayA: *arrayA, arrayB: *arrayB, rate);
141 arrayEntry = arrayEntry->getNext();
142 arrayA = arrayA->getNext();
143 arrayB = arrayB->getNext();
144 }
145}
146
147ParameterBase* ParameterObj::findParameter(const char* name) const {
148 for (ParameterBase* paramEntry = mRootParam; paramEntry; paramEntry = paramEntry->getNext())
149 if (isEqualString(str1: name, str2: paramEntry->getParamName().getStringTop()))
150 return paramEntry;
151 return nullptr;
152}
153
154ParameterArray::ParameterArray() = default;
155
156void ParameterArray::tryGetParam(const ByamlIter& iter) {
157 ByamlIter arrayIter;
158 iter.tryGetIterByKey(iter: &arrayIter, key: mKey.cstr());
159
160 if (!arrayIter.isValid() || !arrayIter.isTypeArray())
161 return;
162
163 mSize = arrayIter.getSize();
164
165 s32 index = 0;
166 for (ParameterObj* objEntry = mRootObjNode; objEntry; objEntry = objEntry->getNext()) {
167 ByamlIter paramIter;
168 arrayIter.tryGetIterByIndex(iter: &paramIter, index);
169 if (!paramIter.isValid())
170 continue;
171 objEntry->tryGetParam(iter: paramIter);
172 index++;
173 }
174}
175
176bool ParameterArray::isEqual(const ParameterArray& array) const {
177 if (mSize != array.getSize())
178 return false;
179
180 ParameterObj* objEntry = mRootObjNode;
181 ParameterObj* obj = array.getRootObjNode();
182
183 if (!objEntry || !obj)
184 return !objEntry && !obj;
185
186 while (objEntry && obj) {
187 if (!objEntry->isEqual(obj: *obj))
188 return false;
189 objEntry = objEntry->getNext();
190 obj = obj->getNext();
191 }
192 return true;
193}
194
195void ParameterArray::copy(const ParameterArray& array) {
196 ParameterObj* obj = array.getRootObjNode();
197 ParameterObj* objEntry = mRootObjNode;
198
199 while (objEntry && obj) {
200 objEntry->copy(obj: *obj);
201 objEntry = objEntry->getNext();
202 obj = obj->getNext();
203 }
204}
205
206void ParameterArray::copyLerp(const ParameterArray& arrayA, const ParameterArray& arrayB,
207 f32 rate) {
208 ParameterObj* objBEntry = arrayB.getRootObjNode();
209 ParameterObj* objAEntry = arrayA.getRootObjNode();
210 ParameterObj* objEntry = mRootObjNode;
211
212 while (objEntry && objAEntry && objBEntry) {
213 objEntry->copyLerp(objA: *objAEntry, objB: *objBEntry, rate);
214 objEntry = objEntry->getNext();
215 objAEntry = objAEntry->getNext();
216 objBEntry = objBEntry->getNext();
217 }
218}
219
220void ParameterArray::addObj(ParameterObj* obj) {
221 obj->setKey(sead::SafeString::cEmptyString);
222
223 if (!mRootObjNode) {
224 mRootObjNode = obj;
225 return;
226 }
227
228 ParameterObj* objEntry = mRootObjNode;
229 while (objEntry->getNext())
230 objEntry = objEntry->getNext();
231 objEntry->setNext(obj);
232}
233
234void ParameterArray::clearObj() {
235 ParameterObj* objEntry = mRootObjNode;
236 while (objEntry) {
237 ParameterObj* next = objEntry->getNext();
238 objEntry->setNext(nullptr);
239 objEntry = next;
240 }
241 mRootObjNode = nullptr;
242}
243
244void ParameterArray::removeObj(ParameterObj* obj) {
245 ParameterObj* prevObjEntry = nullptr;
246 for (ParameterObj* objEntry = mRootObjNode; objEntry; objEntry = objEntry->getNext()) {
247 if (objEntry == obj) {
248 if (prevObjEntry)
249 prevObjEntry->setNext(obj->getNext());
250 else
251 mRootObjNode = obj->getNext();
252 objEntry->setNext(nullptr);
253 return;
254 }
255 prevObjEntry = objEntry;
256 }
257}
258
259bool ParameterArray::isExistObj(ParameterObj* obj) {
260 for (ParameterObj* objEntry = mRootObjNode; objEntry; objEntry = objEntry->getNext())
261 if (objEntry == obj)
262 return true;
263 return false;
264}
265
266ParameterList::ParameterList() = default;
267
268void ParameterList::addParam(ParameterBase* param) {
269 if (!mRootParamNode) {
270 mRootParamNode = param;
271 return;
272 }
273
274 ParameterBase* arrayParam = mRootParamNode;
275 while (arrayParam->getNext())
276 arrayParam = arrayParam->getNext();
277 arrayParam->setNext(param);
278}
279
280void ParameterList::addList(ParameterList* list, const sead::SafeString& key) {
281 list->setKey(key);
282
283 if (!mRootListNode) {
284 mRootListNode = list;
285 return;
286 }
287
288 ParameterList* listEntry = mRootListNode;
289 while (listEntry->getNext())
290 listEntry = listEntry->getNext();
291 listEntry->setNext(list);
292}
293
294void ParameterList::addObj(ParameterObj* obj, const sead::SafeString& key) {
295 obj->setKey(key);
296
297 if (!mRootObjNode) {
298 mRootObjNode = obj;
299 return;
300 }
301
302 ParameterObj* objEntry = mRootObjNode;
303 while (objEntry->getNext())
304 objEntry = objEntry->getNext();
305 objEntry->setNext(obj);
306}
307
308void ParameterList::addArray(ParameterArray* array, const sead::SafeString& key) {
309 array->setKey(key);
310
311 if (!mRootArrayNode) {
312 mRootArrayNode = array;
313 return;
314 }
315
316 ParameterArray* arrayEntry = mRootArrayNode;
317 while (arrayEntry->getNext())
318 arrayEntry = arrayEntry->getNext();
319 arrayEntry->setNext(array);
320}
321
322void ParameterList::clearList() {
323 ParameterList* listEntry = mRootListNode;
324 while (listEntry) {
325 ParameterList* next = listEntry->getNext();
326 listEntry->setNext(nullptr);
327 listEntry = next;
328 }
329 mRootListNode = nullptr;
330}
331
332void ParameterList::clearObj() {
333 ParameterObj* objEntry = mRootObjNode;
334 while (objEntry) {
335 ParameterObj* next = objEntry->getNext();
336 objEntry->setNext(nullptr);
337 objEntry = next;
338 }
339 mRootObjNode = nullptr;
340}
341
342void ParameterList::removeList(ParameterList* list) {
343 ParameterList* prevlistEntry = nullptr;
344 for (ParameterList* listEntry = mRootListNode; listEntry; listEntry = listEntry->getNext()) {
345 if (listEntry == list) {
346 if (prevlistEntry)
347 prevlistEntry->setNext(list->getNext());
348 else
349 mRootListNode = list->getNext();
350 listEntry->setNext(nullptr);
351 return;
352 }
353 prevlistEntry = listEntry;
354 }
355}
356
357void ParameterList::removeObj(ParameterObj* obj) {
358 ParameterObj* prevObjEntry = nullptr;
359 for (ParameterObj* objEntry = mRootObjNode; objEntry; objEntry = objEntry->getNext()) {
360 if (objEntry == obj) {
361 if (prevObjEntry)
362 prevObjEntry->setNext(obj->getNext());
363 else
364 mRootObjNode = obj->getNext();
365 objEntry->setNext(nullptr);
366 return;
367 }
368 prevObjEntry = objEntry;
369 }
370}
371
372bool ParameterList::isExistObj(ParameterObj* obj) {
373 for (ParameterObj* objEntry = mRootObjNode; objEntry; objEntry = objEntry->getNext())
374 if (objEntry == obj)
375 return true;
376 return false;
377}
378
379void ParameterList::tryGetParam(const ByamlIter& iter) {
380 for (ParameterBase* paramEntry = mRootParamNode; paramEntry; paramEntry = paramEntry->getNext())
381 paramEntry->tryGetParam(iter);
382
383 for (ParameterObj* objEntry = mRootObjNode; objEntry; objEntry = objEntry->getNext())
384 objEntry->tryGetParam(iter);
385
386 for (ParameterArray* arrayEntry = mRootArrayNode; arrayEntry;
387 arrayEntry = arrayEntry->getNext()) {
388 arrayEntry->tryGetParam(iter);
389 }
390
391 for (ParameterList* listEntry = mRootListNode; listEntry; listEntry = listEntry->getNext())
392 listEntry->tryGetParam(iter);
393}
394
395ParameterIo::ParameterIo() = default;
396
397} // namespace al
398