🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Problems registering an array.

Started by
6 comments, last by WitchLord 18 years, 11 months ago
Using the latest WIP I get an null object reference when attempting to use Deyja's Register Vector class. this is where the error is: asCString::operator const char *() const { if( buffer == 0 ) return ""; return buffer; } It is called in function: GetArrayTypeFromSubType() here. if( sub.GetTokenType() == ttIdentifier ) { // TODO: Improve linear search for( int n = 0; n < arrayTypes.GetLength(); n++ ) { if( arrayTypes[n]->tokenType == ttIdentifier && arrayTypes[n]->name == sub.GetObjectType()->name && ---->>>> This the error line arrayTypes[n]->arrayType == arrayType ) return arrayTypes[n]; } }
Advertisement
Would you mind telling me the calls that you do to register the vector? I ask because I have already tested Deyja's Register Vector class (it's part of my regression testing) and it showed no problems.

It may be a special combination of registered types that cause this bug.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Ok, I'll get back with you on it a little later. I'm inspecting what builds it started in.
It's when i try to register an array of an array of strings.


string[][]


Using the std::string binding that was on the boards here or that comes with AS.


All other primitive data types register just fine. i can do int[], int[][], int[][][]. I did not have a chance to test objects besides string[][]

The problem was introduced sometime between 2.2.1WIP2 and 2.3.0WIP5. I was unable to get and test versions between those releases.
.

[Edited by - Rain Dog on July 10, 2005 11:20:38 PM]
OK. I think it is enough for me to find the bug.

What compiler are you using? In MSVC6 there seems to be a bug in std::vector that prohibits registration of vectors of vectors, i.e. int[][]. This may be the reason why I didn't spot this bug.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Alright, I believe I've been able to correct the problem. You'll have to exchange the implementation for asCScriptEngine::RegisterObjectType() and asCScriptEngine::GetArrayTypeFromSubType().

int asCScriptEngine::RegisterObjectType(const char *name, int byteSize, asDWORD flags){	// Verify flags	if( flags > 17 )		return ConfigError(asINVALID_ARG);	// Verify type name	if( name == 0 )		return ConfigError(asINVALID_NAME);	// Verify object size (valid sizes 0, 1, 2, or multiple of 4)	if( byteSize < 0 )		return ConfigError(asINVALID_ARG);		if( byteSize < 4 && byteSize == 3 )		return ConfigError(asINVALID_ARG);	if( byteSize > 4 && (byteSize & 0x3) )		return ConfigError(asINVALID_ARG);	// Verify if the name has been registered as a type already	int n;	for( n = 0; n < objectTypes.GetLength(); n++ )	{		if( objectTypes[n]->name == name )			return asALREADY_REGISTERED;	}	for( n = 0; n < arrayTypes.GetLength(); n++ )	{		if( arrayTypes[n]->name == name )			return asALREADY_REGISTERED;	}			// Use builder to parse the datatype	asCDataType dt;	asCBuilder bld(this, 0);	int r = bld.ParseDataType(name, &dt);	// If the builder fails, then the type name 	// is new and it should be registered 	if( r < 0 )	{		// Make sure the name is not a reserved keyword		asCTokenizer t;		int tokenLen;		int token = t.GetToken(name, strlen(name), &tokenLen);		if( token != ttIdentifier || strlen(name) != (unsigned)tokenLen )			return ConfigError(asINVALID_NAME);		int r = bld.CheckNameConflict(name, 0, 0);		if( r < 0 ) 			return ConfigError(asNAME_TAKEN);		// Don't have to check against members of object  		// types as they are allowed to use the names		// Put the data type in the list		asCObjectType *type = new asCObjectType(this);		type->name = name;		type->tokenType = ttIdentifier;		type->arrayType = 0;		type->size = byteSize;		type->flags = flags;		objectTypes.PushLast(type);	}	else	{		// int[][] must not be allowed to be registered		// if int[] hasn't been registered first		if( dt.GetSubType().IsScriptArray() )			return ConfigError(asLOWER_ARRAY_DIMENSION_NOT_REGISTERED);		if( dt.IsReadOnly() ||			dt.IsReference() )			return ConfigError(asINVALID_TYPE);		// Put the data type in the list		asCObjectType *type = new asCObjectType(this);		type->name = name;		type->subType = dt.GetSubType().GetObjectType();		type->tokenType = dt.GetSubType().GetTokenType();		type->arrayType = dt.GetArrayType();		type->size = byteSize;		type->flags = flags;		arrayTypes.PushLast(type);		// Swap the overloaded type with the script type in arrayTypes		SwapArrayTypes(type, dt.GetObjectType());	}	return asSUCCESS;}asCObjectType *asCScriptEngine::GetArrayTypeFromSubType(asCDataType &type){	int arrayType = type.GetArrayType();	if( type.IsObjectHandle() )		arrayType = (arrayType<<2) | 3;	else		arrayType = (arrayType<<2) | 2;	// Is there any array type already with this subtype?	if( type.IsObject() )	{		// TODO: Improve linear search		for( int n = 0; n < arrayTypes.GetLength(); n++ )		{			if( arrayTypes[n]->tokenType == ttIdentifier &&				arrayTypes[n]->subType == type.GetObjectType() &&				arrayTypes[n]->arrayType == arrayType )				return arrayTypes[n];		}	}	else	{		// TODO: Improve linear search		for( int n = 0; n < arrayTypes.GetLength(); n++ )		{			if( arrayTypes[n]->tokenType == type.GetTokenType() &&				arrayTypes[n]->arrayType == arrayType )				return arrayTypes[n];		}	}	// No previous array type has been registered	// Create a new array type based on the defaultArrayObjectType	asCObjectType *ot = new asCObjectType(this);	ot->arrayType = arrayType;	ot->flags = asOBJ_CLASS_CDA | asOBJ_SCRIPT_ARRAY;	ot->size = sizeof(asCArrayObject);	ot->name = ""; // Built-in script arrays are registered without name	ot->tokenType = type.GetTokenType();	ot->methods = defaultArrayObjectType->methods;	ot->beh.construct = defaultArrayObjectType->beh.construct;	ot->beh.constructors = defaultArrayObjectType->beh.constructors;	ot->beh.addref = defaultArrayObjectType->beh.addref;	ot->beh.release = defaultArrayObjectType->beh.release;	ot->beh.copy = defaultArrayObjectType->beh.copy;	ot->beh.operators = defaultArrayObjectType->beh.operators;	// The object type needs to store the sub type as well	ot->subType = type.GetObjectType();	// TODO: The indexing behaviour and assignment  	// behaviour should use the correct datatype	// Verify if the subtype contains an any object, in which case this array is a potential circular reference	if( ot->subType && (ot->subType->flags & asOBJ_CONTAINS_ANY) )		ot->flags |= asOBJ_POTENTIAL_CIRCLE | asOBJ_CONTAINS_ANY;	arrayTypes.PushLast(ot);	// We need to store the object type somewhere for clean-up later	scriptArrayTypes.PushLast(ot);	ot->refCount++;	return ot;}


I had messed up the registration of multi-dimensional arrays with the latest changes, and I didn't have any test cases for this scenario. Now I do, thanks to you. :)

Let me know if there is any more problems with the latest version.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Fixed.

Works now.
Thanks for the confirmation.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement