[Scummvm-cvs-logs] SF.net SVN: scummvm:[38782] scummvm/trunk/engines/sci/engine

jvprat at users.sourceforge.net jvprat at users.sourceforge.net
Sun Feb 22 13:18:23 CET 2009


Revision: 38782
          http://scummvm.svn.sourceforge.net/scummvm/?rev=38782&view=rev
Author:   jvprat
Date:     2009-02-22 12:18:22 +0000 (Sun, 22 Feb 2009)

Log Message:
-----------
SCI: Converted "segment interfaces" into classes

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/gc.cpp
    scummvm/trunk/engines/sci/engine/scriptdebug.cpp
    scummvm/trunk/engines/sci/engine/seg_manager.cpp
    scummvm/trunk/engines/sci/engine/seg_manager.h

Modified: scummvm/trunk/engines/sci/engine/gc.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/gc.cpp	2009-02-22 10:20:45 UTC (rev 38781)
+++ scummvm/trunk/engines/sci/engine/gc.cpp	2009-02-22 12:18:22 UTC (rev 38782)
@@ -100,7 +100,7 @@
 	}
 }
 
-static reg_t_hash_map * normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, SegInterface **interfaces, int interfaces_nr) {
+static reg_t_hash_map *normalise_hashmap_ptrs(reg_t_hash_map *nonnormal_map, SegInterface **interfaces, int interfaces_nr) {
 	reg_t_hash_map *normal_map = new reg_t_hash_map();
 
 	for (reg_t_hash_map::iterator i = nonnormal_map->begin(); i != nonnormal_map->end(); ++i) {
@@ -109,7 +109,7 @@
 		interfce = (reg.segment < interfaces_nr) ? interfaces[reg.segment] : NULL;
 
 		if (interfce) {
-			reg = interfce->find_canonic_address(interfce, reg);
+			reg = interfce->findCanonicAddress(reg);
 			normal_map->setVal(reg, true);
 		}
 	}
@@ -181,8 +181,8 @@
 	// Init: Explicitly loaded scripts
 	for (i = 1; i < sm->heap_size; i++)
 		if (interfaces[i]
-		        && interfaces[i]->type_id == MEM_OBJ_SCRIPT) {
-			script_t *script = &(interfaces[i]->mobj->data.script);
+		        && interfaces[i]->getType() == MEM_OBJ_SCRIPT) {
+			script_t *script = &(interfaces[i]->getMobj()->data.script);
 
 			if (script->lockers) { // Explicitly loaded?
 				int obj_nr;
@@ -209,7 +209,7 @@
 			sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));
 #endif
 			if (reg.segment < sm->heap_size && interfaces[reg.segment])
-				interfaces[reg.segment]->list_all_outgoing_references(interfaces[reg.segment], s, reg,
+				interfaces[reg.segment]->listAllOutgoingReferences(s, reg,
 																		&worklist_manager, add_outgoing_refs);
 		}
 	}
@@ -220,7 +220,7 @@
 	// Cleanup
 	for (i = 1; i < sm->heap_size; i++)
 		if (interfaces[i])
-			interfaces[i]->deallocate_self(interfaces[i]);
+			delete interfaces[i];
 
 	free(interfaces);
 	delete nonnormal_map;
@@ -243,7 +243,7 @@
 
 	if (!use_map->contains(addr)) {
 		// Not found -> we can free it
-		deallocator->interfce->free_at_address(deallocator->interfce, addr);
+		deallocator->interfce->freeAtAddress(addr);
 #ifdef DEBUG_GC
 		sciprintf("[GC] Deallocating "PREG"\n", PRINT_REG(addr));
 		deallocator->segcount[deallocator->interfce->type_id]++;
@@ -271,8 +271,8 @@
 #ifdef DEBUG_GC
 			deallocator.segnames[deallocator.interfce->type_id] = deallocator.interfce->type;
 #endif
-			deallocator.interfce->list_all_deallocatable(deallocator.interfce, &deallocator, free_unless_used);
-			deallocator.interfce->deallocate_self(deallocator.interfce);
+			deallocator.interfce->listAllDeallocatable(&deallocator, free_unless_used);
+			delete deallocator.interfce;
 		}
 	}
 

Modified: scummvm/trunk/engines/sci/engine/scriptdebug.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-02-22 10:20:45 UTC (rev 38781)
+++ scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-02-22 12:18:22 UTC (rev 38782)
@@ -2807,9 +2807,9 @@
 	GET_SEG_INTERFACE(addr.segment);
 
 	sciprintf("Reachable from "PREG":\n", PRINT_REG(addr));
-	seg_interface->list_all_outgoing_references(seg_interface, s, addr, NULL, _print_address);
+	seg_interface->listAllOutgoingReferences(s, addr, NULL, _print_address);
 
-	seg_interface->deallocate_self(seg_interface);
+	delete seg_interface;
 
 	return 0;
 }
@@ -2820,9 +2820,9 @@
 	GET_SEG_INTERFACE(addr.segment);
 
 	sciprintf("Freeable in segment %04x:\n", addr.segment);
-	seg_interface->list_all_deallocatable(seg_interface, NULL, _print_address);
+	seg_interface->listAllDeallocatable(NULL, _print_address);
 
-	seg_interface->deallocate_self(seg_interface);
+	delete seg_interface;
 
 	return 0;
 }
@@ -2832,10 +2832,10 @@
 
 	GET_SEG_INTERFACE(addr.segment);
 
-	addr = seg_interface->find_canonic_address(seg_interface, addr);
+	addr = seg_interface->findCanonicAddress(addr);
 	sciprintf(" "PREG"\n", PRINT_REG(addr));
 
-	seg_interface->deallocate_self(seg_interface);
+	delete seg_interface;
 
 	return 0;
 }

Modified: scummvm/trunk/engines/sci/engine/seg_manager.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/seg_manager.cpp	2009-02-22 10:20:45 UTC (rev 38781)
+++ scummvm/trunk/engines/sci/engine/seg_manager.cpp	2009-02-22 12:18:22 UTC (rev 38782)
@@ -1423,44 +1423,58 @@
 #endif
 }
 
-// ------------------- Segment interface ------------------
 
-static void free_at_address_stub(SegInterface *self, reg_t sub_addr) {
-	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr));
-	// STUB
+// ------------------- Segment interface ------------------
+SegInterface::SegInterface(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId, memObjType typeId) :
+	_segmgr(segmgr), _mobj(mobj), _segId(segId), _typeId(typeId) {
+	VERIFY(_mobj->type == _typeId, "Invalid mem_obj_t type");
 }
 
-static reg_t find_canonic_address_base(SegInterface *self, reg_t addr) {
-	addr.offset = 0;
-
+reg_t SegInterface::findCanonicAddress(reg_t addr) {
 	return addr;
 }
 
-static reg_t find_canonic_address_id(SegInterface *self, reg_t addr) {
-	return addr;
+void SegInterface::freeAtAddress(reg_t sub_addr) {
 }
 
-static void free_at_address_nop(SegInterface *self, reg_t sub_addr) {
+void SegInterface::listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)) {
 }
 
-static void list_all_deallocatable_nop(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
+void SegInterface::listAllOutgoingReferences(EngineState *s, reg_t object, void *param, void (*note)(void *param, reg_t addr)) {
 }
 
-static void list_all_deallocatable_base(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
-	(*note)(param, make_reg(self->seg_id, 0));
-}
 
-static void list_all_outgoing_references_nop(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+//-------------------- base --------------------
+class SegInterfaceBase : public SegInterface {
+protected:
+	SegInterfaceBase(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId, memObjType typeId) :
+		SegInterface(segmgr, mobj, segId, typeId) {}
+public:
+	reg_t findCanonicAddress(reg_t addr);
+	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr));
+};
+
+reg_t SegInterfaceBase::findCanonicAddress(reg_t addr) {
+	addr.offset = 0;
+	return addr;
 }
 
-static void deallocate_self(SegInterface *self) {
-	free(self);
+void SegInterfaceBase::listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)) {
+	(*note)(param, make_reg(_segId, 0));
 }
 
-static void free_at_address_script(SegInterface *self, reg_t addr) {
-	script_t *script;
-	VERIFY(self->mobj->type == MEM_OBJ_SCRIPT, "Trying to free a non-script!");
-	script = &(self->mobj->data.script);
+
+//-------------------- script --------------------
+class SegInterfaceScript : public SegInterfaceBase {
+public:
+	SegInterfaceScript(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_SCRIPT) {}
+	void freeAtAddress(reg_t addr);
+	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr));
+};
+
+void SegInterfaceScript::freeAtAddress(reg_t addr) {
+	script_t *script = &(_mobj->data.script);
 	/*
 		sciprintf("[GC] Freeing script "PREG"\n", PRINT_REG(addr));
 		if (script->locals_segment)
@@ -1468,11 +1482,11 @@
 	*/
 
 	if (script->marked_as_deleted)
-		self->segmgr->deallocateScript(script->nr);
+		_segmgr->deallocateScript(script->nr);
 }
 
-static void list_all_outgoing_references_script(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
-	script_t *script = &(self->mobj->data.script);
+void SegInterfaceScript::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr)) {
+	script_t *script = &(_mobj->data.script);
 
 	if (addr.offset <= script->buf_size && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->buf + addr.offset)) {
 		int idx = RAW_GET_CLASS_INDEX(script, addr);
@@ -1495,41 +1509,36 @@
 	}
 }
 
-//-------------------- script --------------------
-static SegInterface seg_interface_script = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_SCRIPT,
-	/* type = */	"script",
-	/* find_canonic_address = */		find_canonic_address_base,
-	/* free_at_address = */			free_at_address_script,
-	/* list_all_deallocatable = */		list_all_deallocatable_base,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_script,
-	/* deallocate_self = */			deallocate_self
-};
 
-
 #define LIST_ALL_DEALLOCATABLE(kind, kind_field) \
-	mem_obj_t *mobj = self->mobj;					\
-	kind##_table_t * table = &(mobj->data.kind_field);		\
+	kind##_table_t * table = &(_mobj->data.kind_field);		\
 	int i;								\
 									\
 	for (i = 0; i < table->max_entry; i++)				\
 		if (ENTRY_IS_VALID(table, i))				\
-			(*note) (param, make_reg(self->seg_id, i));
+			(*note) (param, make_reg(_segId, i));
 
-static void list_all_deallocatable_clones(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
+
+//-------------------- clones --------------------
+class SegInterfaceClones : public SegInterface {
+public:
+	SegInterfaceClones(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_CLONES) {}
+	void freeAtAddress(reg_t addr);
+	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr));
+	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr));
+};
+
+void SegInterfaceClones::listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr)) {
 	LIST_ALL_DEALLOCATABLE(clone, clones);
 }
 
-static void list_all_outgoing_references_clones(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
-	mem_obj_t *mobj = self->mobj;
-	clone_table_t *clone_table = &(mobj->data.clones);
+void SegInterfaceClones::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr)) {
+	clone_table_t *clone_table = &(_mobj->data.clones);
 	clone_t *clone;
 	int i;
 
-	assert(addr.segment == self->seg_id);
+	assert(addr.segment == _segId);
 
 	if (!(ENTRY_IS_VALID(clone_table, addr.offset))) {
 		fprintf(stderr, "Unexpected request for outgoing references from clone at "PREG"\n", PRINT_REG(addr));
@@ -1548,12 +1557,12 @@
 	//sciprintf("[GC] Reporting clone-pos "PREG"\n", PRINT_REG(clone->pos));
 }
 
-void free_at_address_clones(SegInterface *self, reg_t addr) {
+void SegInterfaceClones::freeAtAddress(reg_t addr) {
 	object_t *victim_obj;
 
-	assert(addr.segment == self->seg_id);
+	assert(addr.segment == _segId);
 
-	victim_obj = &(self->mobj->data.clones.table[addr.offset].entry);
+	victim_obj = &(_mobj->data.clones.table[addr.offset].entry);
 
 #ifdef GC_DEBUG
 	if (!(victim_obj->flags & OBJECT_FLAG_FREED))
@@ -1569,100 +1578,97 @@
 	*/
 	free(victim_obj->variables);
 	victim_obj->variables = NULL;
-	self->segmgr->free_clone(addr);
+	_segmgr->free_clone(addr);
 }
 
-//-------------------- clones --------------------
-static SegInterface seg_interface_clones = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_CLONES,
-	/* type = */	"clones",
-	/* find_canonic_address = */		find_canonic_address_id,
-	/* free_at_address = */			free_at_address_clones,
-	/* list_all_deallocatable = */		list_all_deallocatable_clones,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_clones,
-	/* deallocate_self = */			deallocate_self
+
+//-------------------- locals --------------------
+class SegInterfaceLocals : public SegInterface {
+public:
+	SegInterfaceLocals(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_LOCALS) {}
+	reg_t findCanonicAddress(reg_t addr);
+	void freeAtAddress(reg_t addr);
+	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr));
 };
 
-static reg_t find_canonic_address_locals(SegInterface *self, reg_t addr) {
-	local_variables_t *locals = &(self->mobj->data.locals);
+reg_t SegInterfaceLocals::findCanonicAddress(reg_t addr) {
+	local_variables_t *locals = &(_mobj->data.locals);
 	// Reference the owning script
-	seg_id_t owner_seg = self->segmgr->segGet(locals->script_id);
+	seg_id_t owner_seg = _segmgr->segGet(locals->script_id);
 
 	assert(owner_seg >= 0);
 
 	return make_reg(owner_seg, 0);
 }
 
-static void list_all_outgoing_references_locals(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
-	local_variables_t *locals = &(self->mobj->data.locals);
+void SegInterfaceLocals::freeAtAddress(reg_t sub_addr) {
+	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr));
+	// STUB
+}
+
+void SegInterfaceLocals::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+	local_variables_t *locals = &(_mobj->data.locals);
 	int i;
 
-	assert(addr.segment == self->seg_id);
+	assert(addr.segment == _segId);
 
 	for (i = 0; i < locals->nr; i++)
 		(*note)(param, locals->locals[i]);
 }
 
-//-------------------- locals --------------------
-static SegInterface seg_interface_locals = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_LOCALS,
-	/* type = */	"locals",
-	/* find_canonic_address = */		find_canonic_address_locals,
-	/* free_at_address = */			free_at_address_stub,
-	/* list_all_deallocatable = */		list_all_deallocatable_nop,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_locals,
-	/* deallocate_self = */			deallocate_self
+
+//-------------------- stack --------------------
+class SegInterfaceStack : public SegInterface {
+public:
+	SegInterfaceStack(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_STACK) {}
+	reg_t findCanonicAddress(reg_t addr);
+	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr));
 };
 
-static void list_all_outgoing_references_stack(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+reg_t SegInterfaceStack::findCanonicAddress(reg_t addr) {
+	addr.offset = 0;
+	return addr;
+}
+
+void SegInterfaceStack::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
 	int i;
-	fprintf(stderr, "Emitting %d stack entries\n", self->mobj->data.stack.nr);
-	for (i = 0; i < self->mobj->data.stack.nr; i++)
-		(*note)(param, self->mobj->data.stack.entries[i]);
+	fprintf(stderr, "Emitting %d stack entries\n", _mobj->data.stack.nr);
+	for (i = 0; i < _mobj->data.stack.nr; i++)
+		(*note)(param, _mobj->data.stack.entries[i]);
 	fprintf(stderr, "DONE");
 }
 
-//-------------------- stack --------------------
 
-static SegInterface seg_interface_stack = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_STACK,
-	/* type = */	"stack",
-	/* find_canonic_address = */		find_canonic_address_base,
-	/* free_at_address = */			free_at_address_nop,
-	/* list_all_deallocatable = */		list_all_deallocatable_nop,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_stack,
-	/* deallocate_self = */			deallocate_self
+//-------------------- system strings --------------------
+class SegInterfaceSysStrings : public SegInterface {
+public:
+	SegInterfaceSysStrings(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_SYS_STRINGS) {}
 };
 
-//-------------------- system strings --------------------
-static SegInterface seg_interface_sys_strings = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_SYS_STRINGS,
-	/* type = */	"system strings",
-	/* find_canonic_address = */		find_canonic_address_id,
-	/* free_at_address = */			free_at_address_nop,
-	/* list_all_deallocatable = */		list_all_deallocatable_nop,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_nop,
-	/* deallocate_self = */			deallocate_self
+
+//-------------------- lists --------------------
+class SegInterfaceLists : public SegInterface {
+public:
+	SegInterfaceLists(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_LISTS) {}
+	void freeAtAddress(reg_t addr);
+	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr));
+	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr));
 };
 
-static void list_all_deallocatable_list(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
+void SegInterfaceLists::freeAtAddress(reg_t sub_addr) {
+	_segmgr->free_list(sub_addr);
+}
+
+void SegInterfaceLists::listAllDeallocatable(void *param, void (*note)(void*param, reg_t addr)) {
 	LIST_ALL_DEALLOCATABLE(list, lists);
 }
 
-static void list_all_outgoing_references_list(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
-	list_table_t *table = &(self->mobj->data.lists);
+void SegInterfaceLists::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+	list_table_t *table = &(_mobj->data.lists);
 	list_t *list = &(table->table[addr.offset].entry);
 
 	if (!ENTRY_IS_VALID(table, addr.offset)) {
@@ -1676,30 +1682,27 @@
 	// let's be conservative here.
 }
 
-static void free_at_address_lists(SegInterface *self, reg_t sub_addr) {
-	self->segmgr->free_list(sub_addr);
-}
 
-//-------------------- lists --------------------
-static SegInterface seg_interface_lists = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_LISTS,
-	/* type = */	"lists",
-	/* find_canonic_address = */		find_canonic_address_id,
-	/* free_at_address = */			free_at_address_lists,
-	/* list_all_deallocatable = */		list_all_deallocatable_list,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_list,
-	/* deallocate_self = */			deallocate_self
+//-------------------- nodes --------------------
+class SegInterfaceNodes : public SegInterface {
+public:
+	SegInterfaceNodes(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_NODES) {}
+	void freeAtAddress(reg_t addr);
+	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr));
+	void listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void *param, reg_t addr));
 };
 
-static void list_all_deallocatable_nodes(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
+void SegInterfaceNodes::freeAtAddress(reg_t sub_addr) {
+	_segmgr->free_node(sub_addr);
+}
+
+void SegInterfaceNodes::listAllDeallocatable(void *param, void (*note)(void*param, reg_t addr)) {
 	LIST_ALL_DEALLOCATABLE(node, nodes);
 }
 
-static void list_all_outgoing_references_nodes(SegInterface *self, EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
-	node_table_t *table = &(self->mobj->data.nodes);
+void SegInterfaceNodes::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, void (*note)(void*param, reg_t addr)) {
+	node_table_t *table = &(_mobj->data.nodes);
 	node_t *node = &(table->table[addr.offset].entry);
 
 	if (!ENTRY_IS_VALID(table, addr.offset)) {
@@ -1715,102 +1718,89 @@
 	note(param, node->value);
 }
 
-static void free_at_address_nodes(SegInterface *self, reg_t sub_addr) {
-	self->segmgr->free_node(sub_addr);
-}
 
-//-------------------- nodes --------------------
-static SegInterface seg_interface_nodes = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_NODES,
-	/* type = */	"nodes",
-	/* find_canonic_address = */		find_canonic_address_id,
-	/* free_at_address = */			free_at_address_nodes,
-	/* list_all_deallocatable = */		list_all_deallocatable_nodes,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_nodes,
-	/* deallocate_self = */			deallocate_self
+//-------------------- hunk --------------------
+class SegInterfaceHunk : public SegInterface {
+public:
+	SegInterfaceHunk(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_HUNK) {}
+	void freeAtAddress(reg_t addr);
+	void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr));
 };
 
-static void list_all_deallocatable_hunk(SegInterface *self, void *param, void (*note)(void*param, reg_t addr)) {
+void SegInterfaceHunk::freeAtAddress(reg_t sub_addr) {
+	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr));
+	// STUB
+}
+
+void SegInterfaceHunk::listAllDeallocatable(void *param, void (*note)(void*param, reg_t addr)) {
 	LIST_ALL_DEALLOCATABLE(hunk, hunks);
 }
 
-//-------------------- hunk --------------------
-static SegInterface seg_interface_hunk = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_HUNK,
-	/* type = */	"hunk",
-	/* find_canonic_address = */		find_canonic_address_id,
-	/* free_at_address = */			free_at_address_stub,
-	/* list_all_deallocatable = */		list_all_deallocatable_hunk,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_nop,
-	/* deallocate_self = */			deallocate_self
-};
 
 //-------------------- dynamic memory --------------------
-static SegInterface seg_interface_dynmem = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_DYNMEM,
-	/* type = */	"dynamic memory",
-	/* find_canonic_address = */		find_canonic_address_base,
-	/* free_at_address = */			free_at_address_stub,
-	/* list_all_deallocatable = */		list_all_deallocatable_base,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_nop,
-	/* deallocate_self = */			deallocate_self
+class SegInterfaceDynMem : public SegInterfaceBase {
+public:
+	SegInterfaceDynMem(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterfaceBase(segmgr, mobj, segId, MEM_OBJ_DYNMEM) {}
+	void freeAtAddress(reg_t addr);
 };
 
+void SegInterfaceDynMem::freeAtAddress(reg_t sub_addr) {
+	//sciprintf("  Request to free "PREG"\n", PRINT_REG(sub_addr));
+	// STUB
+}
+
+
 //-------------------- reserved --------------------
-static SegInterface seg_interface_reserved = {
-	/* segmgr = */	NULL,
-	/* mobj = */	NULL,
-	/* seg_id = */	0,
-	/* type_id = */	MEM_OBJ_RESERVED,
-	/* type = */	"reserved",
-	/* find_canonic_address = */		find_canonic_address_id,
-	/* free_at_address = */			free_at_address_nop,
-	/* list_all_deallocatable = */		list_all_deallocatable_nop,
-	/* list_all_outgoing_references = */	list_all_outgoing_references_nop,
-	/* deallocate_self = */			deallocate_self
+class SegInterfaceReserved : public SegInterface {
+public:
+	SegInterfaceReserved(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId) :
+		SegInterface(segmgr, mobj, segId, MEM_OBJ_RESERVED) {}
 };
 
-static SegInterface* seg_interfaces[MEM_OBJ_MAX] = {
-	&seg_interface_script,
-	&seg_interface_clones,
-	&seg_interface_locals,
-	&seg_interface_stack,
-	&seg_interface_sys_strings,
-	&seg_interface_lists,
-	&seg_interface_nodes,
-	&seg_interface_hunk,
-	&seg_interface_dynmem,
-	&seg_interface_reserved
-};
 
 SegInterface *SegManager::getSegInterface(seg_id_t segid) {
-	mem_obj_t *mobj;
-	SegInterface *retval;
-
 	if (!check(segid))
 		return NULL; // Invalid segment
 
-	mobj = heap[segid];
-	retval = (SegInterface *)sci_malloc(sizeof(SegInterface));
-	memcpy(retval, seg_interfaces[mobj->type - 1], sizeof(SegInterface));
-
-	if (mobj->type != retval->type_id) {
+	SegInterface *retval = NULL;
+	mem_obj_t *mobj = heap[segid];
+	switch (mobj->type) {
+	case MEM_OBJ_SCRIPT:
+		retval = new SegInterfaceScript(this, mobj, segid);
+		break;
+	case MEM_OBJ_CLONES:
+		retval = new SegInterfaceClones(this, mobj, segid);
+		break;
+	case MEM_OBJ_LOCALS:
+		retval = new SegInterfaceLocals(this, mobj, segid);
+		break;
+	case MEM_OBJ_STACK:
+		retval = new SegInterfaceStack(this, mobj, segid);
+		break;
+	case MEM_OBJ_SYS_STRINGS:
+		retval = new SegInterfaceSysStrings(this, mobj, segid);
+		break;
+	case MEM_OBJ_LISTS:
+		retval = new SegInterfaceLists(this, mobj, segid);
+		break;
+	case MEM_OBJ_NODES:
+		retval = new SegInterfaceNodes(this, mobj, segid);
+		break;
+	case MEM_OBJ_HUNK:
+		retval = new SegInterfaceHunk(this, mobj, segid);
+		break;
+	case MEM_OBJ_DYNMEM:
+		retval = new SegInterfaceDynMem(this, mobj, segid);
+		break;
+	case MEM_OBJ_RESERVED:
+		retval = new SegInterfaceReserved(this, mobj, segid);
+		break;
+	default:
 		error("Improper segment interface for %d", mobj->type);
 	}
 
-	retval->segmgr = this;
-	retval->mobj = mobj;
-	retval->seg_id = segid;
-
 	return retval;
 }
 

Modified: scummvm/trunk/engines/sci/engine/seg_manager.h
===================================================================
--- scummvm/trunk/engines/sci/engine/seg_manager.h	2009-02-22 10:20:45 UTC (rev 38781)
+++ scummvm/trunk/engines/sci/engine/seg_manager.h	2009-02-22 12:18:22 UTC (rev 38782)
@@ -58,7 +58,7 @@
 		(((mgr).heap[index]	&& ((mgr).heap[index]->type == MEM_OBJ_SCRIPT || (mgr).heap[index]->type == MEM_OBJ_CLONES))? (mgr).heap[index]	\
 		: NULL): NULL
 
-struct SegInterface;
+class SegInterface;
 
 class SegManager {
 public:
@@ -340,6 +340,7 @@
 	// Parameters: (reg_t) addr: Offset of the hunk entry to delete
 	void free_hunk_entry(reg_t addr);
 
+
 	// 9. Dynamic Memory
 
 	// Allocate some dynamic memory
@@ -385,7 +386,7 @@
 	// Retrieves the segment interface to the specified segment
 	// Parameters: (seg_id_t) segid: ID of the segment to look up
 	// Returns   : (SegInterface *): An interface to the specified segment ID, or NULL on error
-	// The returned interface 'si' must be freed after use by calling 'si->dealloc_self(si)';
+	// The returned interface must be deleted after use
 	SegInterface *getSegInterface(seg_id_t segid);
 
 
@@ -450,38 +451,50 @@
 
 // 11. Segment interface, primarily for GC			
 
-struct SegInterface {
-	SegManager *segmgr;
-	mem_obj_t *mobj;
-	seg_id_t seg_id;
-	memObjType type_id;	// Segment type 
-	const char *type;	// String description of the segment type 
+class SegInterface {
+protected:
+	SegInterface(SegManager *segmgr, mem_obj_t *mobj, seg_id_t segId, memObjType typeId);
 
-	reg_t (*find_canonic_address)(SegInterface *self, reg_t sub_addr);
+public:
+	// Deallocates the segment interface
+	virtual ~SegInterface() {}
+
 	// Finds the canonic address associated with sub_reg
 	// Parameters: (reg_t) sub_addr: The base address whose canonic address is to be found
 	// For each valid address a, there exists a canonic address c(a) such that c(a) = c(c(a)).
 	// This address "governs" a in the sense that deallocating c(a) will deallocate a.
+	virtual reg_t findCanonicAddress(reg_t sub_addr);
 	
-	void (*free_at_address)(SegInterface *self, reg_t sub_addr);
 	// Deallocates all memory associated with the specified address
 	// Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
-	
-	void (*list_all_deallocatable)(SegInterface *self, void *param, void (*note)(void *param, reg_t addr));
+	virtual void freeAtAddress(reg_t sub_addr);
+
 	// Iterates over and reports all addresses within the current segment
 	// Parameters: note : (voidptr * addr) -> (): Invoked for each address on which free_at_address()
 	//                                makes sense
 	//             (void *) param: Parameter passed to 'note'
+	virtual void listAllDeallocatable(void *param, void (*note)(void *param, reg_t addr));
 	
-	void (*list_all_outgoing_references)(SegInterface *self, EngineState *s, reg_t object, void *param, void (*note)(void *param, reg_t addr));
 	// Iterates over all references reachable from the specified object
 	// Parameters: (reg_t) object: The object (within the current segment) to analyse
 	//             (void *) param: Parameter passed to 'note'
 	//             note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
 	// Note: This function may also choose to report numbers (segment 0) as adresses
-	
-	void (*deallocate_self)(SegInterface *self);
-	// Deallocates the segment interface
+	virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, void (*note)(void *param, reg_t addr));
+
+	// Get the memory object
+	mem_obj_t *getMobj() { return _mobj; }
+
+	// Get the segment type
+	memObjType getType() { return _typeId; }
+
+protected:
+	SegManager *_segmgr;
+	mem_obj_t *_mobj;
+	seg_id_t _segId;
+
+private:
+	memObjType _typeId; // Segment type
 };
 
 } // End of namespace Sci


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list