#include "KSGScriptObj.h" #include "../Befehl/KSGSKlasse.h" #include "../Leser/KSGSLeser.h" #include #include #include #include #include "../Klassen/KSGSMausEreignis.h" #include "../Klassen/KSGSTastaturEreignis.h" #include "../Klassen/KSGSInt.h" #include "../Klassen/KSGSBild.h" #include "../Klassen/KSGSDouble.h" #include "../Error/Error.h" #include #include using namespace KSGScript; // Inhalt der KSGScriptObj Klasse aus KSGScriptObj.h // Konstruktor KSGScriptObj::KSGScriptObj() { pfad = new Text(); wd = new Text(); rParam = 0; rFunktion = 0; variablen = new RCArray< KSGSVariable >(); funktionen = new RCArray< KSGSFunktion >(); klassen = new RCArray< KSGSKlasse >(); schrift = 0; screen = 0; mainId = 0; mausId = 0; tastaturId = 0; tickId = 0; renderId = 0; geladen = 0; scrId = 0; ref = 1; mausP = new RCArray< KSGSVariable >(); tastaturP = new RCArray< KSGSVariable >(); tickP = new RCArray< KSGSVariable >(); renderP = new RCArray< KSGSVariable >(); log = 0; } // Destruktor KSGScriptObj::~KSGScriptObj() { if( schrift ) schrift->release(); if( screen ) screen->release(); zurücksetzen(); mausP->release(); tastaturP->release(); tickP->release(); renderP->release(); pfad->release(); wd->release(); variablen->release(); funktionen->release(); klassen->release(); if( log ) log->release(); } // nicht constant void KSGScriptObj::lock() { cs.lock(); } void KSGScriptObj::unlock() { cs.unlock(); } void KSGScriptObj::setScriptDatei( const char *pfad ) { this->pfad->setText( pfad ); this->pfad->ersetzen( '\\', '/' ); int l = this->pfad->hat( '/' ) ? this->pfad->positionVon( '/', this->pfad->anzahlVon( '/' ) - 1 ) + 1 : 0; if( l ) wd->setText( pfad, l ); } void KSGScriptObj::setScriptDatei( Text *pfad ) { setScriptDatei( pfad->getText() ); pfad->release(); } bool KSGScriptObj::neuLaden() { lock(); ZeitMesser *gzm = new ZeitMesser(); gzm->messungStart(); if( geladen ) zurücksetzen(); scrId++; KSGSLeser *reader = new KSGSLeser( *pfad, this ); ZeitMesser *zm = new ZeitMesser(); zm->messungStart(); if( !reader->laden() ) { reader->release(); zm->release(); gzm->release(); unlock(); return 0; } zm->messungEnde(); if( log ) { Text msg = "Reader: Zum lesen benötigte Sekunden: "; msg += zm->getSekunden(); logNachricht( msg ); } std::cout << "KSGS Reader: Zum lesen benötigte Sekunden: " << zm->getSekunden() << "\n"; Array< KSGSVariableDef* > *varDefs = new Array< KSGSVariableDef* >(); zm->messungStart(); if( !reader->compile( klassen, funktionen, varDefs ) ) { varDefs->release(); reader->release(); zm->release(); gzm->release(); unlock(); return 0; } mausP->add( new KSGSMausEreignisKlasse( this ) ); tastaturP->add( new KSGSTastaturEreignisKlasse( this ) ); tickP->add( new KSGSDoubleKlasse( this ) ); renderP->add( new KSGSBildKlasse( this ) ); zm->messungEnde(); if( log ) { Text msg = "Reader: Zum compilieren benötigte Sekunden: "; msg += zm->getSekunden(); logNachricht( msg ); } std::cout << "KSGS Reader: Zum compilieren benötigte Sekunden: " << zm->getSekunden() << "\n"; zm->release(); int vAnz = varDefs->getEintragAnzahl(); for( int i = 0; i < vAnz; i++ ) { KSGSVariable *var = KSGSVariable::erstellVariable( this, varDefs->get( i ) ); if( var ) variablen->add( var ); delete varDefs->get( i ); } varDefs->release(); mainId = reader->getMainFuncId(); mausId = reader->getMausFuncId(); tastaturId = reader->getTastaturFuncId(); tickId = reader->getTickFuncId(); renderId = reader->getRenderFuncId(); reader->release(); int anz = funktionen->getEintragAnzahl(); geladen = 1; for( int i = 0; i < anz; i++ ) { if( funktionen->z( i )->getId() == mainId ) { KSGSFunktionInstanz *inst = funktionen->z( i )->erstellInstanz( getThis(), 0, 0 ); KSGSVariable *ret = inst->startFunktion(); if( ret ) ret->release(); if( inst->wirdFunktionAusgeführt() ) inst->warteAufFunktion( INFINITE ); inst->release(); break; } } geladen = 2; gzm->messungEnde(); if( log ) { Text msg = "Reader: Zum laden benötigte Sekunden: "; msg += gzm->getSekunden(); logNachricht( msg ); } std::cout << "KSGS Reader: Zum laden benötigte Sekunden: " << gzm->getSekunden() << "\n"; gzm->release(); unlock(); return 1; } void KSGScriptObj::zurücksetzen() { lock(); geladen = 0; variablen->leeren(); funktionen->leeren(); klassen->leeren(); mausP->leeren(); tastaturP->leeren(); tickP->leeren(); renderP->leeren(); unlock(); } void KSGScriptObj::setRückrufParam( void *p ) { rParam = p; } void KSGScriptObj::setRückrufFunktion( void( *funktion )( void *, RCArray< KSGSVariable > *, KSGSVariable ** ) ) { rFunktion = funktion; } void KSGScriptObj::setSchriftZ( Schrift *s ) { if( schrift ) schrift->release(); schrift = s; } void KSGScriptObj::setBildschirmZ( Bildschirm *s ) { if( screen ) screen->release(); screen = s; } void KSGScriptObj::doMausEreignis( MausEreignis &me ) { if( geladen != 2 ) return; lock(); me.mx -= pos.x; me.my -= pos.y; int anz = funktionen->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( funktionen->z( i )->getId() == mausId ) { ( (KSGSMausEreignisKlasse*)mausP->z( 0 ) )->set( me ); KSGSFunktionInstanz *inst = funktionen->z( i )->erstellInstanz( getThis(), 0, mausP->getThis() ); KSGSVariable *ret = inst->startFunktion(); if( ret ) { me.verarbeitet |= ret->getBool(); ret->release(); } if( inst->wirdFunktionAusgeführt() ) inst->warteAufFunktion( INFINITE ); inst->release(); break; } } me.mx += pos.x; me.my += pos.y; unlock(); } void KSGScriptObj::doTastaturEreignis( TastaturEreignis &te ) { if( geladen != 2 ) return; lock(); int anz = funktionen->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( funktionen->z( i )->getId() == tastaturId ) { ( (KSGSTastaturEreignisKlasse*)tastaturP->z( 0 ) )->set( te ); KSGSFunktionInstanz *inst = funktionen->z( i )->erstellInstanz( getThis(), 0, tastaturP->getThis() ); KSGSVariable *ret = inst->startFunktion(); if( ret ) { te.verarbeitet |= ret->getBool(); ret->release(); } if( inst->wirdFunktionAusgeführt() ) inst->warteAufFunktion( INFINITE ); inst->release(); break; } } unlock(); } bool KSGScriptObj::tick( double zeit ) { if( geladen != 2 ) return 0; lock(); int anz = funktionen->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( funktionen->z( i )->getId() == tickId ) { ( (KSGSDoubleKlasse*)tickP->z( 0 ) )->set( zeit ); KSGSFunktionInstanz *inst = funktionen->z( i )->erstellInstanz( getThis(), 0, tickP->getThis() ); KSGSVariable *ret = inst->startFunktion(); bool r = 0; if( ret ) { r = ret->getBool(); ret->release(); } if( inst->wirdFunktionAusgeführt() ) inst->warteAufFunktion( INFINITE ); inst->release(); unlock(); return r; } } unlock(); return 0; } void KSGScriptObj::render( Bild &zRObj ) { if( geladen != 2 ) return; lock(); if( !zRObj.setDrawOptions( pos, gr ) ) { unlock(); return; } int anz = funktionen->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( funktionen->z( i )->getId() == renderId ) { ( (KSGSBildKlasse*)renderP->z( 0 ) )->set( zRObj.getThis() ); KSGSFunktionInstanz *inst = funktionen->z( i )->erstellInstanz( getThis(), 0, renderP->getThis() ); KSGSVariable *ret = inst->startFunktion(); if( ret ) ret->release(); if( inst->wirdFunktionAusgeführt() ) inst->warteAufFunktion( INFINITE ); inst->release(); break; } } zRObj.releaseDrawOptions(); unlock(); } KSGSVariable *KSGScriptObj::startFunktion( int id, RCArray< KSGSVariable > *parameter ) { if( !funktionen || !funktionen->z( id ) || funktionen->z( id )->getSichtbarkeit() != 0 ) { error( 19, {}, this ); parameter->release(); return 0; } KSGSFunktionInstanz *inst = funktionen->z( id )->erstellInstanz( getThis(), 0, parameter ); KSGSVariable *ret = inst->startFunktion(); inst->release(); return ret; } KSGSVariable *KSGScriptObj::erstellKlassenInstanz( int id ) { int anz = klassen->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( klassen->z( i ) && klassen->z( i )->getId() == id ) return klassen->z( i )->erstellInstanz( this ); } error( 2, {}, this ); return 0; } void KSGScriptObj::setVariable( int id, KSGSVariable *var ) { variablen->set( var, id ); } Text *KSGScriptObj::convertPfad( char *pf ) { Text *ret = new Text( pf ); ret->ersetzen( '\\', '/' ); if( ret->getText()[ 0 ] == '/' ) { ret->remove( 0 ); return ret; } ret->insert( 0, wd->getText() ); return ret; } void KSGScriptObj::setLog( TextFeld *log ) { lock(); if( this->log ) this->log->release(); this->log = log; unlock(); } void KSGScriptObj::logNachricht( char *n ) { if( log ) { lock(); log->addZeile( n ); unlock(); } } // constant KSGSVariable *KSGScriptObj::rückruf( RCArray< KSGSVariable > *parameter ) const { if( !rFunktion ) { parameter->release(); return 0; } KSGSVariable *ret = 0; rFunktion( rParam, parameter, &ret ); parameter->release(); return ret; } Text *KSGScriptObj::getScriptDateiPfad() const { return pfad->getThis(); } Text *KSGScriptObj::zScriptDateiPfad() const { return pfad; } Schrift *KSGScriptObj::getSchrift() const { return schrift ? schrift->getThis() : 0; } Schrift *KSGScriptObj::zSchrift() const { return schrift; } Bildschirm *KSGScriptObj::getBildschirm() const { return screen ? screen->getThis() : 0; } Bildschirm *KSGScriptObj::zBildschirm() const { return screen; } int KSGScriptObj::getScriptId() const { return scrId; } bool KSGScriptObj::istBeendet( int scrId ) const { return !geladen || this->scrId != scrId; } int KSGScriptObj::getFunktionId( const char *name ) const { int anz = funktionen->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) { if( funktionen->z( i )->hatName( name ) ) return i; } return -1; } KSGSVariable *KSGScriptObj::getVariable( int id ) const { if( !variablen || !variablen->z( id ) ) { error( 17, {}, (KSGScriptObj*)this ); return 0; } return variablen->get( id ); } // Reference Counting KSGScriptObj *KSGScriptObj::getThis() { ref++; return this; } KSGScriptObj *KSGScriptObj::release() { ref--; if( !ref ) delete this; return 0; }