Sign in to follow this  
_orm_

Using the CScriptHandle between C++ and Angelscript

Recommended Posts

Are the there any examples of this? I wanted to use it as a vehicle for user data for my messaging system, but the problem is that after it's gone between Angelscript to the C++ side, casting it back to toe required type in Angelscript results in a null pointer.

Here is a basic overview of the system.


[code]


#pragma once
#ifndef IR_MESSAGE_DISPATCHER_H
#define IR_MESSAGE_DISPATCHER_H

#include <set>

#include "Object.h"
#include "../script/angel/scripthandle.h"


#undef DispatchMessage

namespace Irre {


struct Telegram
{
Telegram( double delay,
asIScriptObject* sender,
asIScriptObject* receiver,
int message,
CScriptHandle& data )
: Sender( sender ),
Receiver( receiver ),
Message( message ),
DispatchTime( delay ),
Data( data )
{
Sender->AddRef();
Receiver->AddRef();
}

~Telegram()
{
Sender->Release();
Receiver->Release();
}

asIScriptObject* Sender;
asIScriptObject* Receiver;
int Message;
double DispatchTime;
CScriptHandle Data;

bool operator<=( const Telegram& other ) { return DispatchTime <= other.DispatchTime; }
bool operator==( const Telegram& other ) { return DispatchTime == other.DispatchTime; }
};

class MessageDispatcher
{
public:
void TransmitMessage( double delay,
Object* sender,
Object* receiver,
int msg,
CScriptHandle& data );

void DispatchDelayedMessages();

private:
void Discharge(Object* receiver,const Telegram& message);

std::set<Telegram> m_DelayedTelegrams;
};

}
#endif



#include "MessageDispatcher.h"
#include "../shared/Global.h"
#include "../script/angel/ScriptFunctions.h"
#include "Stage.h"
#include "ObjectManager.h"
#include "Engine.h"

namespace Irre {

void MessageDispatcher::TransmitMessage( double delay,
Object* sender,
Object* receiver,
int msg,
CScriptHandle& data)
{
float current_time = IR_GetTick();
Telegram message(0,sender->m_Core,receiver->m_Core,msg,data );

if( delay == 0 ) Discharge( receiver, message );
}

void MessageDispatcher::Discharge( Object* receiver,const Telegram& message )
{
receiver->ReceiveMessage( message );
}

void MessageDispatcher::DispatchDelayedMessages()
{
// Not implemented yet.
}

}
[/code]

[code]
void RegisterDispatchMessage( asIScripeEngine* e )
{
// Registering the global function.

r=e->RegisterGlobalFunction("void IR_DispatchMessage(double,int,int,int,ref&in)", asFUNCTION(IR_DispatchMessage), asCALL_CDECL); AS_CHECK(r);
}


/* Dummy */
void TelegramDummy( Telegram* self ) { }
void TelegramDestructor( Telegram* self )
{
((Telegram*)self)->~Telegram();
}


void RegisterTelegram( asIScriptEngine* e )
{

r=e->RegisterObjectType("Telegram",sizeof(Telegram),asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CD );AS_CHECK(r);

r=e->RegisterObjectBehaviour("Telegram",asBEHAVE_CONSTRUCT,"void f()",asFUNCTION(TelegramDummy),asCALL_CDECL_OBJLAST);AS_CHECK(r);
r=e->RegisterObjectBehaviour("Telegram",asBEHAVE_DESTRUCT,"void f()",asFUNCTION(TelegramDestructor),asCALL_CDECL_OBJLAST);AS_CHECK(r);
r=e->RegisterObjectProperty("Telegram","IObject@ Sender",offsetof(Telegram,Sender));
r=e->RegisterObjectProperty("Telegram","IObject@ Receiver",offsetof(Telegram,Receiver));
r=e->RegisterObjectProperty("Telegram","int Message",offsetof(Telegram,Message));
r=e->RegisterObjectProperty("Telegram","double DispatchTime",offsetof(Telegram,DispatchTime));
r=e->RegisterObjectProperty("Telegram","ref@ Data",offsetof(Telegram,Data));
}

[/code]


[code]

void OnMessageReceived( const Telegram&in message )
{
switch( message.Message )
{
case TA_Messages::BODY_WITHIN_RADAR_RANGE:
{
TA_Body@ sensed_body = cast<TA_Body@>(message.Data); // The data is null when it gets passed to IsFriendly.
if( sensed_body is null ) Println("The sensed body was null for whatever reason.");

if( !IsFriendly(sensed_body) && !IsDead )
{
m_SensoryMemory.SaveMemoryEntry( TA_MemoryRecord(sensed_body.TA_Mind,sensed_body.Position) );
}
} break;
case TA_Messages::AGENT_ORDER_DROP_EVERYTHING:
case TA_Messages::AGENT_ORDER_PATROL:
case TA_Messages::AGENT_ORDER_WEAPONS_FREE:
case TA_Messages::AGENT_ORDER_DEFEND:
case TA_Messages::AGENT_ORDER_SEEK_AND_DESTROY:
{
DispatchMessage( 0,m_ThinkGoal,message.Message,message.Data );
} break;
}
[/code]

By the way, I know for a fact that the data that gets passed to the telegram in the first place is guaranteed to not be null. And yes, I am well aware of interfaces and such, but I find messaging to be much more convenient than using interfaces for everything. I have also tried using a pointer to the CScriptHandle, but that eventually leads to either a segfault or an assertion.

Share this post


Link to post
Share on other sites
You've registered your Telegram type as a POD object, but it is not. asOBJ_POD tells AngelScript that it is allowed to make bitwise copies of the object, which will cause havok if the object has handles as members (it won't update the ref count properly).

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