Advertisement

Global variables are not released properly

Started by August 26, 2007 07:20 PM
5 comments, last by SergSerg 17 years, 1 month ago
I have global variable it is a wrapper for a window class, i declared it as global, because window is not modal, and it should stay on the screen until user close it, and when user closes window script calls ShutDown function wich releases contexts and current engine but destructor for that global variable is never called
How is the type of the global variable registered? And how is the global variable declared?

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

Advertisement
A variable is simply declared at the beggining of file as
HTMLWindow wndFrame;
....
....
....
void main()
{...
....
}
About type Ok, here now will be several fragments from different files
I made some macros and declared them in ohter file here it is:

//scriptMacro.h


#define DECLARE_SCRIPT_CLASS(class_name)protected: int nRefCount;public: void Begin(); void AddRef(); void Release(); static void Construct(class_name *thisPointer); static void *Alloc(int); static void Free(void*p);

#define IMPLEMENT_SCRIPT_CLASS(class_name)void class_name::AddRef(){ nRefCount++;}void class_name::Construct(class_name *thisPointer){ new(thisPointer) class_name##();}void *class_name::Alloc(int){ return new char[sizeof(class_name)];}void class_name::Free(void*p){ ASSERT( p ); delete[] (char*)p;}void class_name::Release(){ this->nRefCount--; if(!this->nRefCount) { delete this; };}void class_name::Begin(){ nRefCount = 1;}
#define REGISTER_STD_SCRIPT_CLASS(register_as,class_name) int xxxx = 0; xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_CONSTRUCT,"void f()",asFUNCTION(class_name::Construct), asCALL_CDECL_OBJLAST); ASSERT( xxxx >= 0 ); xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_ALLOC, #register_as" &f(uint)", asFUNCTION(class_name::Alloc), asCALL_CDECL); ASSERT( xxxx >= 0 ); xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_FREE, "void f("#register_as" ∈)", asFUNCTION(class_name::Free), asCALL_CDECL); ASSERT( xxxx >= 0 ); xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_ADDREF,"void f()",asMETHOD(class_name,AddRef), asCALL_THISCALL); ASSERT( xxxx >= 0 );xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_RELEASE,"void f()",asMETHOD(class_name,Release), asCALL_THISCALL); ASSERT( xxxx >= 0 );

#define SCRIPT_CLASS_MACRO_END

//end of scriptMacro.h


//a part of scripting.h:

class asCHTMLWindow {
DECLARE_SCRIPT_CLASS(asCHTMLWindow)
protected:
CWnd *m_pWnd;
CString m_strOnCloseCB;
public:
static void OnClose(CWnd*);
asCHTMLWindow();
void Show();
bool SetHTML(asCScriptString &strHTML);
bool IsWindowVisible();
bool SetTitle(asCScriptString &str);
void SetOnCloseEvent(asCScriptString&);
bool JSCall(asCScriptString& strFuncName, asCAssocArray& arrParams);
virtual ~asCHTMLWindow();
};

//end of scripting.h

//a part of scripting.cpp:

IMPLEMENT_SCRIPT_CLASS(asCHTMLWindow)

asCHTMLWindow::asCHTMLWindow()
{
m_pWnd = NULL;
}

void asCHTMLWindow::Show()
{
if (m_pWnd)
{
m_pWnd->BringWindowToTop();
return;
}
CMarketPlaceMDIApp* pApp = (CMarketPlaceMDIApp*) AfxGetApp();
CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, pApp->m_pMainWnd);
WebFrame *pChildFrame = new WebFrame();
m_pWnd = pChildFrame;
pChildFrame->nilThis = &m_pWnd;
asIScriptContext *context = asGetActiveContext();
pChildFrame->m_pScripting = CScripting::ObjectByEngine(context->GetEngine());
pFrame->CreateNewChildGF(pChildFrame,IDR_MarketPlaceMDITYPE, pApp->m_hMDIMenu, pApp->m_hMDIAccel);
pChildFrame->OnCloseEvent = OnClose;
pChildFrame->m_pObjPtr = (void*)this;
}

bool asCHTMLWindow::IsWindowVisible()
{
if (!m_pWnd)
return false;
if (!::IsWindow(m_pWnd->m_hWnd))
return false;
return m_pWnd->IsWindowVisible();
}

bool asCHTMLWindow::SetHTML(asCScriptString &strHTML)
{
if (!m_pWnd)
return false;
WebFrame *pChildFrame = (WebFrame*)m_pWnd;
pChildFrame->LoadFromString(strHTML.buffer);
return true;
}

void asCHTMLWindow::OnClose(CWnd* pWnd)
{
WebFrame *pFrame = (WebFrame*)pWnd;
asCHTMLWindow *pAsWnd = (asCHTMLWindow*)pFrame->m_pObjPtr;
if (pAsWnd->m_strOnCloseCB.GetLength())
{
CScripting *pScripting = pFrame->m_pScripting;
if (pScripting)
{
CString strTo = pAsWnd->m_strOnCloseCB;
strTo.Insert(0,"void ");
strTo.Append("()");
int nID = pScripting->m_pEngine->GetFunctionIDByDecl(0,strTo);
if (nID<0)
return;
asIScriptContext *pEvent = pScripting->m_pEngine->CreateContext();
int r = pEvent->Prepare(nID);
r = pEvent->Execute();
pEvent->Release();
}
}
//delete pWnd;
}

bool asCHTMLWindow::SetTitle(asCScriptString &str)
{
if (!m_pWnd)
return false;
/* CString strMainTitle;
strMainTitle.Format("%s - [%s]",AfxGetApp()->m_pszAppName,str.buffer);
AfxGetApp()->GetMainWnd()->SetWindowText(strMainTitle);
m_pWnd->SetWindowText(str.buffer);
*/
((WebFrame*)m_pWnd)->SetTitle(str.buffer);
((WebFrame*)m_pWnd)->OnUpdateFrameTitle(1);
//m_pWnd->SendMessage(WM_SIZE);
((CMainFrame*)AfxGetApp()->GetMainWnd())->OnUpdateFrameTitle(1);
return true;
}

void asCHTMLWindow::SetOnCloseEvent(asCScriptString &ref)
{
m_strOnCloseCB = ref.buffer;
}

bool asCHTMLWindow::JSCall(asCScriptString& strFuncName, asCAssocArray& arrParams)
{
if (!m_pWnd)
return false;
CStringArray strArr;
int i;
for (i=0;i<arrParams.m_arrVals.GetCount();i++)
strArr.Add(arrParams.m_arrVals->buffer);
return ((WebFrame*)m_pWnd)->CallJScript(strFuncName.buffer,strArr);
}

asCHTMLWindow::~asCHTMLWindow()
{
if (m_pWnd) m_pWnd->DestroyWindow();
}

//registration is as folows:


void CScripting::RegisterHTMLWindowObj(asIScriptEngine *pEngine)
{
int r = pEngine->RegisterObjectType("HTMLWindow",sizeof(asCHTMLWindow),asOBJ_CLASS_CDA);
ASSERT(r>=0);
REGISTER_STD_SCRIPT_CLASS(HTMLWindow, asCHTMLWindow)
r = pEngine->RegisterObjectMethod("HTMLWindow","bool SetHTML(string&)",asMETHOD(asCHTMLWindow,SetHTML),asCALL_THISCALL);
ASSERT(r>=0);
r = pEngine->RegisterObjectMethod("HTMLWindow","void SetOnCloseEvent(string&)",asMETHOD(asCHTMLWindow,SetOnCloseEvent),asCALL_THISCALL);
ASSERT(r>=0);
r = pEngine->RegisterObjectMethod("HTMLWindow","void Show()",asMETHOD(asCHTMLWindow,Show),asCALL_THISCALL); ASSERT(r>=0);
r = pEngine->RegisterObjectMethod("HTMLWindow","bool IsWindowVisible()",asMETHOD(asCHTMLWindow,IsWindowVisible),asCALL_THISCALL);
ASSERT(r>=0);
r = pEngine->RegisterObjectMethod("HTMLWindow","bool SetTitle(string&)",asMETHOD(asCHTMLWindow,SetTitle),asCALL_THISCALL);
ASSERT(r>=0);
r = pEngine->RegisterObjectMethod("HTMLWindow","bool JSCall(string&, AssocArray&)",asMETHOD(asCHTMLWindow,JSCall),asCALL_THISCALL);
ASSERT(r>=0);
}
post.asp removed slashes from macros, so i repost with a little bit different way ^-)))

#define DECLARE_SCRIPT_CLASS(class_name)//
protected://
int nRefCount;//
public://
void Begin();//
void AddRef();//
void Release();//
static void Construct(class_name *thisPointer);//
static void *Alloc(int);//
static void Free(void*p);//


#define IMPLEMENT_SCRIPT_CLASS(class_name)//
void class_name::AddRef()//
{//
nRefCount++;//
}//
void class_name::Construct(class_name *thisPointer)//
{//
new(thisPointer) class_name##();//
}//
//
void *class_name::Alloc(int)//
{//
return new char[sizeof(class_name)];//
}//
//
void class_name::Free(void*p)//
{//
ASSERT( p );//
delete[] (char*)p;//
}//
//
void class_name::Release()//
{//
this->nRefCount--;//
if(!this->nRefCount)//
{//
delete this;//
};//
}//
void class_name::Begin()//
{//
nRefCount = 1;//
}//

#define REGISTER_STD_SCRIPT_CLASS(register_as,class_name)//
int xxxx = 0;//
xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_CONSTRUCT,"void f()",asFUNCTION(class_name::Construct), asCALL_CDECL_OBJLAST);//
ASSERT( xxxx >= 0 );//
xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_ALLOC, #register_as" &f(uint)", asFUNCTION(class_name::Alloc), asCALL_CDECL);//
ASSERT( xxxx >= 0 );//
xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_FREE, "void f("#register_as" ∈)", asFUNCTION(class_name::Free), asCALL_CDECL);//
ASSERT( xxxx >= 0 );//
xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_ADDREF,"void f()",asMETHOD(class_name,AddRef), asCALL_THISCALL);//
ASSERT( xxxx >= 0 );//
xxxx = pEngine->RegisterObjectBehaviour(#register_as, asBEHAVE_RELEASE,"void f()",asMETHOD(class_name,Release), asCALL_THISCALL);//
ASSERT( xxxx >= 0 );//


#define SCRIPT_CLASS_MACRO_END
I found my propb with this class, i just forgot to call Begin() at constructor
so nRefCount was undefined.

But i still have alot of leaks, is me registration of the class is wrong ?

tnx.
The only problem with the registration that I could find is that it is missing the assignment behaviour. If you don't register this and an assignment is made in the script, then AngelScript will perform a direct copy of the memory, which also overwrites the refCounter.

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

Advertisement
Clear.
Big tnx.

This topic is closed to new replies.

Advertisement