[Scummvm-cvs-logs] scummvm master -> c51c89ca3232a4bb128949b033f8f771aeff6dc3

lordhoto lordhoto at gmail.com
Wed Apr 6 23:05:58 CEST 2016


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
77b5ce075a SCI: Get rid of template hack for serialization.
1c6112e121 SCI: Introduce accessors for SegmentObjTable entries.
f23dd0f486 SCI: Use aggregation to store objects in SegmentObjTable.
c11b09dff9 SCI: Remove commented out code line.
c51c89ca32 Merge pull request #721 from lordhoto/sci-saveload-cleanup


Commit: 77b5ce075a70f2f9c835fa085194a5a941f26459
    https://github.com/scummvm/scummvm/commit/77b5ce075a70f2f9c835fa085194a5a941f26459
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-25T01:15:26+01:00

Commit Message:
SCI: Get rid of template hack for serialization.

The former template hack relied on specialized functions for various types. We
use a hand crafted set of functions for serialization functionality now.

Changed paths:
    engines/sci/engine/savegame.cpp



diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index fcb6515..66e8101 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -60,15 +60,121 @@ namespace Sci {
 
 #pragma mark -
 
-// Experimental hack: Use syncWithSerializer to sync. By default, this assume
-// the object to be synced is a subclass of Serializable and thus tries to invoke
-// the saveLoadWithSerializer() method. But it is possible to specialize this
-// template function to handle stuff that is not implementing that interface.
-template<typename T>
-void syncWithSerializer(Common::Serializer &s, T &obj) {
+// These are serialization functions for various objects.
+
+void syncWithSerializer(Common::Serializer &s, Common::Serializable &obj) {
 	obj.saveLoadWithSerializer(s);
 }
 
+// FIXME: Object could implement Serializable to make use of the function
+// above.
+void syncWithSerializer(Common::Serializer &s, Object &obj) {
+	obj.saveLoadWithSerializer(s);
+}
+
+void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
+	// Segment and offset are accessed directly here
+	s.syncAsUint16LE(obj._segment);
+	s.syncAsUint16LE(obj._offset);
+}
+
+void syncWithSerializer(Common::Serializer &s, synonym_t &obj) {
+	s.syncAsUint16LE(obj.replaceant);
+	s.syncAsUint16LE(obj.replacement);
+}
+
+void syncWithSerializer(Common::Serializer &s, Class &obj) {
+	s.syncAsSint32LE(obj.script);
+	syncWithSerializer(s, obj.reg);
+}
+
+void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Clone>::Entry &obj) {
+	s.syncAsSint32LE(obj.next_free);
+
+	syncWithSerializer(s, (Clone &)obj);
+}
+
+void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj) {
+	s.syncAsSint32LE(obj.next_free);
+
+	syncWithSerializer(s, obj.first);
+	syncWithSerializer(s, obj.last);
+}
+
+void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj) {
+	s.syncAsSint32LE(obj.next_free);
+
+	syncWithSerializer(s, obj.pred);
+	syncWithSerializer(s, obj.succ);
+	syncWithSerializer(s, obj.key);
+	syncWithSerializer(s, obj.value);
+}
+
+#ifdef ENABLE_SCI32
+void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >::Entry &obj) {
+	s.syncAsSint32LE(obj.next_free);
+
+	byte type = 0;
+	uint32 size = 0;
+
+	if (s.isSaving()) {
+		type = (byte)obj.getType();
+		size = obj.getSize();
+	}
+	s.syncAsByte(type);
+	s.syncAsUint32LE(size);
+	if (s.isLoading()) {
+		obj.setType((int8)type);
+
+		// HACK: Skip arrays that have a negative type
+		if ((int8)type < 0)
+			return;
+
+		obj.setSize(size);
+	}
+
+	for (uint32 i = 0; i < size; i++) {
+		reg_t value;
+
+		if (s.isSaving())
+			value = obj.getValue(i);
+
+		syncWithSerializer(s, value);
+
+		if (s.isLoading())
+			obj.setValue(i, value);
+	}
+}
+
+void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry &obj) {
+	s.syncAsSint32LE(obj.next_free);
+
+	uint32 size = 0;
+
+	if (s.isSaving()) {
+		size = obj.getSize();
+		s.syncAsUint32LE(size);
+	} else {
+		s.syncAsUint32LE(size);
+		obj.setSize(size);
+	}
+
+	for (uint32 i = 0; i < size; i++) {
+		char value = 0;
+
+		if (s.isSaving())
+			value = obj.getValue(i);
+
+		s.syncAsByte(value);
+
+		if (s.isLoading())
+			obj.setValue(i, value);
+	}
+}
+#endif
+
+#pragma mark -
+
 // By default, sync using syncWithSerializer, which in turn can easily be overloaded.
 template<typename T>
 struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> {
@@ -116,20 +222,6 @@ void syncArray(Common::Serializer &s, Common::Array<T> &arr) {
 	sync(s, arr);
 }
 
-
-template<>
-void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
-	// Segment and offset are accessed directly here
-	s.syncAsUint16LE(obj._segment);
-	s.syncAsUint16LE(obj._offset);
-}
-
-template<>
-void syncWithSerializer(Common::Serializer &s, synonym_t &obj) {
-	s.syncAsUint16LE(obj.replaceant);
-	s.syncAsUint16LE(obj.replacement);
-}
-
 void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
 	if (s.isLoading()) {
 		resetSegMan();
@@ -247,12 +339,6 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
 }
 
 
-template<>
-void syncWithSerializer(Common::Serializer &s, Class &obj) {
-	s.syncAsSint32LE(obj.script);
-	syncWithSerializer(s, obj.reg);
-}
-
 static void sync_SavegameMetadata(Common::Serializer &s, SavegameMetadata &obj) {
 	s.syncString(obj.name);
 	s.syncVersion(CURRENT_SAVEGAME_VERSION);
@@ -331,95 +417,6 @@ void Object::saveLoadWithSerializer(Common::Serializer &s) {
 	syncArray<reg_t>(s, _variables);
 }
 
-template<>
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Clone>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
-	syncWithSerializer<Object>(s, obj);
-}
-
-template<>
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
-	syncWithSerializer(s, obj.first);
-	syncWithSerializer(s, obj.last);
-}
-
-template<>
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
-	syncWithSerializer(s, obj.pred);
-	syncWithSerializer(s, obj.succ);
-	syncWithSerializer(s, obj.key);
-	syncWithSerializer(s, obj.value);
-}
-
-#ifdef ENABLE_SCI32
-template<>
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
-	byte type = 0;
-	uint32 size = 0;
-
-	if (s.isSaving()) {
-		type = (byte)obj.getType();
-		size = obj.getSize();
-	}
-	s.syncAsByte(type);
-	s.syncAsUint32LE(size);
-	if (s.isLoading()) {
-		obj.setType((int8)type);
-
-		// HACK: Skip arrays that have a negative type
-		if ((int8)type < 0)
-			return;
-
-		obj.setSize(size);
-	}
-
-	for (uint32 i = 0; i < size; i++) {
-		reg_t value;
-
-		if (s.isSaving())
-			value = obj.getValue(i);
-
-		syncWithSerializer(s, value);
-
-		if (s.isLoading())
-			obj.setValue(i, value);
-	}
-}
-
-template<>
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
-	uint32 size = 0;
-
-	if (s.isSaving()) {
-		size = obj.getSize();
-		s.syncAsUint32LE(size);
-	} else {
-		s.syncAsUint32LE(size);
-		obj.setSize(size);
-	}
-
-	for (uint32 i = 0; i < size; i++) {
-		char value = 0;
-
-		if (s.isSaving())
-			value = obj.getValue(i);
-
-		s.syncAsByte(value);
-
-		if (s.isLoading())
-			obj.setValue(i, value);
-	}
-}
-#endif
 
 template<typename T>
 void sync_Table(Common::Serializer &s, T &obj) {


Commit: 1c6112e121c6a70df965d6cba1b382d1a3cdbc9c
    https://github.com/scummvm/scummvm/commit/1c6112e121c6a70df965d6cba1b382d1a3cdbc9c
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-25T01:15:26+01:00

Commit Message:
SCI: Introduce accessors for SegmentObjTable entries.

This makes code not use _table directly whenever possible. An exception is the
save game code which is not easy to adapt due to design deficiencies.

Changed paths:
    engines/sci/console.cpp
    engines/sci/engine/scriptdebug.cpp
    engines/sci/engine/seg_manager.cpp
    engines/sci/engine/segment.cpp
    engines/sci/engine/segment.h



diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index a092e06..1661f92 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -1861,7 +1861,7 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
 
 	for (uint i = 0; i < entries.size(); ++i) {
 		uint16 offset = entries[i].getOffset();
-		const Hunk& h = hunks->_table[offset];
+		const Hunk& h = hunks->at(offset);
 		if (strcmp(h.type, "SaveBits()") == 0) {
 			byte* memoryPtr = (byte *)h.mem;
 
@@ -1928,7 +1928,7 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
 		return true;
 	}
 
-	const Hunk& h = hunks->_table[memoryHandle.getOffset()];
+	const Hunk& h = hunks->at(memoryHandle.getOffset());
 
 	if (strcmp(h.type, "SaveBits()") != 0) {
 		debugPrintf("Invalid address.\n");
@@ -2144,32 +2144,32 @@ bool Console::segmentInfo(int nr) {
 	break;
 
 	case SEG_TYPE_CLONES: {
-		CloneTable *ct = (CloneTable *)mobj;
+		CloneTable &ct = *(CloneTable *)mobj;
 
 		debugPrintf("clones\n");
 
-		for (uint i = 0; i < ct->_table.size(); i++)
-			if (ct->isValidEntry(i)) {
+		for (uint i = 0; i < ct.size(); i++)
+			if (ct.isValidEntry(i)) {
 				reg_t objpos = make_reg(nr, i);
 				debugPrintf("  [%04x] %s; copy of ", i, _engine->_gamestate->_segMan->getObjectName(objpos));
 				// Object header
-				const Object *obj = _engine->_gamestate->_segMan->getObject(ct->_table[i].getPos());
+				const Object *obj = _engine->_gamestate->_segMan->getObject(ct[i].getPos());
 				if (obj)
-					debugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()),
-								_engine->_gamestate->_segMan->getObjectName(ct->_table[i].getPos()),
+					debugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct[i].getPos()),
+								_engine->_gamestate->_segMan->getObjectName(ct[i].getPos()),
 								obj->getVarCount(), obj->getMethodCount());
 			}
 	}
 	break;
 
 	case SEG_TYPE_LISTS: {
-		ListTable *lt = (ListTable *)mobj;
+		ListTable &lt = *(ListTable *)mobj;
 
 		debugPrintf("lists\n");
-		for (uint i = 0; i < lt->_table.size(); i++)
-			if (lt->isValidEntry(i)) {
+		for (uint i = 0; i < lt.size(); i++)
+			if (lt.isValidEntry(i)) {
 				debugPrintf("  [%04x]: ", i);
-				printList(&(lt->_table[i]));
+				printList(&lt[i]);
 			}
 	}
 	break;
@@ -2180,13 +2180,13 @@ bool Console::segmentInfo(int nr) {
 	}
 
 	case SEG_TYPE_HUNK: {
-		HunkTable *ht = (HunkTable *)mobj;
+		HunkTable &ht = *(HunkTable *)mobj;
 
-		debugPrintf("hunk  (total %d)\n", ht->entries_used);
-		for (uint i = 0; i < ht->_table.size(); i++)
-			if (ht->isValidEntry(i)) {
+		debugPrintf("hunk  (total %d)\n", ht.entries_used);
+		for (uint i = 0; i < ht.size(); i++)
+			if (ht.isValidEntry(i)) {
 				debugPrintf("    [%04x] %d bytes at %p, type=%s\n",
-				          i, ht->_table[i].size, ht->_table[i].mem, ht->_table[i].type);
+				          i, ht[i].size, ht[i].mem, ht[i].type);
 			}
 	}
 	break;
@@ -4362,7 +4362,7 @@ void Console::printList(List *list) {
 			return;
 		}
 
-		node = &(nt->_table[pos.getOffset()]);
+		node = &nt->at(pos.getOffset());
 
 		debugPrintf("\t%04x:%04x  : %04x:%04x -> %04x:%04x\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value));
 
@@ -4392,7 +4392,7 @@ int Console::printNode(reg_t addr) {
 			return 1;
 		}
 
-		list = &(lt->_table[addr.getOffset()]);
+		list = &lt->at(addr.getOffset());
 
 		debugPrintf("%04x:%04x : first x last = (%04x:%04x, %04x:%04x)\n", PRINT_REG(addr), PRINT_REG(list->first), PRINT_REG(list->last));
 	} else {
@@ -4411,7 +4411,7 @@ int Console::printNode(reg_t addr) {
 			debugPrintf("Address does not contain a node\n");
 			return 1;
 		}
-		node = &(nt->_table[addr.getOffset()]);
+		node = &nt->at(addr.getOffset());
 
 		debugPrintf("%04x:%04x : prev x next = (%04x:%04x, %04x:%04x); maps %04x:%04x -> %04x:%04x\n",
 		          PRINT_REG(addr), PRINT_REG(node->pred), PRINT_REG(node->succ), PRINT_REG(node->key), PRINT_REG(node->value));
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 7d70f30..b017e62 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -741,13 +741,13 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke
 					switch (mobj->getType()) {
 					case SEG_TYPE_HUNK:
 					{
-						HunkTable *ht = (HunkTable *)mobj;
+						HunkTable &ht = *(HunkTable *)mobj;
 						int index = argv[parmNr].getOffset();
-						if (ht->isValidEntry(index)) {
+						if (ht.isValidEntry(index)) {
 							// NOTE: This ", deleted" isn't as useful as it could
 							// be because it prints the status _after_ the kernel
 							// call.
-							debugN(" ('%s' hunk%s)", ht->_table[index].type, ht->_table[index].mem ? "" : ", deleted");
+							debugN(" ('%s' hunk%s)", ht[index].type, ht[index].mem ? "" : ", deleted");
 						} else
 							debugN(" (INVALID hunk ref)");
 						break;
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 8090b18..95e3cd1 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -247,9 +247,9 @@ Object *SegManager::getObject(reg_t pos) const {
 
 	if (mobj != NULL) {
 		if (mobj->getType() == SEG_TYPE_CLONES) {
-			CloneTable *ct = (CloneTable *)mobj;
-			if (ct->isValidEntry(pos.getOffset()))
-				obj = &(ct->_table[pos.getOffset()]);
+			CloneTable &ct = *(CloneTable *)mobj;
+			if (ct.isValidEntry(pos.getOffset()))
+				obj = &(ct[pos.getOffset()]);
 			else
 				warning("getObject(): Trying to get an invalid object");
 		} else if (mobj->getType() == SEG_TYPE_SCRIPT) {
@@ -313,7 +313,7 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {
 		} else if (mobj->getType() == SEG_TYPE_CLONES) {
 			// It's clone table, scan all objects in it
 			const CloneTable *ct = (const CloneTable *)mobj;
-			for (uint idx = 0; idx < ct->_table.size(); ++idx) {
+			for (uint idx = 0; idx < ct->size(); ++idx) {
 				if (!ct->isValidEntry(idx))
 					continue;
 
@@ -404,7 +404,7 @@ reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
 	offset = table->allocEntry();
 
 	reg_t addr = make_reg(_hunksSegId, offset);
-	Hunk *h = &(table->_table[offset]);
+	Hunk *h = &table->at(offset);
 
 	if (!h)
 		return NULL_REG;
@@ -424,7 +424,7 @@ byte *SegManager::getHunkPointer(reg_t addr) {
 		return NULL;
 	}
 
-	return (byte *)ht->_table[addr.getOffset()].mem;
+	return (byte *)ht->at(addr.getOffset()).mem;
 }
 
 Clone *SegManager::allocateClone(reg_t *addr) {
@@ -439,7 +439,7 @@ Clone *SegManager::allocateClone(reg_t *addr) {
 	offset = table->allocEntry();
 
 	*addr = make_reg(_clonesSegId, offset);
-	return &(table->_table[offset]);
+	return &table->at(offset);
 }
 
 List *SegManager::allocateList(reg_t *addr) {
@@ -453,7 +453,7 @@ List *SegManager::allocateList(reg_t *addr) {
 	offset = table->allocEntry();
 
 	*addr = make_reg(_listsSegId, offset);
-	return &(table->_table[offset]);
+	return &table->at(offset);
 }
 
 Node *SegManager::allocateNode(reg_t *addr) {
@@ -467,7 +467,7 @@ Node *SegManager::allocateNode(reg_t *addr) {
 	offset = table->allocEntry();
 
 	*addr = make_reg(_nodesSegId, offset);
-	return &(table->_table[offset]);
+	return &table->at(offset);
 }
 
 reg_t SegManager::newNode(reg_t value, reg_t key) {
@@ -486,14 +486,14 @@ List *SegManager::lookupList(reg_t addr) {
 		return NULL;
 	}
 
-	ListTable *lt = (ListTable *)_heap[addr.getSegment()];
+	ListTable &lt = *(ListTable *)_heap[addr.getSegment()];
 
-	if (!lt->isValidEntry(addr.getOffset())) {
+	if (!lt.isValidEntry(addr.getOffset())) {
 		error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr));
 		return NULL;
 	}
 
-	return &(lt->_table[addr.getOffset()]);
+	return &(lt[addr.getOffset()]);
 }
 
 Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) {
@@ -507,9 +507,9 @@ Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) {
 		return NULL;
 	}
 
-	NodeTable *nt = (NodeTable *)_heap[addr.getSegment()];
+	NodeTable &nt = *(NodeTable *)_heap[addr.getSegment()];
 
-	if (!nt->isValidEntry(addr.getOffset())) {
+	if (!nt.isValidEntry(addr.getOffset())) {
 		if (!stopOnDiscarded)
 			return NULL;
 
@@ -517,7 +517,7 @@ Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) {
 		return NULL;
 	}
 
-	return &(nt->_table[addr.getOffset()]);
+	return &(nt[addr.getOffset()]);
 }
 
 SegmentRef SegManager::dereference(reg_t pointer) {
@@ -873,32 +873,32 @@ SciArray<reg_t> *SegManager::allocateArray(reg_t *addr) {
 	offset = table->allocEntry();
 
 	*addr = make_reg(_arraysSegId, offset);
-	return &(table->_table[offset]);
+	return &table->at(offset);
 }
 
 SciArray<reg_t> *SegManager::lookupArray(reg_t addr) {
 	if (_heap[addr.getSegment()]->getType() != SEG_TYPE_ARRAY)
 		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
 
-	ArrayTable *arrayTable = (ArrayTable *)_heap[addr.getSegment()];
+	ArrayTable &arrayTable = *(ArrayTable *)_heap[addr.getSegment()];
 
-	if (!arrayTable->isValidEntry(addr.getOffset()))
+	if (!arrayTable.isValidEntry(addr.getOffset()))
 		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
 
-	return &(arrayTable->_table[addr.getOffset()]);
+	return &(arrayTable[addr.getOffset()]);
 }
 
 void SegManager::freeArray(reg_t addr) {
 	if (_heap[addr.getSegment()]->getType() != SEG_TYPE_ARRAY)
 		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
 
-	ArrayTable *arrayTable = (ArrayTable *)_heap[addr.getSegment()];
+	ArrayTable &arrayTable = *(ArrayTable *)_heap[addr.getSegment()];
 
-	if (!arrayTable->isValidEntry(addr.getOffset()))
+	if (!arrayTable.isValidEntry(addr.getOffset()))
 		error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
 
-	arrayTable->_table[addr.getOffset()].destroy();
-	arrayTable->freeEntry(addr.getOffset());
+	arrayTable[addr.getOffset()].destroy();
+	arrayTable.freeEntry(addr.getOffset());
 }
 
 SciString *SegManager::allocateString(reg_t *addr) {
@@ -913,32 +913,32 @@ SciString *SegManager::allocateString(reg_t *addr) {
 	offset = table->allocEntry();
 
 	*addr = make_reg(_stringSegId, offset);
-	return &(table->_table[offset]);
+	return &table->at(offset);
 }
 
 SciString *SegManager::lookupString(reg_t addr) {
 	if (_heap[addr.getSegment()]->getType() != SEG_TYPE_STRING)
 		error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
 
-	StringTable *stringTable = (StringTable *)_heap[addr.getSegment()];
+	StringTable &stringTable = *(StringTable *)_heap[addr.getSegment()];
 
-	if (!stringTable->isValidEntry(addr.getOffset()))
+	if (!stringTable.isValidEntry(addr.getOffset()))
 		error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
 
-	return &(stringTable->_table[addr.getOffset()]);
+	return &(stringTable[addr.getOffset()]);
 }
 
 void SegManager::freeString(reg_t addr) {
 	if (_heap[addr.getSegment()]->getType() != SEG_TYPE_STRING)
 		error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
 
-	StringTable *stringTable = (StringTable *)_heap[addr.getSegment()];
+	StringTable &stringTable = *(StringTable *)_heap[addr.getSegment()];
 
-	if (!stringTable->isValidEntry(addr.getOffset()))
+	if (!stringTable.isValidEntry(addr.getOffset()))
 		error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
 
-	stringTable->_table[addr.getOffset()].destroy();
-	stringTable->freeEntry(addr.getOffset());
+	stringTable[addr.getOffset()].destroy();
+	stringTable.freeEntry(addr.getOffset());
 }
 
 #endif
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index bb90698..2cff799 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -97,7 +97,7 @@ Common::Array<reg_t> CloneTable::listAllOutgoingReferences(reg_t addr) const {
 		error("Unexpected request for outgoing references from clone at %04x:%04x", PRINT_REG(addr));
 	}
 
-	const Clone *clone = &(_table[addr.getOffset()]);
+	const Clone *clone = &at(addr.getOffset());
 
 	// Emit all member variables (including references to the 'super' delegate)
 	for (uint i = 0; i < clone->getVarCount(); i++)
@@ -112,7 +112,7 @@ Common::Array<reg_t> CloneTable::listAllOutgoingReferences(reg_t addr) const {
 
 void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) {
 #ifdef GC_DEBUG
-	Object *victim_obj = &(_table[addr.getOffset()]);
+	Object *victim_obj = &at(addr.getOffset());
 
 	if (!(victim_obj->_flags & OBJECT_FLAG_FREED))
 		warning("[GC] Clone %04x:%04x not reachable and not freed (freeing now)", PRINT_REG(addr));
@@ -208,7 +208,7 @@ Common::Array<reg_t> ListTable::listAllOutgoingReferences(reg_t addr) const {
 		error("Invalid list referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
 	}
 
-	const List *list = &(_table[addr.getOffset()]);
+	const List *list = &at(addr.getOffset());
 
 	tmp.push_back(list->first);
 	tmp.push_back(list->last);
@@ -225,7 +225,7 @@ Common::Array<reg_t> NodeTable::listAllOutgoingReferences(reg_t addr) const {
 	if (!isValidEntry(addr.getOffset())) {
 		error("Invalid node referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
 	}
-	const Node *node = &(_table[addr.getOffset()]);
+	const Node *node = &at(addr.getOffset());
 
 	// We need all four here. Can't just stick with 'pred' OR 'succ' because node operations allow us
 	// to walk around from any given node
@@ -252,13 +252,13 @@ SegmentRef DynMem::dereference(reg_t pointer) {
 SegmentRef ArrayTable::dereference(reg_t pointer) {
 	SegmentRef ret;
 	ret.isRaw = false;
-	ret.maxSize = _table[pointer.getOffset()].getSize() * 2;
-	ret.reg = _table[pointer.getOffset()].getRawData();
+	ret.maxSize = at(pointer.getOffset()).getSize() * 2;
+	ret.reg = at(pointer.getOffset()).getRawData();
 	return ret;
 }
 
 void ArrayTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
-	_table[sub_addr.getOffset()].destroy();
+	at(sub_addr.getOffset()).destroy();
 	freeEntry(sub_addr.getOffset());
 }
 
@@ -268,7 +268,7 @@ Common::Array<reg_t> ArrayTable::listAllOutgoingReferences(reg_t addr) const {
 		error("Invalid array referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
 	}
 
-	const SciArray<reg_t> *array = &(_table[addr.getOffset()]);
+	const SciArray<reg_t> *array = &at(addr.getOffset());
 
 	for (uint32 i = 0; i < array->getSize(); i++) {
 		reg_t value = array->getValue(i);
@@ -305,8 +305,8 @@ void SciString::fromString(const Common::String &string) {
 SegmentRef StringTable::dereference(reg_t pointer) {
 	SegmentRef ret;
 	ret.isRaw = true;
-	ret.maxSize = _table[pointer.getOffset()].getSize();
-	ret.raw = (byte *)_table[pointer.getOffset()].getRawData();
+	ret.maxSize = at(pointer.getOffset()).getSize();
+	ret.raw = (byte *)at(pointer.getOffset()).getRawData();
 	return ret;
 }
 
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 2699bc2..529f6b7 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -215,7 +215,6 @@ struct SegmentObjTable : public SegmentObj {
 	};
 	enum { HEAPENTRY_INVALID = -1 };
 
-
 	int first_free; /**< Beginning of a singly linked list for entries */
 	int entries_used; /**< Statistical information */
 
@@ -272,6 +271,14 @@ public:
 				tmp.push_back(make_reg(segId, i));
 		return tmp;
 	}
+
+	uint size() const { return _table.size(); }
+
+	T &at(uint index) { return _table[index]; }
+	const T &at(uint index) const { return _table[index]; }
+
+	T &operator[](uint index) { return at(index); }
+	const T &operator[](uint index) const { return at(index); }
 };
 
 
@@ -323,8 +330,8 @@ struct HunkTable : public SegmentObjTable<Hunk> {
 	}
 
 	void freeEntryContents(int idx) {
-		free(_table[idx].mem);
-		_table[idx].mem = 0;
+		free(at(idx).mem);
+		at(idx).mem = 0;
 	}
 
 	virtual void freeEntry(int idx) {
@@ -502,7 +509,7 @@ struct StringTable : public SegmentObjTable<SciString> {
 	StringTable() : SegmentObjTable<SciString>(SEG_TYPE_STRING) {}
 
 	virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
-		_table[sub_addr.getOffset()].destroy();
+		at(sub_addr.getOffset()).destroy();
 		freeEntry(sub_addr.getOffset());
 	}
 


Commit: f23dd0f4864a0d6b1e6e54159e4948249b15fc80
    https://github.com/scummvm/scummvm/commit/f23dd0f4864a0d6b1e6e54159e4948249b15fc80
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-25T01:15:26+01:00

Commit Message:
SCI: Use aggregation to store objects in SegmentObjTable.

This allows to store pointers and fundamental types in a SegmentObjTable.

Changed paths:
    engines/sci/engine/savegame.cpp
    engines/sci/engine/segment.h



diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 66e8101..3a9ce00 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -88,22 +88,12 @@ void syncWithSerializer(Common::Serializer &s, Class &obj) {
 	syncWithSerializer(s, obj.reg);
 }
 
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Clone>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
-	syncWithSerializer(s, (Clone &)obj);
-}
-
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
+void syncWithSerializer(Common::Serializer &s, List &obj) {
 	syncWithSerializer(s, obj.first);
 	syncWithSerializer(s, obj.last);
 }
 
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
+void syncWithSerializer(Common::Serializer &s, Node &obj) {
 	syncWithSerializer(s, obj.pred);
 	syncWithSerializer(s, obj.succ);
 	syncWithSerializer(s, obj.key);
@@ -111,9 +101,7 @@ void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj
 }
 
 #ifdef ENABLE_SCI32
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
+void syncWithSerializer(Common::Serializer &s, SciArray<reg_t> &obj) {
 	byte type = 0;
 	uint32 size = 0;
 
@@ -146,9 +134,7 @@ void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >
 	}
 }
 
-void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry &obj) {
-	s.syncAsSint32LE(obj.next_free);
-
+void syncWithSerializer(Common::Serializer &s, SciString &obj) {
 	uint32 size = 0;
 
 	if (s.isSaving()) {
@@ -184,6 +170,16 @@ struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> {
 	}
 };
 
+// Syncer for entries in a segment obj table
+template<typename T>
+struct SegmentObjTableEntrySyncer : Common::BinaryFunction<Common::Serializer, typename T::Entry &, void> {
+	void operator()(Common::Serializer &s, typename T::Entry &entry) const {
+		s.syncAsSint32LE(entry.next_free);
+
+		syncWithSerializer(s, entry.data);
+	}
+};
+
 /**
  * Sync a Common::Array using a Common::Serializer.
  * When saving, this writes the length of the array, then syncs (writes) all entries.
@@ -216,9 +212,9 @@ struct ArraySyncer : Common::BinaryFunction<Common::Serializer, T, void> {
 };
 
 // Convenience wrapper
-template<typename T>
+template<typename T, class Syncer = DefaultSyncer<T>>
 void syncArray(Common::Serializer &s, Common::Array<T> &arr) {
-	ArraySyncer<T> sync;
+	ArraySyncer<T, Syncer> sync;
 	sync(s, arr);
 }
 
@@ -423,7 +419,7 @@ void sync_Table(Common::Serializer &s, T &obj) {
 	s.syncAsSint32LE(obj.first_free);
 	s.syncAsSint32LE(obj.entries_used);
 
-	syncArray<typename T::Entry>(s, obj._table);
+	syncArray<typename T::Entry, SegmentObjTableEntrySyncer<T> >(s, obj._table);
 }
 
 void CloneTable::saveLoadWithSerializer(Common::Serializer &s) {
@@ -900,7 +896,7 @@ void SegManager::reconstructClones() {
 				if (!isUsed)
 					continue;
 
-				CloneTable::Entry &seeker = ct->_table[j];
+				CloneTable::value_type &seeker = ct->at(j);
 				const Object *baseObj = getObject(seeker.getSpeciesSelector());
 				seeker.cloneFromObject(baseObj);
 				if (!baseObj) {
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 529f6b7..50c77d0 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -210,7 +210,8 @@ struct Hunk {
 template<typename T>
 struct SegmentObjTable : public SegmentObj {
 	typedef T value_type;
-	struct Entry : public T {
+	struct Entry {
+		T data;
 		int next_free; /* Only used for free entries */
 	};
 	enum { HEAPENTRY_INVALID = -1 };
@@ -218,7 +219,8 @@ struct SegmentObjTable : public SegmentObj {
 	int first_free; /**< Beginning of a singly linked list for entries */
 	int entries_used; /**< Statistical information */
 
-	Common::Array<Entry> _table;
+	typedef Common::Array<Entry> ArrayType;
+	ArrayType _table;
 
 public:
 	SegmentObjTable(SegmentType type) : SegmentObj(type) {
@@ -274,8 +276,8 @@ public:
 
 	uint size() const { return _table.size(); }
 
-	T &at(uint index) { return _table[index]; }
-	const T &at(uint index) const { return _table[index]; }
+	T &at(uint index) { return _table[index].data; }
+	const T &at(uint index) const { return _table[index].data; }
 
 	T &operator[](uint index) { return at(index); }
 	const T &operator[](uint index) const { return at(index); }


Commit: c11b09dff91bdb5047722a0a4399f34fcc042589
    https://github.com/scummvm/scummvm/commit/c11b09dff91bdb5047722a0a4399f34fcc042589
Author: Johannes Schickel (lordhoto at scummvm.org)
Date: 2016-03-25T01:15:26+01:00

Commit Message:
SCI: Remove commented out code line.

Changed paths:
    engines/sci/engine/savegame.cpp



diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 3a9ce00..48d5e44 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -165,7 +165,6 @@ void syncWithSerializer(Common::Serializer &s, SciString &obj) {
 template<typename T>
 struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> {
 	void operator()(Common::Serializer &s, T &obj) const {
-		//obj.saveLoadWithSerializer(s);
 		syncWithSerializer(s, obj);
 	}
 };


Commit: c51c89ca3232a4bb128949b033f8f771aeff6dc3
    https://github.com/scummvm/scummvm/commit/c51c89ca3232a4bb128949b033f8f771aeff6dc3
Author: Johannes Schickel (lordhoto at gmail.com)
Date: 2016-04-06T23:05:54+02:00

Commit Message:
Merge pull request #721 from lordhoto/sci-saveload-cleanup

SCI: Cleanup of Save/Load Code

Changed paths:
    engines/sci/console.cpp
    engines/sci/engine/savegame.cpp
    engines/sci/engine/scriptdebug.cpp
    engines/sci/engine/seg_manager.cpp
    engines/sci/engine/segment.cpp
    engines/sci/engine/segment.h









More information about the Scummvm-git-logs mailing list