[Scummvm-cvs-logs] CVS: scummvm/scumm object.cpp,1.128,1.129 resource.cpp,1.100,1.101 resource.h,1.4,1.5 scummvm.cpp,2.255,2.256

Max Horn fingolfin at users.sourceforge.net
Wed Jun 25 17:48:18 CEST 2003


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv18830

Modified Files:
	object.cpp resource.cpp resource.h scummvm.cpp 
Log Message:
added ResourceIterator, replacing two of the old findResource/findResourceSmall function - contraty to those, this approach is thread safe

Index: object.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/object.cpp,v
retrieving revision 1.128
retrieving revision 1.129
diff -u -d -r1.128 -r1.129
--- object.cpp	25 Jun 2003 23:25:51 -0000	1.128
+++ object.cpp	26 Jun 2003 00:47:38 -0000	1.129
@@ -533,10 +533,11 @@
 	assert(searchptr);
 
 	// Load in new room objects
+	ResourceIterator	obcds(searchptr, false);
 	for (i = 0; i < _numObjectsInRoom; i++) {
 		od = &_objs[findLocalObjectSlot()];
 
-		ptr = findResource(MKID('OBCD'), searchptr);
+		ptr = obcds.findNext(MKID('OBCD'));
 		if (ptr == NULL)
 			error("Room %d missing object code block(s)", _roomResource);
 
@@ -553,16 +554,16 @@
 		if (_dumpScripts) {
 			char buf[32];
 			sprintf(buf, "roomobj-%d-", _roomResource);
-			ptr = findResource(MKID('VERB'), ptr, 0);
+			ptr = findResource(MKID('VERB'), ptr);
 			dumpResource(buf, od->obj_nr, ptr);
 		}
 
-		searchptr = NULL;
 	}
 
 	searchptr = room;
+	ResourceIterator	obims(room, false);
 	for (i = 0; i < _numObjectsInRoom; i++) {
-		ptr = findResource(MKID('OBIM'), searchptr);
+		ptr = obims.findNext(MKID('OBIM'));
 		if (ptr == NULL)
 			error("Room %d missing image blocks(s)", _roomResource);
 
@@ -580,7 +581,6 @@
 			if (_objs[j].obj_nr == obim_id)
 				_objs[j].OBIMoffset = ptr - room;
 		}
-		searchptr = NULL;
 	}
 
 	for (i = 1; i < _numLocalObjects; i++) {
@@ -636,7 +636,7 @@
 	ObjectData *od;
 	const byte *ptr;
 	uint16 obim_id;
-	const byte *room, *searchptr;
+	const byte *room;
 	const RoomHeader *roomhdr;
 
 	CHECK_HEAP
@@ -651,11 +651,11 @@
 	if (_numObjectsInRoom > _numLocalObjects)
 		error("More than %d objects in room %d", _numLocalObjects, _roomResource);
 
-	searchptr = room;
+	ResourceIterator	obcds(room, true);
 	for (i = 0; i < _numObjectsInRoom; i++) {
 		od = &_objs[findLocalObjectSlot()];
 
-		ptr = findResourceSmall(MKID('OBCD'), searchptr);
+		ptr = obcds.findNext(MKID('OBCD'));
 		if (ptr == NULL)
 			error("Room %d missing object code block(s)", _roomResource);
 
@@ -666,13 +666,11 @@
 			sprintf(buf, "roomobj-%d-", _roomResource);
 			dumpResource(buf, od->obj_nr, ptr);
 		}
-
-		searchptr = NULL;
 	}
 
-	searchptr = room;
+	ResourceIterator	obims(room, true);
 	for (i = 0; i < _numObjectsInRoom; i++) {
-		ptr = findResourceSmall(MKID('OBIM'), searchptr);
+		ptr = obims.findNext(MKID('OBIM'));
 		if (ptr == NULL)
 			error("Room %d missing image blocks(s)", _roomResource);
 
@@ -682,7 +680,6 @@
 			if (_objs[j].obj_nr == obim_id)
 				_objs[j].OBIMoffset = ptr - room;
 		}
-		searchptr = NULL;
 	}
 
 	for (i = 1; i < _numLocalObjects; i++) {
@@ -1090,11 +1087,9 @@
 		else
 			searchptr = roomptr;
 		assert(searchptr);
+		ResourceIterator	obcds(searchptr, _features & GF_SMALL_HEADER);
 		for (i = 0;;) {
-			if (_features & GF_SMALL_HEADER)
-				obcdptr = findResourceSmall(MKID('OBCD'), searchptr);
-			else
-				obcdptr = findResource(MKID('OBCD'), searchptr);
+			obcdptr = obcds.findNext(MKID('OBCD'));
 			if (obcdptr == NULL)
 				error("findObjectInRoom: Not enough code blocks in room %d", room);
 			cdhd = (const CodeHeader *)findResourceData(MKID('CDHD'), obcdptr);
@@ -1115,19 +1110,14 @@
 			}
 			if (++i == numobj)
 				error("findObjectInRoom: Object %d not found in room %d", id, room);
-			searchptr = NULL;
 		}
 	}
 
 	roomptr = fo->roomptr;
 	if (findWhat & foImageHeader) {
-		searchptr = roomptr;
-		assert(searchptr);
+		ResourceIterator	obims(roomptr, _features & GF_SMALL_HEADER);
 		for (i = 0;;) {
-			if (_features & GF_SMALL_HEADER)
-				obimptr = findResourceSmall(MKID('OBIM'), searchptr);
-			else
-				obimptr = findResource(MKID('OBIM'), searchptr);
+			obimptr = obims.findNext(MKID('OBIM'));
 			if (obimptr == NULL)
 				error("findObjectInRoom: Not enough image blocks in room %d", room);
 			imhd = (const ImageHeader *)findResourceData(MKID('IMHD'), obimptr);
@@ -1149,7 +1139,6 @@
 			}
 			if (++i == numobj)
 				error("findObjectInRoom: Object %d image not found in room %d", id, room);
-			searchptr = NULL;
 		}
 	}
 }
@@ -1640,7 +1629,7 @@
 		char buf[32];
 		const byte *ptr = foir.obcd;
 		sprintf(buf, "roomobj-%d-", room);
-		ptr = findResource(MKID('VERB'), ptr, 0);
+		ptr = findResource(MKID('VERB'), ptr);
 		dumpResource(buf, object, ptr);
 	}
 

Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.cpp,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -d -r1.100 -r1.101
--- resource.cpp	25 Jun 2003 23:49:54 -0000	1.100
+++ resource.cpp	26 Jun 2003 00:47:39 -0000	1.101
@@ -1349,9 +1349,9 @@
 	if (_features & GF_OLD_BUNDLE)
 		error("findResourceData must not be used in GF_OLD_BUNDLE games");
 	else if (_features & GF_SMALL_HEADER)
-		ptr = findResourceSmall(tag, ptr, 0);
+		ptr = findResourceSmall(tag, ptr);
 	else
-		ptr = findResource(tag, ptr, 0);
+		ptr = findResource(tag, ptr);
 
 	if (ptr == NULL)
 		return NULL;
@@ -1370,72 +1370,58 @@
 		return READ_BE_UINT32(ptr - 4) - 8;
 }
 
-struct FindResourceState {
-	uint32 size, pos;
-	const byte *ptr;
-};
-
-/* just O(N) complexity when iterating with this function */
-const byte *findResource(uint32 tag, const byte *searchin) {
-	uint32 size;
-	static FindResourceState frs;
-	FindResourceState *f = &frs;	/* easier to make it thread safe like this */
-
-	if (searchin) {
-		f->size = READ_BE_UINT32(searchin + 4);
-		f->pos = 8;
-		f->ptr = searchin + 8;
-		goto StartScan;
+ResourceIterator::ResourceIterator(const byte *searchin, bool smallHeader)
+	: _ptr(searchin), _smallHeader(smallHeader) {
+	assert(searchin);
+	if (_smallHeader) {
+		_size = READ_LE_UINT32(searchin);
+		_pos = 6;
+		_ptr = searchin + 6;
+	} else {
+		_size = READ_BE_UINT32(searchin + 4);
+		_pos = 8;
+		_ptr = searchin + 8;
 	}
-
-	do {
-		size = READ_BE_UINT32(f->ptr + 4);
-		if ((int32)size <= 0)
-			return NULL;
-
-		f->pos += size;
-		f->ptr += size;
-
-	StartScan:
-		if (f->pos >= f->size)
-			return NULL;
-	} while (READ_UINT32(f->ptr) != tag);
-
-	return f->ptr;
+	
 }
 
-const byte *findResourceSmall(uint32 tag, const byte *searchin) {
-	uint32 size;
-	static FindResourceState frs;
-	FindResourceState *f = &frs;	/* easier to make it thread safe like this */
-	uint16 smallTag;
-
-	smallTag = newTag2Old(tag);
-
-	if (searchin) {
-		f->size = READ_LE_UINT32(searchin);
-		f->pos = 6;
-		f->ptr = searchin + 6;
-		goto StartScan;
+const byte *ResourceIterator::findNext(uint32 tag) {
+	uint32 size = 0;
+	const byte *result = 0;
+	
+	if (_smallHeader) {
+		uint16 smallTag = newTag2Old(tag);
+		do {
+			if (_pos >= _size)
+				return 0;
+	
+			result = _ptr;
+			size = READ_LE_UINT32(result);
+			if ((int32)size <= 0)
+				return 0;	// Avoid endless loop
+			
+			_pos += size;
+			_ptr += size;
+		} while (READ_LE_UINT16(result + 4) != smallTag);
+	} else {
+		do {
+			if (_pos >= _size)
+				return 0;
+	
+			result = _ptr;
+			size = READ_BE_UINT32(result + 4);
+			if ((int32)size <= 0)
+				return 0;	// Avoid endless loop
+			
+			_pos += size;
+			_ptr += size;
+		} while (READ_UINT32(result) != tag);
 	}
 
-	do {
-		size = READ_LE_UINT32(f->ptr);
-		if ((int32)size <= 0)
-			return NULL;
-
-		f->pos += size;
-		f->ptr += size;
-
-	StartScan:
-		if (f->pos >= f->size)
-			return NULL;
-	} while (READ_LE_UINT16(f->ptr + 4) != smallTag);
-
-	return f->ptr;
+	return result;
 }
 
-const byte *findResource(uint32 tag, const byte *searchin, int idx) {
+const byte *findResource(uint32 tag, const byte *searchin) {
 	uint32 curpos, totalsize, size;
 
 	assert(searchin);
@@ -1446,7 +1432,7 @@
 	searchin += 4;
 
 	while (curpos < totalsize) {
-		if (READ_UINT32(searchin) == tag && !idx--)
+		if (READ_UINT32(searchin) == tag)
 			return searchin;
 
 		size = READ_BE_UINT32(searchin + 4);
@@ -1463,7 +1449,7 @@
 	return NULL;
 }
 
-const byte *findResourceSmall(uint32 tag, const byte *searchin, int idx) {
+const byte *findResourceSmall(uint32 tag, const byte *searchin) {
 	uint32 curpos, totalsize, size;
 	uint16 smallTag;
 
@@ -1478,7 +1464,7 @@
 	while (curpos < totalsize) {
 		size = READ_LE_UINT32(searchin);
 
-		if (READ_LE_UINT16(searchin + 4) == smallTag && !idx--)
+		if (READ_LE_UINT16(searchin + 4) == smallTag)
 			return searchin;
 
 		if ((int32)size <= 0) {

Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/resource.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- resource.h	14 Jun 2003 18:52:29 -0000	1.4
+++ resource.h	26 Jun 2003 00:47:39 -0000	1.5
@@ -50,9 +50,18 @@
 };
 
 
-const byte *findResource(uint32 tag, const byte *searchin, int index);
-const byte *findResourceSmall(uint32 tag, const byte *searchin, int index);
 const byte *findResource(uint32 tag, const byte *searchin);
 const byte *findResourceSmall(uint32 tag, const byte *searchin);
+
+class ResourceIterator {
+	uint32 _size;
+	uint32 _pos;
+	const byte *_ptr;
+	bool _smallHeader;
+public:
+	ResourceIterator(const byte *searchin, bool smallHeader);
+	const byte *findNext(uint32 tag);
+};
+
 
 #endif

Index: scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
retrieving revision 2.255
retrieving revision 2.256
diff -u -d -r2.255 -r2.256
--- scummvm.cpp	25 Jun 2003 23:49:54 -0000	2.255
+++ scummvm.cpp	26 Jun 2003 00:47:39 -0000	2.256
@@ -1662,7 +1662,8 @@
 			}
 		}
 	} else if (_features & GF_SMALL_HEADER) {
-		while ((ptr = findResourceSmall(MKID('LSCR'), searchptr)) != NULL) {
+		ResourceIterator localScriptIterator(searchptr, true);
+		while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) {
 			int id = 0;
 			ptr += _resourceHeaderSize;	/* skip tag & size */
 			id = ptr[0];
@@ -1674,10 +1675,10 @@
 			}
 
 			_localScriptList[id - _numGlobalScripts] = ptr + 1 - roomptr;
-			searchptr = NULL;
 		}
 	} else {
-		while ((ptr = findResource(MKID('LSCR'), searchptr)) != NULL) {
+		ResourceIterator localScriptIterator(searchptr, false);
+		while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) {
 			int id = 0;
 
 			ptr += _resourceHeaderSize;	/* skip tag & size */
@@ -1700,8 +1701,6 @@
 				sprintf(buf, "room-%d-", _roomResource);
 				dumpResource(buf, id, ptr - _resourceHeaderSize);
 			}
-
-			searchptr = NULL;
 		}
 	}
 





More information about the Scummvm-git-logs mailing list