reference arrays are pointer to pointer to value + an int while
"normal" arrays are pointer to value + an int
refs #34
td.SetConstructor(&Construct);
td.SetSize(sizeof(PartyLayout));
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) {
}
void PartyLayout::Construct(void *data) {
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("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));
td.AddField("class", FieldDescription(((char *)&c.curClass) - ((char *)&c), Interpreter::NUMBER_ID));
td.AddField("maxClass", FieldDescription(((char *)&c.maxClass) - ((char *)&c), Interpreter::NUMBER_ID));
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("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));
td.AddField("useMask", FieldDescription(((char *)&h.useMask) - ((char *)&h), Interpreter::NUMBER_ID));
td.AddSupertype(Animation::TYPE_ID, ((char *)a) - ((char *)&ca));
Animation::AddFields(td, ca, ((char *)a) - ((char *)&ca));
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"));
char *dest(object + fd.Offset());
if (fd.IsAggregate()) {
int arraySize(i->second->GetLiteral().ArraySize());
char *dest(object + fd.Offset());
if (fd.IsAggregate()) {
int arraySize(i->second->GetLiteral().ArraySize());
+ 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) {
if (i->second->GetLiteral().GetType() == Literal::ARRAY_PROPS) {
- aggregate = alloc.Alloc(fieldType.Size() * arraySize);
- char *iter = aggregate;
const vector<PropertyList *> &list(i->second->GetLiteral().GetPropertyLists());
const vector<PropertyList *> &list(i->second->GetLiteral().GetPropertyLists());
- for (vector<PropertyList *>::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<PropertyList *>::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<char **>(iter) = member;
+ } else {
+ member = iter;
+ }
+ fieldType.Construct(member);
+ ReadObject(fieldType.TypeId(), -1, member, **j);
}
} else if (i->second->GetLiteral().GetType() == Literal::ARRAY_VALUES) {
}
} else if (i->second->GetLiteral().GetType() == Literal::ARRAY_VALUES) {
- aggregate = alloc.Alloc(fieldType.Size() * arraySize);
- char *iter = aggregate;
const vector<Value *> &list(i->second->GetLiteral().GetValues());
const vector<Value *> &list(i->second->GetLiteral().GetValues());
- for (vector<Value *>::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<Value *>::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<char **>(iter) = member;
+ } else {
+ member = iter;
+ }
+ fieldType.Construct(member);
+ ReadLiteral(fieldType.TypeId(), -1, member, (*j)->GetLiteral());
- 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<string> &list(i->second->GetLiteral().GetIdentifiers());
const vector<string> &list(i->second->GetLiteral().GetIdentifiers());
- for (vector<string>::const_iterator j(list.begin()), end(list.end()); j != end; ++j, iter += sizeof(void *)) {
+ for (vector<string>::const_iterator j(list.begin()), end(list.end());
+ j != end; ++j, iter += memberSize) {
if (source.IsDefined(*j)) {
*reinterpret_cast<void **>(iter)
= GetObject(fd.TypeId(), *j);
if (source.IsDefined(*j)) {
*reinterpret_cast<void **>(iter)
= GetObject(fd.TypeId(), *j);
- 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()) {
} else if (i->second->IsLiteral() && !fd.IsReferenced()) {
// inline literals
if (i->second->GetLiteral().IsObject()) {
td.SetSize(sizeof(Area));
td.AddField("battlebg", FieldDescription(((char *)&a.battlebg) - ((char *)&a), Interpreter::IMAGE_ID).SetReferenced());
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));
}
td.AddField("width", FieldDescription(((char *)&a.width) - ((char *)&a), Interpreter::NUMBER_ID));
}
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("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));
}
td.AddField("width", FieldDescription(((char *)&m.width) - ((char *)&m), Interpreter::NUMBER_ID));
}