00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "qtscriptcomponent.h"
00022
00023 #include <core/gluonobject.h>
00024 #include <graphics/materialinstance.h>
00025 #include <gameobject.h>
00026 #include <core/debughelper.h>
00027 #include <game.h>
00028 #include <engine/asset.h>
00029
00030 #include <QtScript/QScriptEngine>
00031 #include <QtCore/QDebug>
00032 #include <QMimeData>
00033
00034
00035 REGISTER_OBJECTTYPE( GluonEngine, QtScriptComponent )
00036
00037 using namespace GluonEngine;
00038
00039 void qtscript_initialize_com_trolltech_qt_gui_bindings( QScriptValue& );
00040 class QtScriptComponent::QtScriptComponentPrivate
00041 {
00042 public:
00043 QtScriptComponentPrivate()
00044 {
00045 QScriptValue extensionObject = engine.globalObject();
00046 qtscript_initialize_com_trolltech_qt_gui_bindings( extensionObject );
00047 script = 0;
00048 }
00049
00050 QScriptEngine engine;
00051
00052 QScriptValue drawFunc;
00053 QScriptValue updateFunc;
00054
00055 GluonEngine::Asset* script;
00056 };
00057
00058 QtScriptComponent::QtScriptComponent( QObject* parent )
00059 : Component( parent )
00060 , d( new QtScriptComponentPrivate )
00061 {
00062 qScriptRegisterMetaType( &d->engine, gluonObjectToScriptValue, gluonObjectFromScriptValue );
00063 qScriptRegisterMetaType( &d->engine, gameObjectToScriptValue, gameObjectFromScriptValue );
00064 qScriptRegisterMetaType( &d->engine, materialInstanceToScriptValue, materialInstanceFromScriptValue );
00065 }
00066
00067 QtScriptComponent::QtScriptComponent( const QtScriptComponent& other )
00068 : Component( other )
00069 , d( other.d )
00070 {
00071 }
00072
00073 QtScriptComponent::~QtScriptComponent()
00074 {
00075 delete d;
00076 }
00077
00078 QString QtScriptComponent::category() const
00079 {
00080 return QString( "Game Logic" );
00081 }
00082
00083 void QtScriptComponent::initialize()
00084 {
00085 if( !d->script )
00086 return;
00087
00088 d->script->load();
00089
00090 if( d->script->data()->hasText() )
00091 {
00092 d->engine.evaluate( d->script->data()->text(), gameObject()->name() );
00093 if( d->engine.uncaughtException().isValid() )
00094 {
00095 debug( QString( "%1: %2" ).arg( d->engine.uncaughtException().toString() ).arg( d->engine.uncaughtExceptionBacktrace().join( " " ) ) );
00096 return;
00097 }
00098
00099 QScriptValue component = d->engine.newQObject( this, QScriptEngine::QtOwnership, QScriptEngine::AutoCreateDynamicProperties );
00100 d->engine.globalObject().setProperty( "Component", component );
00101
00102 QScriptValue gameObj = d->engine.newQObject( gameObject(), QScriptEngine::QtOwnership, QScriptEngine::AutoCreateDynamicProperties );
00103 d->engine.globalObject().setProperty( "GameObject", gameObj );
00104
00105 QScriptValue game = d->engine.newQObject( Game::instance(), QScriptEngine::QtOwnership, QScriptEngine::AutoCreateDynamicProperties );
00106 d->engine.globalObject().setProperty( "Game", game );
00107
00108 d->updateFunc = d->engine.globalObject().property( "update" );
00109 d->drawFunc = d->engine.globalObject().property( "draw" );
00110
00111 QScriptValue initFunc = d->engine.globalObject().property( "initialize" );
00112 if( initFunc.isFunction() )
00113 {
00114 initFunc.call( QScriptValue() );
00115 if( d->engine.uncaughtException().isValid() )
00116 debug( QString( "%1: %2" ).arg( d->engine.uncaughtException().toString() ).arg( d->engine.uncaughtExceptionBacktrace().join( " " ) ) );
00117 }
00118 }
00119 }
00120
00121 void QtScriptComponent::start()
00122 {
00123 if( d->script )
00124 {
00125 QScriptValue startFunc = d->engine.globalObject().property( "start" );
00126 if( startFunc.isFunction() )
00127 {
00128 startFunc.call( QScriptValue() );
00129 if( d->engine.uncaughtException().isValid() )
00130 debug( QString( "%1: %2" ).arg( d->engine.uncaughtException().toString() ).arg( d->engine.uncaughtExceptionBacktrace().join( " " ) ) );
00131 }
00132 }
00133 }
00134
00135 void QtScriptComponent::draw( int timeLapse )
00136 {
00137 if( d->drawFunc.isFunction() )
00138 {
00139 d->drawFunc.call( QScriptValue(), QScriptValueList() << timeLapse );
00140 if( d->engine.uncaughtException().isValid() )
00141 {
00142 debug( QString( "%1: %2" ).arg( d->engine.uncaughtException().toString() ).arg( d->engine.uncaughtExceptionBacktrace().join( " " ) ) );
00143 d->drawFunc = QScriptValue();
00144 }
00145 }
00146 }
00147
00148 void QtScriptComponent::update( int elapsedMilliseconds )
00149 {
00150 if( d->updateFunc.isFunction() )
00151 {
00152 d->updateFunc.call( QScriptValue(), QScriptValueList() << elapsedMilliseconds );
00153 if( d->engine.uncaughtException().isValid() )
00154 {
00155 debug( QString( "%1: %2" ).arg( d->engine.uncaughtException().toString() ).arg( d->engine.uncaughtExceptionBacktrace().join( " " ) ) );
00156 d->updateFunc = QScriptValue();
00157 }
00158 }
00159 }
00160
00161 void QtScriptComponent::stop()
00162 {
00163 if( d->script )
00164 {
00165 QScriptValue stopFunc = d->engine.globalObject().property( "stop" );
00166 if( stopFunc.isFunction() )
00167 {
00168 stopFunc.call( QScriptValue() );
00169 if( d->engine.uncaughtException().isValid() )
00170 debug( QString( "%1: %2" ).arg( d->engine.uncaughtException().toString() ).arg( d->engine.uncaughtExceptionBacktrace().join( " " ) ) );
00171 }
00172 }
00173 }
00174
00175 void QtScriptComponent::cleanup()
00176 {
00177 if( d->script )
00178 {
00179 QScriptValue cleanupFunc = d->engine.globalObject().property( "cleanup" );
00180 if( cleanupFunc.isFunction() )
00181 {
00182 cleanupFunc.call( QScriptValue() );
00183 if( d->engine.uncaughtException().isValid() )
00184 debug( QString( "%1: %2" ).arg( d->engine.uncaughtException().toString() ).arg( d->engine.uncaughtExceptionBacktrace().join( " " ) ) );
00185 }
00186 }
00187 }
00188
00189 Asset* QtScriptComponent::script()
00190 {
00191 return d->script;
00192 }
00193
00194 void QtScriptComponent::setScript( Asset* asset )
00195 {
00196 d->script = asset;
00197 }
00198
00199 QScriptValue gluonObjectToScriptValue( QScriptEngine* engine, const pGluonObject& in )
00200 {
00201 return engine->newQObject( in );
00202 }
00203
00204 void gluonObjectFromScriptValue( const QScriptValue& object, pGluonObject& out )
00205 {
00206 out = qobject_cast<GluonCore::GluonObject*>( object.toQObject() );
00207 }
00208
00209 QScriptValue gameObjectToScriptValue( QScriptEngine* engine, const pGameObject& in )
00210 {
00211 return engine->newQObject( in );
00212 }
00213
00214 void gameObjectFromScriptValue( const QScriptValue& object, pGameObject& out )
00215 {
00216 out = qobject_cast<GameObject*>( object.toQObject() );
00217 }
00218
00219 QScriptValue materialInstanceToScriptValue( QScriptEngine* engine, const pMaterialInstance& in )
00220 {
00221 return engine->newQObject( in );
00222 }
00223
00224 void materialInstanceFromScriptValue( const QScriptValue& object, pMaterialInstance& out )
00225 {
00226 out = qobject_cast<pMaterialInstance>( object.toQObject() );
00227 }
00228
00229 Q_EXPORT_PLUGIN2( gluon_component_qtscript, GluonEngine::QtScriptComponent );
00230
00231 #include "qtscriptcomponent.moc"