| 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 | |
| 7 | namespace al { |
| 8 | ParameterObj::ParameterObj() = default; |
| 9 | |
| 10 | void 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 | |
| 20 | void 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 | |
| 38 | void 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 | |
| 52 | bool 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 | |
| 87 | void 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 | |
| 108 | void 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 | |
| 147 | ParameterBase* 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 | |
| 154 | ParameterArray::ParameterArray() = default; |
| 155 | |
| 156 | void 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: ¶mIter, index); |
| 169 | if (!paramIter.isValid()) |
| 170 | continue; |
| 171 | objEntry->tryGetParam(iter: paramIter); |
| 172 | index++; |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | bool 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 | |
| 195 | void 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 | |
| 206 | void 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 | |
| 220 | void 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 | |
| 234 | void 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 | |
| 244 | void 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 | |
| 259 | bool 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 | |
| 266 | ParameterList::ParameterList() = default; |
| 267 | |
| 268 | void 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 | |
| 280 | void 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 | |
| 294 | void 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 | |
| 308 | void 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 | |
| 322 | void 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 | |
| 332 | void 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 | |
| 342 | void 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 | |
| 357 | void 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 | |
| 372 | bool 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 | |
| 379 | void 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 | |
| 395 | ParameterIo::ParameterIo() = default; |
| 396 | |
| 397 | } // namespace al |
| 398 | |