Created
October 31, 2020 22:46
-
-
Save leoetlino/e6c8be64e6074523d52ded262a682f54 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @param dest Destination flag array | |
* @param src Source flag array | |
* @param records Copy records (only used if add_records is true) | |
* @param counts Boolean flag counts per category (only used if T = bool) | |
* @param record_copies Whether copies should be recorded | |
* @param ignore_temp_flags Whether temporary flags (i.e. flags that aren't saved) | |
* should be ignored | |
* @param find_existing_record See addFlagCopyRecord. | |
* @param is_array Whether the flag arrays are associated with an array-type flag (e.g. bool array) | |
*/ | |
template <typename T> | |
void copyFlags(sead::PtrArray<FlagBase>& dest, const sead::PtrArray<FlagBase>& src, | |
sead::ObjArray<TriggerParam::FlagCopyRecord>& records, | |
sead::SafeArray<s32, 15>& counts, bool record_copies, bool ignore_temp_flags, | |
bool find_existing_record, bool is_array) { | |
// This function only handles two cases: | |
// | |
// 1. If both the source and destination have the same number of flags, we assume that | |
// both arrays store the same flags in the exact same order. | |
// | |
// 2. If the source has fewer flags than the destination, it is assumed that src is a subset of | |
// dest (i.e. every flag that is in src is also in dest) and src forms a subsequence of dest. | |
// Any flag in dest that isn't in src will be reset to its initial value. | |
const auto update_records = [&](Flag<T>* flag, s32 i) { | |
s32 category; | |
if constexpr (std::is_same<T, bool>()) | |
category = flag->getCategory(); | |
if (record_copies) | |
addFlagCopyRecord<T>(records, flag, is_array ? i : -1, find_existing_record); | |
if constexpr (std::is_same<T, bool>()) { | |
if (category > 0) { | |
if (flag->getValue()) | |
++counts[category - 1]; | |
else if (counts[category - 1] > 0) | |
--counts[category - 1]; | |
} | |
} | |
}; | |
const auto dest_size = dest.size(); | |
const auto src_size = src.size(); | |
if (dest_size == src_size) { | |
for (s32 i = 0; i < dest_size; ++i) { | |
if (!dest[i]) | |
continue; | |
if (ignore_temp_flags && !dest[i]->isSave()) | |
continue; | |
if (record_copies && dest[i]->isSave()) | |
continue; | |
if (!src[i]) { | |
if (!dest[i]->isSave()) | |
dest[i]->resetToInitialValue(); | |
} else { | |
auto* flag = static_cast<Flag<T>*>(dest[i]); | |
auto* flag_src = static_cast<Flag<T>*>(src[i]); | |
flag->setValue(flag_src->getValue()); | |
update_records(flag, i); | |
} | |
} | |
} else if (src_size < dest_size) { | |
s32 j = 0; | |
for (s32 i = 0; i < dest_size; ++i) { | |
if (ignore_temp_flags && !dest[i]->isSave()) | |
continue; | |
if (record_copies && dest[i]->isSave()) | |
continue; | |
if (j >= src_size || src[j]->getHash() != dest[i]->getHash()) { | |
if (!dest[i]->isSave()) | |
dest[i]->resetToInitialValue(); | |
} else if (src[j]->getHash() == dest[i]->getHash()) { | |
auto* flag = static_cast<Flag<T>*>(dest[i]); | |
auto* flag_src = static_cast<Flag<T>*>(src[j]); | |
flag->setValue(flag_src->getValue()); | |
update_records(flag, i); | |
++j; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment