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));
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<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) {
- aggregate = alloc.Alloc(fieldType.Size() * arraySize);
- char *iter = aggregate;
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());
}
} 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<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 (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()) {
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));
}