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.
294 lines
7.9 KiB
294 lines
7.9 KiB
15 years ago
|
/***************************************************************************
|
||
|
* scriptcontainer.cpp
|
||
|
* This file is part of the KDE project
|
||
|
* copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License as published by the Free Software Foundation; either
|
||
|
* version 2 of the License, or (at your option) 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
|
||
|
* Library General Public License for more details.
|
||
|
* You should have received a copy of the GNU Library General Public License
|
||
|
* along with this program; see the file COPYING. If not, write to
|
||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
***************************************************************************/
|
||
|
|
||
|
#include "scriptcontainer.h"
|
||
|
#include "../api/object.h"
|
||
|
#include "../api/list.h"
|
||
|
#include "../api/interpreter.h"
|
||
|
#include "../api/script.h"
|
||
|
#include "../main/manager.h"
|
||
|
#include "mainmodule.h"
|
||
|
|
||
|
#include <qfile.h>
|
||
|
|
||
|
#include <klocale.h>
|
||
|
|
||
|
using namespace Kross::Api;
|
||
|
|
||
|
namespace Kross { namespace Api {
|
||
|
|
||
|
/// @internal
|
||
|
class ScriptContainerPrivate
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* The \a Script instance the \a ScriptContainer uses
|
||
|
* if initialized. It will be NULL as long as we
|
||
|
* didn't initialized it what will be done on
|
||
|
* demand.
|
||
|
*/
|
||
|
Script* script;
|
||
|
|
||
|
/**
|
||
|
* The unique name the \a ScriptContainer is
|
||
|
* reachable as.
|
||
|
*/
|
||
|
QString name;
|
||
|
|
||
|
/**
|
||
|
* The scripting code.
|
||
|
*/
|
||
|
QString code;
|
||
|
|
||
|
/**
|
||
|
* The name of the interpreter. This could be
|
||
|
* something like "python" for the python
|
||
|
* binding.
|
||
|
*/
|
||
|
QString interpretername;
|
||
|
|
||
|
/**
|
||
|
* The name of the scriptfile that should be
|
||
|
* executed. Those scriptfile will be readed
|
||
|
* and the content will be used to set the
|
||
|
* scripting code and, if not defined, the
|
||
|
* used interpreter.
|
||
|
*/
|
||
|
QString scriptfile;
|
||
|
|
||
|
/**
|
||
|
* Map of options that overwritte the \a InterpreterInfo::Option::Map
|
||
|
* standard options.
|
||
|
*/
|
||
|
QMap<QString, QVariant> options;
|
||
|
|
||
|
};
|
||
|
|
||
|
}}
|
||
|
|
||
|
ScriptContainer::ScriptContainer(const QString& name)
|
||
|
: MainModule(name)
|
||
|
, d( new ScriptContainerPrivate() ) // initialize d-pointer class
|
||
|
{
|
||
|
//krossdebug( QString("ScriptContainer::ScriptContainer() Ctor name='%1'").arg(name) );
|
||
|
|
||
|
d->script = 0;
|
||
|
d->name = name;
|
||
|
}
|
||
|
|
||
|
ScriptContainer::~ScriptContainer()
|
||
|
{
|
||
|
//krossdebug( QString("ScriptContainer::~ScriptContainer() Dtor name='%1'").arg(d->name) );
|
||
|
|
||
|
finalize();
|
||
|
delete d;
|
||
|
}
|
||
|
|
||
|
const QString ScriptContainer::getName() const
|
||
|
{
|
||
|
return d->name;
|
||
|
}
|
||
|
|
||
|
void ScriptContainer::setName(const QString& name)
|
||
|
{
|
||
|
d->name = name;
|
||
|
}
|
||
|
|
||
|
QString ScriptContainer::getCode() const
|
||
|
{
|
||
|
return d->code;
|
||
|
}
|
||
|
|
||
|
void ScriptContainer::setCode(const QString& code)
|
||
|
{
|
||
|
finalize();
|
||
|
d->code = code;
|
||
|
}
|
||
|
|
||
|
QString ScriptContainer::getInterpreterName() const
|
||
|
{
|
||
|
return d->interpretername;
|
||
|
}
|
||
|
|
||
|
void ScriptContainer::setInterpreterName(const QString& interpretername)
|
||
|
{
|
||
|
finalize();
|
||
|
d->interpretername = interpretername;
|
||
|
}
|
||
|
|
||
|
QString ScriptContainer::getFile() const
|
||
|
{
|
||
|
return d->scriptfile;
|
||
|
}
|
||
|
|
||
|
void ScriptContainer::setFile(const QString& scriptfile)
|
||
|
{
|
||
|
finalize();
|
||
|
d->scriptfile = scriptfile;
|
||
|
}
|
||
|
|
||
|
QMap<QString, QVariant>& ScriptContainer::getOptions()
|
||
|
{
|
||
|
return d->options;
|
||
|
}
|
||
|
|
||
|
QVariant ScriptContainer::getOption(const QString name, QVariant defaultvalue, bool /*recursive*/)
|
||
|
{
|
||
|
if(d->options.contains(name))
|
||
|
return d->options[name];
|
||
|
Kross::Api::InterpreterInfo* info = Kross::Api::Manager::scriptManager()->getInterpreterInfo( d->interpretername );
|
||
|
return info ? info->getOptionValue(name, defaultvalue) : defaultvalue;
|
||
|
}
|
||
|
|
||
|
bool ScriptContainer::setOption(const QString name, const QVariant& value)
|
||
|
{
|
||
|
Kross::Api::InterpreterInfo* info = Kross::Api::Manager::scriptManager()->getInterpreterInfo( d->interpretername );
|
||
|
if(info) {
|
||
|
if(info->hasOption(name)) {
|
||
|
d->options.replace(name, value);
|
||
|
return true;
|
||
|
} else krosswarning( QString("Kross::Api::ScriptContainer::setOption(%1, %2): No such option").arg(name).arg(value.toString()) );
|
||
|
} else krosswarning( QString("Kross::Api::ScriptContainer::setOption(%1, %2): No such interpreterinfo").arg(name).arg(value.toString()) );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
Object::Ptr ScriptContainer::execute()
|
||
|
{
|
||
|
if(! d->script)
|
||
|
if(! initialize())
|
||
|
return 0;
|
||
|
|
||
|
if(hadException())
|
||
|
return 0;
|
||
|
|
||
|
Object::Ptr r = d->script->execute();
|
||
|
if(d->script->hadException()) {
|
||
|
setException( d->script->getException() );
|
||
|
finalize();
|
||
|
return 0;
|
||
|
}
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
const QStringList ScriptContainer::getFunctionNames()
|
||
|
{
|
||
|
return d->script ? d->script->getFunctionNames() : QStringList(); //FIXME init before if needed?
|
||
|
}
|
||
|
|
||
|
Object::Ptr ScriptContainer::callFunction(const QString& functionname, List::Ptr arguments)
|
||
|
{
|
||
|
if(! d->script)
|
||
|
if(! initialize())
|
||
|
return 0;
|
||
|
|
||
|
if(hadException())
|
||
|
return 0;
|
||
|
|
||
|
if(functionname.isEmpty()) {
|
||
|
setException( new Exception(i18n("No functionname defined for ScriptContainer::callFunction().")) );
|
||
|
finalize();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
Object::Ptr r = d->script->callFunction(functionname, arguments);
|
||
|
if(d->script->hadException()) {
|
||
|
setException( d->script->getException() );
|
||
|
finalize();
|
||
|
return 0;
|
||
|
}
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
QStringList ScriptContainer::getClassNames()
|
||
|
{
|
||
|
return d->script ? d->script->getClassNames() : QStringList(); //FIXME init before if needed?
|
||
|
}
|
||
|
|
||
|
Object::Ptr ScriptContainer::classInstance(const QString& classname)
|
||
|
{
|
||
|
if(! d->script)
|
||
|
if(! initialize())
|
||
|
return 0;
|
||
|
|
||
|
if(hadException())
|
||
|
return 0;
|
||
|
|
||
|
Object::Ptr r = d->script->classInstance(classname);
|
||
|
if(d->script->hadException()) {
|
||
|
setException( d->script->getException() );
|
||
|
finalize();
|
||
|
return 0;
|
||
|
}
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
bool ScriptContainer::initialize()
|
||
|
{
|
||
|
finalize();
|
||
|
|
||
|
if(! d->scriptfile.isNull()) {
|
||
|
krossdebug( QString("Kross::Api::ScriptContainer::initialize() file=%1").arg(d->scriptfile) );
|
||
|
|
||
|
if(d->interpretername.isNull()) {
|
||
|
d->interpretername = Manager::scriptManager()->getInterpreternameForFile( d->scriptfile );
|
||
|
if(d->interpretername.isNull()) {
|
||
|
setException( new Exception(i18n("Failed to determinate interpreter for scriptfile '%1'").arg(d->scriptfile)) );
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QFile f( d->scriptfile );
|
||
|
if(! f.open(IO_ReadOnly)) {
|
||
|
setException( new Exception(i18n("Failed to open scriptfile '%1'").arg(d->scriptfile)) );
|
||
|
return false;
|
||
|
}
|
||
|
d->code = QString( f.readAll() );
|
||
|
f.close();
|
||
|
}
|
||
|
|
||
|
Interpreter* interpreter = Manager::scriptManager()->getInterpreter(d->interpretername);
|
||
|
if(! interpreter) {
|
||
|
setException( new Exception(i18n("Unknown interpreter '%1'").arg(d->interpretername)) );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
d->script = interpreter->createScript(this);
|
||
|
if(! d->script) {
|
||
|
setException( new Exception(i18n("Failed to create script for interpreter '%1'").arg(d->interpretername)) );
|
||
|
return false;
|
||
|
}
|
||
|
if(d->script->hadException()) {
|
||
|
setException( d->script->getException() );
|
||
|
finalize();
|
||
|
return false;
|
||
|
}
|
||
|
setException( 0 ); // clear old exception
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void ScriptContainer::finalize()
|
||
|
{
|
||
|
delete d->script;
|
||
|
d->script = 0;
|
||
|
}
|
||
|
|
||
|
|