From: Daniel Karbach Date: Thu, 31 Jan 2013 06:41:28 +0000 (+0100) Subject: use referenced flag of array types X-Git-Url: http://git.localhorst.tv/?p=l2e.git;a=commitdiff_plain;h=dc275497c592669dda75645604a9b35d32f63e90 use referenced flag of array types reference arrays are pointer to pointer to value + an int while "normal" arrays are pointer to value + an int refs #34 --- diff --git a/src/battle/PartyLayout.cpp b/src/battle/PartyLayout.cpp index e46b276..00fa930 100644 --- a/src/battle/PartyLayout.cpp +++ b/src/battle/PartyLayout.cpp @@ -39,7 +39,7 @@ void PartyLayout::CreateTypeDescription() { td.SetConstructor(&Construct); td.SetSize(sizeof(PartyLayout)); - td.AddField("positions", FieldDescription(((char *)&p.positions) - ((char *)&p), Interpreter::VECTOR_ID).SetReferenced().SetAggregate().SetDescription("the members' positions")); + td.AddField("positions", FieldDescription(((char *)&p.positions) - ((char *)&p), Interpreter::VECTOR_ID).SetAggregate().SetDescription("the members' positions")); } void PartyLayout::Construct(void *data) { diff --git a/src/common/Capsule.cpp b/src/common/Capsule.cpp index c8a490e..6667068 100644 --- a/src/common/Capsule.cpp +++ b/src/common/Capsule.cpp @@ -231,9 +231,9 @@ void Capsule::CreateTypeDescription() { td.AddField("level", FieldDescription(((char *)&c.level) - ((char *)&c), Interpreter::NUMBER_ID)); td.AddField("experience", FieldDescription(((char *)&c.experience) - ((char *)&c), Interpreter::NUMBER_ID)); - td.AddField("ladder", FieldDescription(((char *)&c.levelLadder) - ((char *)&c), Interpreter::NUMBER_ID).SetReferenced().SetAggregate()); + td.AddField("ladder", FieldDescription(((char *)&c.levelLadder) - ((char *)&c), Interpreter::NUMBER_ID).SetAggregate()); - td.AddField("classes", FieldDescription(((char *)&c.classes) - ((char *)&c), Class::TYPE_ID).SetReferenced().SetAggregate()); + td.AddField("classes", FieldDescription(((char *)&c.classes) - ((char *)&c), Class::TYPE_ID).SetAggregate()); td.AddField("class", FieldDescription(((char *)&c.curClass) - ((char *)&c), Interpreter::NUMBER_ID)); td.AddField("maxClass", FieldDescription(((char *)&c.maxClass) - ((char *)&c), Interpreter::NUMBER_ID)); diff --git a/src/common/Hero.cpp b/src/common/Hero.cpp index dbd5aed..cca9d43 100644 --- a/src/common/Hero.cpp +++ b/src/common/Hero.cpp @@ -97,7 +97,7 @@ void Hero::CreateTypeDescription() { td.AddField("stats", FieldDescription(((char *)&h.stats) - ((char *)&h), Stats::TYPE_ID)); td.AddField("level", FieldDescription(((char *)&h.level) - ((char *)&h), Interpreter::NUMBER_ID)); - td.AddField("ladder", FieldDescription(((char *)&h.levelLadder) - ((char *)&h), Interpreter::NUMBER_ID).SetReferenced().SetAggregate()); + td.AddField("ladder", FieldDescription(((char *)&h.levelLadder) - ((char *)&h), Interpreter::NUMBER_ID).SetAggregate()); td.AddField("useMask", FieldDescription(((char *)&h.useMask) - ((char *)&h), Interpreter::NUMBER_ID)); diff --git a/src/graphics/ComplexAnimation.cpp b/src/graphics/ComplexAnimation.cpp index c1b88c1..95f5869 100644 --- a/src/graphics/ComplexAnimation.cpp +++ b/src/graphics/ComplexAnimation.cpp @@ -55,7 +55,7 @@ void ComplexAnimation::CreateTypeDescription() { td.AddSupertype(Animation::TYPE_ID, ((char *)a) - ((char *)&ca)); Animation::AddFields(td, ca, ((char *)a) - ((char *)&ca)); - td.AddField("frames", FieldDescription(((char *)&ca.frames) - ((char *)&ca), FrameProp::TYPE_ID).SetReferenced().SetAggregate().SetDescription("a variable number of frames")); + td.AddField("frames", FieldDescription(((char *)&ca.frames) - ((char *)&ca), FrameProp::TYPE_ID).SetAggregate().SetDescription("a variable number of frames")); FrameProp fp; diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index cb15a03..8f9e9dc 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -286,28 +286,45 @@ 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); @@ -316,13 +333,9 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis } } } - 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()) { diff --git a/src/map/Area.cpp b/src/map/Area.cpp index 91018e5..6299290 100644 --- a/src/map/Area.cpp +++ b/src/map/Area.cpp @@ -108,7 +108,7 @@ void Area::CreateTypeDescription() { td.SetSize(sizeof(Area)); td.AddField("battlebg", FieldDescription(((char *)&a.battlebg) - ((char *)&a), Interpreter::IMAGE_ID).SetReferenced()); - td.AddField("tiles", FieldDescription(((char *)&a.tiles) - ((char *)&a), Tile::TYPE_ID).SetReferenced().SetAggregate()); + td.AddField("tiles", FieldDescription(((char *)&a.tiles) - ((char *)&a), Tile::TYPE_ID).SetAggregate()); td.AddField("width", FieldDescription(((char *)&a.width) - ((char *)&a), Interpreter::NUMBER_ID)); } diff --git a/src/map/Map.cpp b/src/map/Map.cpp index 60c319d..85fbd22 100644 --- a/src/map/Map.cpp +++ b/src/map/Map.cpp @@ -162,9 +162,9 @@ void Map::CreateTypeDescription() { td.AddField("tileset", FieldDescription(((char *)&m.tileset) - ((char *)&m), Sprite::TYPE_ID).SetReferenced()); td.AddField("battlebg", FieldDescription(((char *)&m.battlebg) - ((char *)&m), Interpreter::IMAGE_ID).SetReferenced()); - td.AddField("areas", FieldDescription(((char *)&m.areas) - ((char *)&m), Area::TYPE_ID).SetReferenced().SetAggregate()); - td.AddField("triggers", FieldDescription(((char *)&m.triggers) - ((char *)&m), Trigger::TYPE_ID).SetReferenced().SetAggregate()); - td.AddField("entities", FieldDescription(((char *)&m.entities) - ((char *)&m), Entity::TYPE_ID).SetReferenced().SetAggregate()); + td.AddField("areas", FieldDescription(((char *)&m.areas) - ((char *)&m), Area::TYPE_ID).SetAggregate()); + td.AddField("triggers", FieldDescription(((char *)&m.triggers) - ((char *)&m), Trigger::TYPE_ID).SetAggregate()); + td.AddField("entities", FieldDescription(((char *)&m.entities) - ((char *)&m), Entity::TYPE_ID).SetAggregate()); td.AddField("width", FieldDescription(((char *)&m.width) - ((char *)&m), Interpreter::NUMBER_ID)); }