#include "EditorKarte.h" #include #include #include #include #include #include #include #include using namespace Editor; EditorObject::EditorObject() : Model2DObject() {} EditorObject::~EditorObject() {} EdSpieler::EdSpieler( SpielerDaten *model ) : EditorObject() { mdl = model; } EdSpieler::~EdSpieler() {} void EdSpieler::update() { mdl->pos = position; mdl->rot = (double)rotation; mdl->update(); } EdObjekt::EdObjekt( ObjektDaten *model ) : EditorObject() { mdl = model; } EdObjekt::~EdObjekt() {} void EdObjekt::update() { mdl->pos = position; mdl->rot = rotation; mdl->scale = size; mdl->update(); } UpdateObserver::UpdateObserver( std::function< void() > f ) { this->f = f; } void UpdateObserver::update( Model *m ) { f(); } KarteDaten::KarteDaten( EditorKlient *client, SpielerTeamStruktur *sts ) : Thread() { HMODULE dll = Framework::getDLLRegister()->ladeDLL( "GSL.dll", "data/bin/GSL.dll" ); getGSLDatei = (GetGSLDatei)GetProcAddress( dll, "getGSLDatei" ); welt = new Welt2D(); welt->setCircular( 1 ); this->client = client; this->sts = (SpielerTeamStruktur *)sts->getThis(); client->loadMapSize( size ); client->loadResources( resources ); client->loadSpieler( spieler ); client->loadTeams( teams ); client->loadObjekte( objekte ); welt->setSize( size.x, size.y ); welt->setSize( 1 ); for( auto s = spieler.getIterator(); s; s++ ) { Model2DObject *model = new EdSpieler( s._ ); Bild *bild; int fc = sts->spielerFarbe->get( s->id - 1 ); for( auto r = resources.getIterator(); r; r++ ) { if( r->id == s->m2d ) model->setModel( client->loadModel( r->path ) ); if( r->id == s->bild ) bild = client->loadBild( r->path ); } if( bild ) { Bild *shb = new Bild(); shb->neuBild( bild->getBreite(), bild->getHeight(), 0 ); int maxP = shb->getBreite() * shb->getHeight(); int *buffer = bild->getBuffer(); for( int i = 0; i < maxP; i++ ) { if( buffer[ i ] ) { shb->setPixelDP( i, fc ); shb->alphaPixelDP2D( i, buffer[ i ] ); } } Textur2D *textur = new Textur2D(); textur->setTexturZ( shb ); model->setTextur( textur, "ship" ); bild->release(); } model->setPosition( s->pos ); model->setDrehung( (float)s->rot ); model->setCollision( 0 ); welt->addObject( model ); SpielerDaten *d = s._; d->addView( new UpdateObserver( [ this, d ]() { aktionen.add( [ this, d ]() { this->client->saveSpieler( d ); } ); } ) ); } for( auto t = teams.getIterator(); t; t++ ) { TeamDaten *d = t._; d->addView( new UpdateObserver( [ this, d ]() { aktionen.add( [ this, d ]() { this->client->saveTeam( d ); } ); } ) ); } for( auto o = objekte.getIterator(); o; o++ ) { Model2DObject *model = new EdObjekt( o._ ); Bild *bild; for( auto r = resources.getIterator(); r; r++ ) { if( r->id == o->m2d ) model->setModel( client->loadModel( r->path ) ); if( r->id == o->bild ) bild = client->loadBild( r->path ); } if( bild ) { Textur2D *textur = new Textur2D(); textur->setTexturZ( bild ); model->setTextur( textur ); } model->setPosition( o->pos ); model->setDrehung( o->rot ); model->setSize( o->scale ); model->setCollision( 0 ); welt->addObject( model ); ObjektDaten *d = o._; d->addView( new UpdateObserver( [ this, d, model ]() { aktionen.add( [ this, d, model ]() { this->client->saveObjekt( d ); Bild *bild; for( auto r = resources.getIterator(); r; r++ ) { if( r->id == d->m2d ) model->setModel( this->client->loadModel( r->path ) ); if( r->id == d->bild ) bild = this->client->loadBild( r->path ); } if( bild ) { Textur2D *textur = new Textur2D(); textur->setTexturZ( bild ); model->setTextur( textur ); } } ); } ) ); } exit = 0; start(); } KarteDaten::~KarteDaten() { cs.lock(); for( auto i = resources.getIterator(); i; i++ ) delete i._; for( auto i = objekte.getIterator(); i; i++ ) delete i._; for( auto i = spieler.getIterator(); i; i++ ) delete i._; for( auto i = teams.getIterator(); i; i++ ) delete i._; sts->release(); client->release(); welt->release(); Framework::getDLLRegister()->releaseDLL( "GSL.dll" ); } void KarteDaten::addObjekt( ObjektDaten & daten, std::function< void( int ) > callBack ) { ObjektDaten *nd = new ObjektDaten( daten ); cs.lock(); nd->id = objekte.getEintragAnzahl() + 1; objekte.add( nd ); Model2DObject *model = new EdObjekt( nd ); Bild *bild; for( auto r = resources.getIterator(); r; r++ ) { if( r->id == nd->m2d ) model->setModel( client->loadModel( r->path ) ); if( r->id == nd->bild ) bild = client->loadBild( r->path ); } if( bild ) { Textur2D *textur = new Textur2D(); textur->setTexturZ( bild ); model->setTextur( textur ); } model->setPosition( nd->pos ); model->setDrehung( nd->rot ); model->setSize( nd->scale ); model->setCollision( 0 ); welt->addObject( model ); nd->addView( new UpdateObserver( [ this, nd, model ]() { aktionen.add( [ this, nd, model ]() { this->client->saveObjekt( nd ); Bild *bild; for( auto r = resources.getIterator(); r; r++ ) { if( r->id == nd->m2d ) model->setModel( this->client->loadModel( r->path ) ); if( r->id == nd->bild ) bild = this->client->loadBild( r->path ); } if( bild ) { Textur2D *textur = new Textur2D(); textur->setTexturZ( bild ); model->setTextur( textur ); } } ); } ) ); ObjektDaten td = *nd; EditorKlient *c = client; aktionen.add( [ td, c, callBack ]() { if( c->saveObjekt( &td ) ) callBack( td.id ); else callBack( 0 ); } ); cs.unlock(); } void KarteDaten::removeObjekt( int index ) { cs.lock(); int id = objekte.get( index )->id; delete objekte.get( index ); objekte.remove( index ); EditorKlient *c = client; aktionen.add( [ id, c ]() { c->deleteObjekt( id ); } ); cs.unlock(); } void KarteDaten::thread() { while( !exit ) { cs.lock(); while( hasAktions() ) { std::function< void() > ak = aktionen.get( 0 ); cs.unlock(); ak(); cs.lock(); aktionen.remove( 0 ); } cs.unlock(); Sleep( 100 ); } } ResourceDaten *KarteDaten::getResource( int index ) { ResourceDaten *ret = 0; cs.lock(); ret = resources.get( index ); cs.unlock(); return ret; } ObjektDaten *KarteDaten::getObjekt( int index ) { ObjektDaten *ret = 0; cs.lock(); ret = objekte.get( index ); cs.unlock(); return ret; } SpielerDaten *KarteDaten::getSpieler( int index ) { SpielerDaten *ret = 0; cs.lock(); ret = spieler.get( index ); cs.unlock(); return ret; } TeamDaten *KarteDaten::getTeam( int index ) { TeamDaten *ret = 0; cs.lock(); ret = teams.get( index ); cs.unlock(); return ret; } const char *KarteDaten::getTeamName( int index ) { return sts->teamName->z( teams.get( index )->id - 1 )->getText(); } int KarteDaten::getSpielerIndexById( int id ) { int index = 0; cs.lock(); for( auto i = spieler.getIterator(); i; i++ ) { if( i->id == id ) break; index++; } cs.unlock(); return index; } int KarteDaten::getSpielerAnzahl() const { return spieler.getEintragAnzahl(); } int KarteDaten::getTeamIndexById( int id ) { int index = 0; cs.lock(); for( auto i = teams.getIterator(); i; i++ ) { if( i->id == id ) break; index++; } cs.unlock(); return index; } int KarteDaten::getTeamAnzahl() const { return teams.getEintragAnzahl(); } int KarteDaten::getObjektIndexById( int id ) { int index = 0; cs.lock(); for( auto i = objekte.getIterator(); i; i++ ) { if( i->id == id ) break; index++; } cs.unlock(); return index; } int KarteDaten::getObjektAnzahl() const { return objekte.getEintragAnzahl(); } int KarteDaten::getResourceIndexById( int id ) { int index = 0; cs.lock(); for( auto i = resources.getIterator(); i; i++ ) { if( i->id == id ) break; index++; } cs.unlock(); return index; } int KarteDaten::getResourceAnzahl() { return resources.getEintragAnzahl(); } bool KarteDaten::hasError() const { return !error.istGleich( "" ); } char *KarteDaten::getError() const { return error; } bool KarteDaten::hasAktions() const { return aktionen.getEintragAnzahl() > 0; } Welt2D *KarteDaten::getWelt() const { return welt->getThis(); } Welt2D *KarteDaten::zWelt() const { return welt; } void KarteDaten::getResourceIdFromPath( const char *path, std::function< void( int ) > callBack ) { for( auto r = resources.getIterator(); r; r++ ) { if( r->path.istGleich( path ) ) { callBack( r->id ); return; } } aktionen.add( [ this, path, callBack ]() { int id = client->addResource( path ); if( !id ) { callBack( 0 ); return; } ResourceDaten *nr = new ResourceDaten(); nr->id = id; nr->path = path; cs.lock(); resources.add( nr ); cs.unlock(); callBack( id ); } ); } bool KarteDaten::doesResourceExist( const char *path ) { for( auto r = resources.getIterator(); r; r++ ) { if( r->path.istGleich( path ) ) return 1; } return 0; } Model2DData *KarteDaten::loadModelFromRessource( int id ) { for( auto r = resources.getIterator(); r; r++ ) { if( r->id == id ) return client->loadModel( r->path ); } return 0; } Bild *KarteDaten::loadBildFromRessource( int id ) { for( auto r = resources.getIterator(); r; r++ ) { if( r->id == id ) return client->loadBild( r->path ); } return 0; } Model2DData *KarteDaten::loadModelFromPath( const char *path ) { return client->loadModel( path ); } Bild *KarteDaten::loadBildFromPath( const char *path ) { return client->loadBild( path ); } void KarteDaten::loadUnusedResourcePaths( std::function< void( RCArray< Text > * ) > callBack ) { cs.lock(); aktionen.add( [ this, callBack ]() { RCArray< Text > *result = new RCArray< Text >(); loadSpielResourcePathsFromFolder( "data/spiele/Asteroids", result ); RCArray< Text > *mapPaths = client->getAllMapResourcePaths(); for( auto mp = mapPaths->getIterator(); mp; mp++ ) { if( !doesResourceExist( mp->getText() ) ) result->add( mp->getThis() ); } mapPaths->release(); callBack( result ); } ); } void KarteDaten::loadSpielResourcePathsFromFolder( const char *folderPath, RCArray< Text > * zPaths ) { Datei f; f.setDatei( folderPath ); if( f.istOrdner() ) { RCArray< Text > *list = f.getDateiListe(); for( auto n = list->getIterator(); n; n++ ) { Text path( folderPath ); path += Text( "/" ) + (const char *)n->getText(); loadSpielResourcePathsFromFolder( path, zPaths ); } list->release(); } else { if( f.zPfad()->hat( ".ltdb" ) ) { LTDBDatei d; d.setDatei( new Text( folderPath ) ); d.leseDaten( 0 ); int anz = d.getBildAnzahl(); for( int i = 0; i < anz; i++ ) { Text *path = new Text( folderPath ); path->ersetzen( 0, (int)strlen( "data/spiele/Asteroids" ), "spiel:" ); path->append( (const char *)( Text( "/" ) + (const char *)d.zBildListe()->z( i )->getText() ) ); if( doesResourceExist( path->getText() ) ) path->release(); else zPaths->add( path ); } } if( f.zPfad()->hat( ".m2" ) ) { M2Datei d; d.setPfad( folderPath ); d.leseDaten(); int anz = d.getModelAnzahl(); for( int i = 0; i < anz; i++ ) { Text *path = new Text( folderPath ); path->ersetzen( 0, (int)strlen( "data/spiele/Asteroids" ), "spiel:" ); path->append( (const char *)( Text( "/" ) + (const char *)d.zModelName( i )->getText() ) ); if( doesResourceExist( path->getText() ) ) path->release(); else zPaths->add( path ); } } if( f.zPfad()->hat( ".gsl" ) ) { HMODULE dll = Framework::getDLLRegister()->ladeDLL( "GSL.dll", "data/bin/GSL.dll" ); GSL::GSLDateiV *d = getGSLDatei(); d->setDatei( (char *)folderPath ); d->leseDaten(); int anz = d->getSoundAnzahl(); for( int i = 0; i < anz; i++ ) { Text *path = new Text( folderPath ); path->ersetzen( 0, (int)strlen( "data/spiele/Asteroids" ), "spiel:" ); Text *name = d->getSoundName( i ); path->append( (const char *)( Text( "/" ) + (const char *)name->getText() ) ); name->release(); if( doesResourceExist( path->getText() ) ) path->release(); else zPaths->add( path ); } } } } // löscht das objekt wenn es nicht mehr gebraucht wird und beendet den Thread Thread *KarteDaten::release() { if( Thread::ref == 2 && run ) { exit = 1; if( isRunning() ) warteAufThread( INT_MAX ); } return Thread::release(); }