Sign in to follow this  
Jason Goepel

CScriptArray::Destruct

Recommended Posts

Jason Goepel    797

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?

Share this post


Link to post
Share on other sites
Jason Goepel    797

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.

Share this post


Link to post
Share on other sites
saejox    714

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

Share this post


Link to post
Share on other sites
Jason Goepel    797
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

 

 

Share this post


Link to post
Share on other sites
saejox    714

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

Edited by saejox

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this