#include "KSGSFunktion.h" #include "../Leser/KSGSLeser.h" #include "../Main/KSGScriptObj.h" #include "../Klassen/KSGSThread.h" #include "../Error/Error.h" #include "../Klassen/KSGSTyp.h" #include using namespace KSGScript; // Inhalt der KSGSFunktionInstanz Klasse aus KSGSFunktion.h // Konstruktor KSGSFunktionInstanz::KSGSFunktionInstanz( RCArray< KSGSBefehl > *ba, int rt, KSGScriptObj *obj, KSGSKlasseInstanz *klasse ) : Thread() { lokaleVariablen = new RCArray< KSGSVariable >(); befehle = ba; this->klasse = klasse; this->obj = obj; threadVar = 0; returnTyp = rt; retVar = 0; pausiert = 0; beendet = 0; breakB = 0; continueB = 0; scrId = obj->getScriptId(); ref = 1; } // Destruktor KSGSFunktionInstanz::~KSGSFunktionInstanz() { lokaleVariablen->release(); befehle->release(); if( klasse ) klasse->release(); obj->release(); if( threadVar ) threadVar->release(); if( retVar ) retVar->release(); } // privat void KSGSFunktionInstanz::lock() { cs.lock(); } void KSGSFunktionInstanz::unlock() { cs.unlock(); } // nicht constant void KSGSFunktionInstanz::setParameter( Array< KSGSVariableDef* > *zDef, RCArray< KSGSVariable > *vars ) { int anz = zDef->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { int id = zDef->get( i )->id; if( vars->z( id ) ) { if( zDef->get( i )->typId != vars->z( id )->getTyp() ) { KSGSVariable *var = vars->z( id )->umwandelnIn( zDef->get( i )->typId ); if( !var ) lokaleVariablen->set( KSGSVariable::erstellVariable( obj, zDef->get( i ) ), id ); else lokaleVariablen->set( var, id ); } else lokaleVariablen->set( vars->get( id ), id ); } else lokaleVariablen->set( KSGSVariable::erstellVariable( obj, zDef->get( i ) ), id ); } vars->release(); } void KSGSFunktionInstanz::setReturnVariable( KSGSVariable *var ) { if( var->getTyp() != returnTyp ) { error( 15, {}, obj ); KSGSVariable *tmp = var->umwandelnIn( returnTyp ); var->release(); var = tmp; } lock(); if( retVar ) retVar->release(); retVar = var; unlock(); } void KSGSFunktionInstanz::setPause( bool p ) { pausiert = p; } void KSGSFunktionInstanz::setContinue() { continueB = 1; } void KSGSFunktionInstanz::setBreak() { breakB = 0; } void KSGSFunktionInstanz::setEnde() { beendet = 1; } KSGSVariable *KSGSFunktionInstanz::startFunktion() { if( run ) return 0; if( threadVar ) threadVar = (KSGSThreadKlasse*)threadVar->release(); if( retVar ) retVar = retVar->release(); if( returnTyp == KSGS_THREAD ) { threadVar = new KSGSThreadKlasse( obj, getThis() ); start(); return threadVar->getThis(); } else { run = 1; thread(); warteAufFunktion( INFINITE ); return retVar ? retVar->getThis() : 0; } } void KSGSFunktionInstanz::thread() { getThis(); int anz = befehle->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { while( pausiert && !beendet && !obj->istBeendet( scrId ) ) Sleep( 100 ); if( obj->istBeendet( scrId ) || beendet ) break; KSGSBefehl *b = befehle->z( i ); if( b ) { KSGSVariable *var = b->ausführen( obj, this, klasse ); if( var ) var->release(); } } run = 0; if( threadVar ) { threadVar->threadEnde(); threadVar = (KSGSThreadKlasse*)threadVar->release(); } release(); } int KSGSFunktionInstanz::getStatus() { if( !isRunning() || beendet ) return 0; if( pausiert ) return 1; if( breakB ) { breakB = 0; return 2; } if( continueB ) { continueB = 0; return 3; } return 4; } void KSGSFunktionInstanz::setVariable( int id, KSGSVariable *var ) { lokaleVariablen->set( var, id ); } // constant KSGSVariable *KSGSFunktionInstanz::getVariable( int id ) const { return lokaleVariablen->get( id ); } int KSGSFunktionInstanz::getReturnTyp() const { return returnTyp; } bool KSGSFunktionInstanz::wirdFunktionAusgeführt() const { return isRunning(); } int KSGSFunktionInstanz::warteAufFunktion( int zeit ) { if( run ) return warteAufThread( zeit ); return 0; } bool KSGSFunktionInstanz::wirdAusgeführt() const { return isRunning() && !beendet && !pausiert; } // Reference Counting KSGSFunktionInstanz *KSGSFunktionInstanz::getThis() { ref++; return this; } KSGSFunktionInstanz *KSGSFunktionInstanz::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der KSGSFunktion Klasse aus KSGSFunktion.h // Konstruktor KSGSFunktion::KSGSFunktion( int id, int sichtbar, int typ ) : typId( typ ), sichtbar( sichtbar ), id( id ), ref( 1 ) { befehle = new RCArray< KSGSBefehl >(); parameter = new Array< KSGSVariableDef* >(); name = ""; } // Destruktor KSGSFunktion::~KSGSFunktion() { if( befehle ) befehle->release(); int anz = parameter->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) delete parameter->get( i ); if( parameter ) parameter->release(); } // nicht constant void KSGSFunktion::setName( const char *txt ) { name = txt; } void KSGSFunktion::addParameter( KSGSVariableDef *var ) { parameter->add( var ); } void KSGSFunktion::addBefehl( KSGSBefehl *befehl ) { befehle->add( befehl ); } KSGSFunktionInstanz *KSGSFunktion::erstellInstanz( KSGScriptObj *obj, KSGSKlasseInstanz *klasse, RCArray< KSGSVariable > *params ) { KSGSFunktionInstanz *inst = new KSGSFunktionInstanz( befehle->getThis(), typId, obj, klasse ); if( params ) inst->setParameter( parameter, params ); return inst; } // constant int KSGSFunktion::getId() const { return id; } int KSGSFunktion::getTypId() const { return typId; } int KSGSFunktion::getSichtbarkeit() const { return sichtbar; } bool KSGSFunktion::hatName( const char *txt ) const { return name.istGleich( txt ); } // Reference Counting KSGSFunktion *KSGSFunktion::getThis() { ref++; return this; } KSGSFunktion *KSGSFunktion::release() { ref--; if( !ref ) delete this; return 0; }