Advertisement

CScriptArray::Destruct

Started by May 15, 2013 06:15 PM
4 comments, last by Jason Goepel 11 years, 6 months ago

In the copy code for CScriptArray, I notice that handles are released when they are replaced.

[source]void CScriptArray::CopyBuffer(SArrayBuffer *dst, SArrayBuffer *src)

{

asIScriptEngine *engine = objType->GetEngine();

if( subTypeId & asTYPEID_OBJHANDLE )

{

// Copy the references and increase the reference counters

if( dst->numElements > 0 && src->numElements > 0 )

{

int count = dst->numElements > src->numElements ? src->numElements : dst->numElements;

void **max = (void**)(dst->data + count * sizeof(void*));

void **d = (void**)dst->data;

void **s = (void**)src->data;

for( ; d < max; d++, s++ )

{

void *tmp = *d;

*d = *s;

if( *d )

engine->AddRefScriptObject(*d, objType->GetSubType());

// Release the old ref after incrementing the new to avoid problem incase it is the same ref

if( tmp )

engine->ReleaseScriptObject(tmp, objType->GetSubType());

}

}

}

else

{

if( dst->numElements > 0 && src->numElements > 0 )

{

int count = dst->numElements > src->numElements ? src->numElements : dst->numElements;

if( subTypeId & asTYPEID_MASK_OBJECT )

{

// Call the assignment operator on all of the objects

void **max = (void**)(dst->data + count * sizeof(void*));

void **d = (void**)dst->data;

void **s = (void**)src->data;

for( ; d < max; d++, s++ )

engine->AssignScriptObject(*d, *s, subTypeId);

}

else

{

// Primitives are copied byte for byte

memcpy(dst->data, src->data, count*elementSize);

}

}

}

}
[/source]

In the Destruct function, however, only types with a bit set in the Object mask are released, which does not appear to include handles.

[source]void CScriptArray::Destruct(SArrayBuffer *buf, asUINT start, asUINT end)

{

if( subTypeId & asTYPEID_MASK_OBJECT )

{

asIScriptEngine *engine = objType->GetEngine();

void **max = (void**)(buf->data + end * sizeof(void*));

void **d = (void**)(buf->data + start * sizeof(void*));

for( ; d < max; d++ )

{

if( *d )

engine->ReleaseScriptObject(*d, objType->GetSubType());

}

}

}[/source]

Is there a reason for this, or is it an oversight?

This looks like it makes sense if the asTYPEID_OBJHANDLE bit is only set if one of the bits in asTYPEID_MASK_OBJECT is also set. Is this the case? Is there documentation I can read (either online or in the source) to confirm this?

Thanks, I'm new to AngelScript, but I am excited about it.

Advertisement

It's a binary mask. You can check its value in angelscript.h.

If a type is asTYPEID_OBJHANDLE then it's a asTYPEID_MASK_OBJECT.

asTYPEID_MASK_OBJECT = asTYPEID_OBJHANDLE | asTYPEID_SCRIPTOBJECT | asTYPEID_APPOBJECT

That's not what I see:

enum asETypeIdFlags
{
	asTYPEID_VOID           = 0,
	asTYPEID_BOOL           = 1,
	asTYPEID_INT8           = 2,
	asTYPEID_INT16          = 3,
	asTYPEID_INT32          = 4,
	asTYPEID_INT64          = 5,
	asTYPEID_UINT8          = 6,
	asTYPEID_UINT16         = 7,
	asTYPEID_UINT32         = 8,
	asTYPEID_UINT64         = 9,
	asTYPEID_FLOAT          = 10,
	asTYPEID_DOUBLE         = 11,
	asTYPEID_OBJHANDLE      = 0x40000000,
	asTYPEID_HANDLETOCONST  = 0x20000000,
	asTYPEID_MASK_OBJECT    = 0x1C000000,
	asTYPEID_APPOBJECT      = 0x04000000,
	asTYPEID_SCRIPTOBJECT   = 0x08000000,
	asTYPEID_TEMPLATE       = 0x10000000,
	asTYPEID_MASK_SEQNBR    = 0x03FFFFFF
};

It looks more like


asTYPEID_MASK_OBJECT = asTYPEID_TEMPLATE | asTYPEID_SCRIPTOBJECT | asTYPEID_APPOBJECT

edit:

Ok i am sorry, i just did the math for real this time. You are right. I should have rushed to answer without checking my facts :)

A script object handle has mask of asTYPEID_MASK_OBJECT | asTYPEID_OBJHANDLE

An c++ object handle has mask of asTYPEID_APPOBJECT | asTYPEID_OBJHANDLE

I don't think there is anything wrong with if( subTypeId & asTYPEID_MASK_OBJECT ).

It doesn't care about handles because all handles are asTYPEID_APPOBJECT or asTYPEID_MASK_OBJECT or asTYPEID_TEMPLATE .

There aren't any handle types that doesn't fit those 3. No such thing as pure asTYPEID_OBJHANDLE

Very good. That makes sense, because most of the tests I see are (x & asTYPEID_MASK_OBJECT) && !(x & asTYPEID_OBJHANDLE)

This topic is closed to new replies.

Advertisement