Pass an asIScriptObject to a script?

Started by
4 comments, last by justin12343 10 years, 11 months ago

I'm trying to pass a handle of a game object to a script function, but its not working properly.


CScriptAny *Object::GetScriptObject()
{
	CScriptAny *n = new CScriptAny( scriptManager->GetEngine());
	int typeId = scriptManager->GetEngine()->GetTypeIdByDecl("Base_Object_IMP@");
	n->Store( pScrObj, typeId);

	return n;
}

Base_Object_IMP is the interface that the parent class of all scripted game objects, Base_Object inherit. Each instance store a asIScriptObject returned from the constructor. The function above fails with an access violation and it doesn't seem to be able to find the type id for 'Base_Object'.

I'm trying to cast from the base type to a another child type, like so:


Base_Object @base = null;
Object @obj = find_instance( objPlayer, Player);

if (obj != null)
	obj.GetScriptObject().retrieve( @base);

objPlayer_controller @PlayerHandle = cast<objPlayer_controller>( @base);
 

This is what I'm trying to do:

asIScriptObject -> Base_Object_IMP@ -> Base_Object@ -> objPlayer_controller@ (or any other child type).

Is there a proper way to do this?

Advertisement

I found that I could do the following:


asIScriptObject *Object::GetScriptObject()
{
	/*CScriptAny *n = new CScriptAny( scriptManager->GetEngine());
	int typeId = scriptManager->GetEngine()->GetTypeIdByDecl( "Base_Object_IMP@");
	n->Store( pScrObj, typeId);

	return n;*/

	pScrObj->AddRef();//<----- Crashes without calling AddRef
	return pScrObj;
}

and then cast like so:


int id = create_instance( x+(LogWidth*i), y, objBridgeNode);
objBridgeNode_controller @node;
Object @obj = get_instance( id);

if (obj != null)
	@node = cast<objBridgeNode_controller>( @obj.GetScriptObject());

Now the problem is the frame rate slowly drops. What could be causing this to happen?

In your original post the problem was that you told Store() that you was passing in a pointer to a handle, but in reality you were passing in a pointer to the object directly. The correct way to do it would be:

CScriptAny *Object::GetScriptObject()
{
    CScriptAny *n = new CScriptAny( scriptManager->GetEngine());
    int typeId = scriptManager->GetEngine()->GetTypeIdByDecl("Base_Object_IMP@");
    n->Store( &pScrObj, typeId );  // pass in a pointer to the pointer to the object as the typeId is a handle

    return n;
}

Still, your second post is much better. smile.png

With only the little information that you have shared so far it is impossible to know why your framerate decreases overtime. It can be any number of factors.

Profiling your application is a good way to find out what is going on. Especially if you can do separate profiles at different time periods, then you would be able to figure out why in the later period it is slower than in the early period.

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

I solved that frame rate problem. My debug output window was filling up with "accessing null pointer" errors. Now I'm checking for null pointers before I try to access:


for (int i = 0; i < NumLogs; ++i)
{
	int id = create_instance( x+(LogWidth*i), y, objBridgeNode);
	objBridgeNode_controller @node;
	Object @obj = get_instance( id);

	if (obj != null)
		@node = cast<objBridgeNode_controller>( @obj.GetScriptObject());
	else
		continue;
	
	if (node == null)
		continue;

	node.ParentBridge = GetId();
	node.Id = i;
	
	Nodes = id;
}

Apparently, I'm getting null pointers every time as if the cast operator does not know what type the returned asIScriptObject really is.

Even this doesn't work:

Base_Object_IMP @base = null;

base = cast<Base_Object_IMP>( @obj.GetScriptObject());

The result is still null. I know asIScriptObject being passed is valid before hand, so what can this problem be?

Edit:

Here's my other Base_Object class if it helps:


class Base_Object : Base_Object_IMP
{
//========== Constructor / Destructor ===========
	Base_Object( Object @obj)
	{
		@this.object = obj;
		x = object.x;
		y = object.y;
		sprite_index = -1;
		mask_index = -1;
		image_index = object.image_index;
		depth = object.depth;
	}

//=========== Events =============
	void Create(){}
	void Destroy(){}
	void Alarm1(){}
	void Alarm2(){}
	void Alarm3(){}
	void Alarm4(){}
	void Alarm5(){}
	void Alarm6(){}
	void Alarm7(){}
	void Alarm8(){}
	void Alarm9(){}
	void Alarm10(){}
	void Alarm11(){}
	
	void BeginStep(){}
	void Step(){}
	void EndStep(){}
	
	void Collision( int objType, int objId, Object @other){}
	
	void Key( int key){}
	void KeyPressed( int key){}
	void KeyReleased( int key){}
	
	void MouseButton( int button){}
	void MouseButtonPressed( int button){}
	void MouseButtonReleased( int button){}
	
	void JoystickButton( int id, int button){}
	void JoystickButtonPressed( int id, int button){}
	void JoystickButtonReleased( int id, int button){}
	
	void OutsideRoom(){}
	void OutsideView(){}
	void IntersectBoundary(){}
	
	void GameStart(){}
	void GameEnd(){}
	
	void RoomStart(){}
	void RoomEnd(){}
	
	void NoMoreLives(){}
	void NoMoreHealth(){}
	
	void AnimationEnd(){}
	void EndOfPath(){}
	void Draw(){}

//======= Collision =========
	bool place_meeting( float mX, float mY, int type)
	{
		return object.PlaceMeeting( mX, mY, type);
	}
	
	bool place_meeting_depth( float mX, float mY, int depth, int type)
	{
		return object.PlaceMeetingDepth( mX, mY, type, depth);
	}
	
	Base_Object @object_place( float mX, float mY, int type)
	{
		Base_Object @base = null;
		Object @obj = object.ObjectPlace( mX, mY, type);
		
		if (obj == null)
			return null;
		else
			//obj.GetScriptObject().retrieve( @base);
			@base = cast<Base_Object>(@obj.GetScriptObject());
			
		return base;
	}


//========== Misc ===========
	uint GetId()
	{
		return object.GetId();
	}

	void SetRect( int l, int t, int w, int h)
	{
		object.general_rect.left = l;
		object.general_rect.top = t;
		object.general_rect.right = l+w;
		object.general_rect.bottom = t+h;
	}
	
//======= Variables =========
	Object @object;
	float x;
	float y;
	int sprite_index;
	int mask_index;
	int image_index;
	int depth;
}

classes are declared like:

objBridge_controller : Base_Object

{

....

}

Are you using multiple modules? I mean GetScriptObject() returning an instance of a class type declared in a different script module than the one that calls GetScriptObject()? If so, that is likely the cause.

To share object types across modules you need to declare them as shared.

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

That just might solve it. I currently using #include in each script to define Base_Object. Using shared makes a lot more sense.

EDIT:

That fixed it. Thanks!

This topic is closed to new replies.

Advertisement