🎉 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.
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];
}
}
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
It may be a special combination of registered types that cause this bug.
Regards,
Andreas
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]
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
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
Alright, I believe I've been able to correct the problem. You'll have to exchange the implementation for asCScriptEngine::RegisterObjectType() and asCScriptEngine::GetArrayTypeFromSubType().
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
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
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement