Skip to content

Commit

Permalink
Handle ambiguity in array kind determination
Browse files Browse the repository at this point in the history
Turns out that reading a "None" as the first element of an array
doesn't necessarily mean it's a struct array where the first element
has all default values -- "None" can also appear in enum arrays,
presumably where "None" means the 0 value of the enum (unconfirmed).

This has been observed in the
XGExaltSimulation.m_arrCellLastVisibilityData checkpoint element,
where the first element is "None" and the second is an enumerator
value.

Since this is ambiguous, we need to keep scanning ahead at subsequent
array elements to figure out what kind of array this really is. It's
in theory possible that all the elements will be "None", although I
haven't seen this yet. If that can happen we have no recourse except
to hard-code particular known arrays with the correct type as per the
UPK file or actually read the UPKs to determine what shape the array
has.
  • Loading branch information
tracktwo committed Apr 20, 2018
1 parent 8579c26 commit 96b291e
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions xcomreader.cpp
Expand Up @@ -182,13 +182,28 @@ namespace xcom
return property::kind_t::last_property;
}

// If the first thing we get is a "None", then this is a struct
// property with all default values in the first element.
// If the first thing we get is a "None", we have an ambiguity. This could be
// a struct array (as in XGExaltSimulation.m_arrCellData) where the "None"
// indicates a struct element with all default property values. Or it could be
// an enum array (as in XGExaltSimulation.m_arrCellLastVisibilityData) where "None"
// presumably indicates the 0 value of the enumeration?
//
// Either way, we don't know how to parse this yet. There should be a 0 int after
// the "None" to complete this element. Read that and then recursively call this
// function to try to determine based on the next array element.
//
// I'm not sure if it's possible to have an array element here with "None" in every
// element. If so this will eventually run off the end of the array and we'd probably
// fail to parse the rest of the file. If that happens though we are hosed anyway
// as we still won't know whether this is an struct or enum array.
if (s.str.compare("None") == 0)
{
return property::kind_t::struct_array_property;
r.read_int();
return determine_array_property_kind(r);
// return property::kind_t::struct_array_property;
}


// Try to read another string. If we find a non-zero length string this must be
// an array of strings. Otherwise it's likely an array of enums or structs.
{
Expand Down

0 comments on commit 96b291e

Please sign in to comment.