You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
235 lines
7.0 KiB
235 lines
7.0 KiB
//=============================================================================
|
|
//
|
|
// File : kvi_kvs_objectclass.cpp
|
|
// Created on Sat 23 Apr 2005 20:31:32 by Szymon Stefanek
|
|
//
|
|
// This file is part of the KVIrc IRC client distribution
|
|
// Copyright (C) 2005 Szymon Stefanek <pragma at kvirc dot net>
|
|
//
|
|
// This program is FREE software. You can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your opinion) any later version.
|
|
//
|
|
// This program is distributed in the HOPE that it will be USEFUL,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, write to the Free Software Foundation,
|
|
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
//
|
|
//=============================================================================
|
|
|
|
#define __KVIRC__
|
|
|
|
#include "kvi_kvs_object_class.h"
|
|
#include "kvi_kvs_object_controller.h"
|
|
#include "kvi_kvs_object.h"
|
|
#include "kvi_kvs_kernel.h"
|
|
#include "kvi_kvs_object_functionhandlerimpl.h"
|
|
#include "kvi_kvs_object_functioncall.h"
|
|
#include "kvi_kvs_runtimecontext.h"
|
|
#include "kvi_kvs_variantlist.h"
|
|
#include "kvi_kvs_script.h"
|
|
#include "kvi_fileutils.h"
|
|
#include "kvi_window.h"
|
|
#include "kvi_cmdformatter.h"
|
|
|
|
KviKvsObjectClass::KviKvsObjectClass(
|
|
KviKvsObjectClass * pParent,
|
|
const TQString &szName,
|
|
KviKvsObjectAllocateInstanceProc pProc,
|
|
bool bBuiltin)
|
|
{
|
|
m_pParentClass = pParent;
|
|
if(m_pParentClass)
|
|
m_pParentClass->registerChildClass(this);
|
|
m_szName = szName;
|
|
m_bBuiltin = bBuiltin;
|
|
m_bDirty = !bBuiltin;
|
|
m_pFunctionHandlers = new KviPointerHashTable<TQString,KviKvsObjectFunctionHandler>(17,false);
|
|
m_pFunctionHandlers->setAutoDelete(true);
|
|
m_pChildClasses = new KviPointerList<KviKvsObjectClass>;
|
|
m_pChildClasses->setAutoDelete(false);
|
|
m_allocProc = pProc ? pProc : pParent->m_allocProc;
|
|
|
|
// inherit everything from the class above
|
|
if(pParent)
|
|
{
|
|
KviPointerHashTableIterator<TQString,KviKvsObjectFunctionHandler> it(*(pParent->functionHandlers()));
|
|
while(KviKvsObjectFunctionHandler * fh = it.current())
|
|
{
|
|
m_pFunctionHandlers->insert(it.currentKey(),fh->clone());
|
|
++it;
|
|
}
|
|
}
|
|
|
|
// "object" class is automatically registered in the controller constructor
|
|
KviKvsKernel::instance()->objectController()->registerClass(this);
|
|
}
|
|
|
|
KviKvsObjectClass::~KviKvsObjectClass()
|
|
{
|
|
// order here is critical
|
|
|
|
// first of all kill our child classes
|
|
while(m_pChildClasses->first())delete m_pChildClasses->first();
|
|
// then kill all objects that belong to our class
|
|
KviKvsKernel::instance()->objectController()->killAllObjectsWithClass(this);
|
|
// now we're quite clean: should have no object depending on us alive
|
|
// unregister from the parent, if any
|
|
if(m_pParentClass)m_pParentClass->unregisterChildClass(this);
|
|
// unregister from the object controller
|
|
KviKvsKernel::instance()->objectController()->unregisterClass(this);
|
|
// and start effectively dying
|
|
delete m_pFunctionHandlers;
|
|
// this is empty now
|
|
delete m_pChildClasses;
|
|
}
|
|
|
|
void KviKvsObjectClass::registerFunctionHandler(const TQString & szFunctionName,KviKvsObjectFunctionHandlerProc pProc,unsigned int uFlags)
|
|
{
|
|
m_pFunctionHandlers->replace(szFunctionName,new KviKvsObjectCoreCallFunctionHandler(pProc,uFlags));
|
|
}
|
|
|
|
void KviKvsObjectClass::registerFunctionHandler(const TQString & szFunctionName,const TQString &szBuffer,unsigned int uFlags)
|
|
{
|
|
TQString szContext = m_szName;
|
|
szContext += "::";
|
|
szContext += szFunctionName;
|
|
m_pFunctionHandlers->replace(szFunctionName,new KviKvsObjectScriptFunctionHandler(szContext,szBuffer,uFlags));
|
|
}
|
|
|
|
void KviKvsObjectClass::registerStandardNothingReturnFunctionHandler(const TQString &szFunctionName)
|
|
{
|
|
m_pFunctionHandlers->replace(szFunctionName,new KviKvsObjectStandardNothingReturnFunctionHandler());
|
|
}
|
|
|
|
void KviKvsObjectClass::registerStandardTrueReturnFunctionHandler(const TQString &szFunctionName)
|
|
{
|
|
m_pFunctionHandlers->replace(szFunctionName,new KviKvsObjectStandardTrueReturnFunctionHandler());
|
|
}
|
|
|
|
void KviKvsObjectClass::registerStandardFalseReturnFunctionHandler(const TQString &szFunctionName)
|
|
{
|
|
m_pFunctionHandlers->replace(szFunctionName,new KviKvsObjectStandardFalseReturnFunctionHandler());
|
|
}
|
|
|
|
|
|
KviKvsObject * KviKvsObjectClass::allocateInstance(KviKvsObject * pParent,const TQString &szName,KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams)
|
|
{
|
|
if(!m_allocProc)return 0;
|
|
KviKvsObject * pObject = m_allocProc(this,pParent,szName);
|
|
if(!pObject)return 0;
|
|
|
|
KviKvsVariant * v=pParams->first(); // FIXME: what the hell is this ?
|
|
if(!pObject->init(pContext,pParams))
|
|
{
|
|
// internal init failure : abort
|
|
delete pObject;
|
|
return 0;
|
|
}
|
|
|
|
KviKvsVariant ret;
|
|
KviKvsVariantList copy;
|
|
copy.setAutoDelete(false);
|
|
while(v)
|
|
{
|
|
copy.append(v);
|
|
v = pParams->next();
|
|
}
|
|
|
|
if(!pObject->callFunction(pObject,"constructor",TQString(),pContext,&ret,©))
|
|
{
|
|
// ops...constructor failed (script error!)
|
|
delete pObject;
|
|
return 0;
|
|
} else {
|
|
if(ret.isInteger())
|
|
{
|
|
if(ret.integer() == 0)
|
|
{
|
|
// implementation failure...
|
|
delete pObject;
|
|
return 0;
|
|
}
|
|
} else if(ret.isHObject())
|
|
{
|
|
if(ret.hobject() == (kvs_hobject_t)0)
|
|
{
|
|
// implementation failure...
|
|
delete pObject;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pObject;
|
|
}
|
|
|
|
void KviKvsObjectClass::registerChildClass(KviKvsObjectClass *pClass)
|
|
{
|
|
m_pChildClasses->append(pClass);
|
|
}
|
|
|
|
void KviKvsObjectClass::unregisterChildClass(KviKvsObjectClass *pClass)
|
|
{
|
|
m_pChildClasses->removeRef(pClass);
|
|
}
|
|
|
|
bool KviKvsObjectClass::save(const TQString &szFileName)
|
|
{
|
|
if(!m_pParentClass)return false;
|
|
if(isBuiltin())return false;
|
|
|
|
|
|
TQString szBuffer;
|
|
TQString szParentName = m_pParentClass->name();
|
|
|
|
KviTQString::sprintf(szBuffer,
|
|
"# Automatically generated KVS class dump\n\n" \
|
|
"class(\"%Q\",\"%Q\")\n" \
|
|
"{\n",
|
|
&m_szName,&szParentName);
|
|
|
|
KviPointerHashTableIterator<TQString,KviKvsObjectFunctionHandler> it(*m_pFunctionHandlers);
|
|
|
|
while(KviKvsObjectFunctionHandler * h = it.current())
|
|
{
|
|
if(h->isScriptHandler())
|
|
{
|
|
szBuffer += " ";
|
|
if(h->flags() & KviKvsObjectFunctionHandler::Internal)
|
|
szBuffer += "internal ";
|
|
szBuffer += "function ";
|
|
szBuffer += it.currentKey();
|
|
szBuffer += "()\n";
|
|
TQString szCode = h->scriptHandlerCode();
|
|
KviCommandFormatter::blockFromBuffer(szCode);
|
|
KviCommandFormatter::indent(szCode);
|
|
szBuffer += szCode;
|
|
szBuffer += "\n";
|
|
}
|
|
++it;
|
|
}
|
|
|
|
szBuffer += "}\n";
|
|
|
|
return KviFileUtils::writeFile(szFileName,szBuffer);
|
|
}
|
|
void KviKvsObjectClass::getFunctionCode(TQString &szCode,KviKvsObjectFunctionHandler &h)
|
|
{
|
|
szCode=h.scriptHandlerCode();
|
|
}
|
|
|
|
|
|
|
|
bool KviKvsObjectClass::load(const TQString &szFileName)
|
|
{
|
|
TQString szBuffer;
|
|
if(!KviFileUtils::readFile(szFileName,szBuffer,0xffffff))return false;
|
|
return KviKvsScript::run(szBuffer,g_pActiveWindow);
|
|
}
|