X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=src%2Floader%2FInterpreter.cpp;h=8b54fc177913de18a1266f885cc8e959b6eb4eef;hb=c97ea32c4101fcdadedbfa5eabf8098210306b4b;hp=e64110dbf7175801cbd2cde01aea701ce874d4d1;hpb=a67f7e662c85b2b8d46f26a3c6e018b2df6eb318;p=l2e.git diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index e64110d..8b54fc1 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -1,6 +1,7 @@ #include "Interpreter.h" #include "ParsedSource.h" +#include "TypeDescription.h" #include "../battle/Hero.h" #include "../battle/Monster.h" #include "../battle/PartyLayout.h" @@ -40,7 +41,7 @@ using graphics::Gauge; using graphics::ComplexAnimation; using graphics::SimpleAnimation; using graphics::Sprite; -using geometry::Vector; +using math::Vector; using std::make_pair; using std::set; using std::string; @@ -285,43 +286,56 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis char *dest(object + fd.Offset()); if (fd.IsAggregate()) { int arraySize(i->second->GetLiteral().ArraySize()); - char *aggregate; + size_t memberSize = fd.IsReferenced() ? sizeof(char *) : fieldType.Size(); + char *aggregate = alloc.Alloc(arraySize * memberSize); + char *iter = aggregate; if (i->second->GetLiteral().GetType() == Literal::ARRAY_PROPS) { - aggregate = alloc.Alloc(fieldType.Size() * arraySize); - char *iter = aggregate; const vector &list(i->second->GetLiteral().GetPropertyLists()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) { - fieldType.Construct(iter); - ReadObject(fieldType.TypeId(), -1, iter, **j); + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { + char *member; + if (fd.IsReferenced()) { + member = alloc.Alloc(fieldType.Size()); + *reinterpret_cast(iter) = member; + } else { + member = iter; + } + fieldType.Construct(member); + ReadObject(fieldType.TypeId(), -1, member, **j); } } else if (i->second->GetLiteral().GetType() == Literal::ARRAY_VALUES) { - aggregate = alloc.Alloc(fieldType.Size() * arraySize); - char *iter = aggregate; const vector &list(i->second->GetLiteral().GetValues()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += fieldType.Size()) { - fieldType.Construct(iter); - ReadLiteral(fieldType.TypeId(), -1, iter, (*j)->GetLiteral()); + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { + char *member; + if (fd.IsReferenced()) { + member = alloc.Alloc(fieldType.Size()); + *reinterpret_cast(iter) = member; + } else { + member = iter; + } + fieldType.Construct(member); + ReadLiteral(fieldType.TypeId(), -1, member, (*j)->GetLiteral()); } } else { - aggregate = alloc.Alloc(sizeof(char *) * arraySize); - char *iter = aggregate; + if (!fd.IsReferenced()) { + // TODO: implement inline identifier arrays + throw std::runtime_error("inline identifier arrays not implemented (yet)"); + } const vector &list(i->second->GetLiteral().GetIdentifiers()); - for (vector::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += sizeof(void *)) { + for (vector::const_iterator j(list.begin()), end(list.end()); + j != end; ++j, iter += memberSize) { if (source.IsDefined(*j)) { *reinterpret_cast(iter) = GetObject(fd.TypeId(), *j); } else { - Postpone(typeId, id, fd.Offset() + (iter - aggregate), *j, fd.TypeId(), false); + Postpone(iter, *j, fd.TypeId(), false); } } } - if (fd.IsReferenced()) { - std::memcpy(dest, &aggregate, sizeof(char *)); - dest += sizeof(char *); - std::memcpy(dest, &arraySize, sizeof(int)); - } else { - throw Error("aggregate type fields must be referenced"); - } + std::memcpy(dest, &aggregate, sizeof(char *)); + dest += sizeof(char *); + std::memcpy(dest, &arraySize, sizeof(int)); } else if (i->second->IsLiteral() && !fd.IsReferenced()) { // inline literals if (i->second->GetLiteral().IsObject()) { @@ -341,7 +355,7 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis } } } else { - Postpone(typeId, id, fd.Offset(), i->second->GetIdentifier(), fd.TypeId(), !fd.IsReferenced()); + Postpone(object, i->second->GetIdentifier(), fd.TypeId(), !fd.IsReferenced(), fd.IsAggregate()); } } td.Load(object); @@ -846,11 +860,17 @@ bool Interpreter::CanLink(const Value &v) const { return v.IsLiteral() || source.IsDefined(v.GetIdentifier()); } -void Interpreter::Postpone(int type, int id, std::ptrdiff_t offset, const std::string &identifier, int linkedType, bool inlined) { +void Interpreter::Postpone( + char *dest, + const std::string &identifier, + int type, + bool inlined, + bool aggregate) { char *str(alloc.Alloc(identifier.size() + 1)); std::memcpy(str, identifier.c_str(), identifier.size()); str[identifier.size()] = '\0'; - postponedDefinitions.push_back(PostponedDefinition(type, id, offset, str, linkedType, inlined)); + postponedDefinitions.push_back( + PostponedDefinition(dest, str, type, inlined, aggregate)); }