• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
iraxef

crash when caching engine->GetTypeIdByDecl()

8 posts in this topic

I'm using 2.28.1 WIP on debug, 32-bit windows 7.

 

I have a wrapper function around engine->GetTypeIdByDecl() along these lines:

i32 GetEngineTypeIdFromDecl(string s)
{
  if ( s is in container )
    // return cached int from container
  else
  {
    // call engine->GetTypeIdByDecl(s)
    // add int to container
    // return int
  }
}

I've run into a crash in engine->GetObjectTypeById():

asIObjectType *asCScriptEngine::GetObjectTypeById(int typeId) const
{
	asCDataType dt = GetDataTypeFromTypeId(typeId);

	// Is the type id valid?
	if( !dt.IsValid() ) return 0;

	// Enum types are not objects, so we shouldn't return an object type for them
	if( dt.GetObjectType() && dt.GetObjectType()->GetFlags() & asOBJ_ENUM )
		return 0;

	return dt.GetObjectType();
}

dt, as it comes back from GetDataTypeFromTypeId(typeId) is a garbage instance.. it passes the valid check but crashes in the dt.GetObjectType()-> call.. I noticed in the debugger that many of dt's variables are 0xfeeefeee which VS's debug allocator uses to indicate that you're pointing to deleted heap memory.

Here is what I'm doing:

void MyExecuteScriptFunction(functionName, paramsForFunction)
{
    // this potentially returns a cached typeid
    i32 myArrayTypeId = GetEngineTypeIdFromDecl("array<MyType@>@");

    // the second time I run through this code, the below call crashes:
    asIObjectType* type engine->GetObjectTypeById(myArrayTypeId);

    CScriptArray* arr = new CScriptArray(0, type);

    // fill array with some stuff, pass it to a script function, execute function

    arr->Release();
}

I can get around the crash either by leaking the CScriptArray, which means its dtor doesn't run and it doesn't call Release() on the object type, or I can avoid caching the results of engine->GetTypeIdByDecl() and call it every time.

CScriptArray::~CScriptArray()
{
    ...
    if( objType ) objType->Release();
}

Since the AngelScript documentation suggests caching the results of engine->GetTypeIdByDecl(), am I doing anything wrong above? Is there any way for me to know that my cached type id has been invalidated?

 

Thank you very much.

Edited by iraxef
0

Share this post


Link to post
Share on other sites

The object type for array<MyType@> has probably been removed, e.g if the script that declared the MyType is recompiled, so the typeId you cached is no longer valid.

 

Of course, the GetObjectTypeById shouldn't crash when giving invalid type id's, instead it should return a null pointer. I'll need to look into why it crashes.

0

Share this post


Link to post
Share on other sites

I didn't even think to mention it, but yes, I was recompiling the script!

 

So what you're saying is that my one script was the only one referencing the array<MyType@> type and when the script went away, the type was released...

 

By the way, when I'm looking up either "MyType&" or "array<MyType@>@" should I be specifying a reference or handle on the type? Would it be more correct to look up "MyType" and "array<MyType@>"? What I'm doing is trying to match a script-function's parameter with one of the types that I know. So if the script function is: void foo(array<MyType@>@) would I want to look up "array<MyType@>@" or "array<MyType@>" ?

 

Thank you very much!

0

Share this post


Link to post
Share on other sites

Exactly, if there were no live objects of either the MyType type or the array<MyType@> type, then when you discarded the script (or recompiled it) the object types are released as they won't be used any longer.

 

If you do not want the object type to be release, you can hold on to the asIObjectType by increasing the reference count. It will then keep the type and related script code in memory until you release the object.

 

Observe however, when you recompile the script, the old types will be incompatible with the new ones (unless declared as shared), even though they are compiled from the same source code. Both the asIObjectType and the typeId will be different.

 

The type id for array<MyType@>@ and array<MyType@> are different, but the only difference is the bit asTYPEID_OBJHANDLE, so you can easily derive one from the other.

 

However, in your case, it is not really the type id that you want. You want the asIObjectType so you can create the CScriptArray. You can get this with GetObjectTypeByName("array<MyType@>") so you don't even need to retrieve the type id first. It's still a good idea to cache the returned asIObjectType though.

0

Share this post


Link to post
Share on other sites

I've fixed the crash in GetObjectTypeById in revision 1850. Now it will properly return a null pointer to inform the caller that the object type doesn't exist anymore.

0

Share this post


Link to post
Share on other sites

Thank you for the fix!

 

If I'm doing something like:

int paramTypeId = scriptFunc->GetParamTypeId(0);

And I want to enforce that 'paramTypeId' is of type array handle (I don't care, at this point, what it's an array of.. I'll validate the subtype later. I just want to know that it's an array handle), what syntax would I use? GetObjectTypeByName("array<>@") ? GetObjectTypeByName("array<?>@")

 

UPDATE: Apparently asIObjectType* arrayType = scriptEngine->GetObjectTypeByName("array"); works just fine. Is there any way to tell whether the script-function is taking this array by handle, instead of by value?

Edited by iraxef
0

Share this post


Link to post
Share on other sites

You can it like this:

 

bool isHandle = (paramTypeId & asTYPEID_OBJHANDLE) ? true : false;
 
asIObjectType *type = engine->GetObjectTypeById(paramTypeId);
bool isArray = (type && strcmp(type->GetName(), "array") == 0) ? true : false;

 

Regards,

Andreas

0

Share this post


Link to post
Share on other sites

GetObjectTypeByName("array<MyType@>") doesn't seem to work. I've got the following tests:

scriptEngine->GetObjectTypeByName("array");                                         // non-NULL address 1
scriptEngine->GetObjectTypeByName("array<MyType@>");                                // NULL
scriptEngine->GetObjectTypeByName("array<MyType@>@");                               // NULL

scriptEngine->GetObjectTypeById(scriptEngine->GetTypeIdByDecl("array"));            // NULL
scriptEngine->GetObjectTypeById(scriptEngine->GetTypeIdByDecl("array<MyType@>"));   // non-NULL address 2
scriptEngine->GetObjectTypeById(scriptEngine->GetTypeIdByDecl("array<MyType@>@"));  // non-NULL address 2

So if you want to check whether a type is "array", regardless of subtype, it seems that you need to use GetObjectTypeByName(). If you want to check what the actual array-plus-subtype is, it seems that you need to use the declaration instead of the name, like GetObjectTypeById(GetTypeIdByDecl()).

 

Am I doing something wrong?

Edited by iraxef
0

Share this post


Link to post
Share on other sites

Yes, that's true. Sorry for misleading you earlier.

 

GetObjectTypeByName() only accepts a single name for the lookup, it doesn't accept a type declaration, so it cannot be used to get the template instance type, e.g. array<int> array<MyType@>, etc.

 

I'll probably add a GetObjectTypeByDecl() for release 2.29.0 to better support this scenario.

0

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  
Followers 0