🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Global variables are not released properly

Started by
5 comments, last by SergSerg 16 years, 10 months 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
Advertisement
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

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

Clear.
Big tnx.

This topic is closed to new replies.

Advertisement