#include "EditorKarte.h" #include #include #include #include #include #include #include #include using namespace Editor; SpielerDaten::SpielerDaten() : Model() {} SpielerDaten::SpielerDaten(const SpielerDaten& daten) { *this = daten; views->getThis(); } TeamDaten::TeamDaten() : Model() {} TeamDaten::TeamDaten(const TeamDaten& daten) { *this = daten; views->getThis(); } ObjektDaten::ObjektDaten() : Model() {} ObjektDaten::ObjektDaten(const ObjektDaten& daten) { *this = daten; views->getThis(); } EditorObject::EditorObject(EditorObject::ObjektTyp typ, int id) : Model2DObject() { this->typ = typ; this->id = id; } EditorObject::~EditorObject() {} bool EditorObject::isObjekt(EditorObject::ObjektTyp typ, int id) { return this->typ == typ && this->id == id; } EdSpieler::EdSpieler(SpielerDaten* model) : EditorObject(SPIELER, model->id) { mdl = model; } EdSpieler::~EdSpieler() {} void EdSpieler::update() { mdl->pos = position; mdl->rot = (double)rotation; mdl->update(); } EdObjekt::EdObjekt(ObjektDaten* model) : EditorObject(OBJEKT, model->id) { 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) { Model2DObject* model = new EdSpieler(s); Bild* bild; int fc = sts->spielerFarbe->get(s->id - 1); for (auto r : resources) { 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) { TeamDaten* d = t; d->addView(new UpdateObserver([this, d]() { aktionen.add([this, d]() { this->client->saveTeam(d); }); })); } for (auto o : objekte) { Model2DObject* model = new EdObjekt(o); Bild* bild; for (auto r : resources) { 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 = 0; Model2DData* da = 0; for (auto r : resources) { if (r->id == d->m2d) da = this->client->loadModel(r->path); if (r->id == d->bild) bild = this->client->loadBild(r->path); } if (bild && da) { Textur2D* textur = new Textur2D(); textur->setTexturZ(bild); model->postAction([model, da, textur]() { model->setModel(da); model->setTextur(textur); }); } else { if (bild) bild->release(); if (da) da->release(); } }); })); } exit = 0; start(); } KarteDaten::~KarteDaten() { cs.lock(); for (auto i : resources) delete i; for (auto i : objekte) delete i; for (auto i : spieler) delete i; for (auto i : teams) delete i; sts->release(); client->release(); welt->release(); Framework::getDLLRegister()->releaseDLL("GSL.dll"); cs.unlock(); } void KarteDaten::addObjekt(ObjektDaten& daten, std::function< void(int) > callBack) { ObjektDaten* nd = new ObjektDaten(daten); cs.lock(); nd->id = 0; bool found = 0; do { nd->id++; found = 0; for (auto o : objekte) { if (o->id == nd->id) { found = 1; break; } } } while (found); objekte.add(nd); Model2DObject* model = new EdObjekt(nd); Bild* bild; for (auto r : resources) { 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 = 0; Model2DData* d = 0; for (auto r : resources) { if (r->id == nd->m2d) d = this->client->loadModel(r->path); if (r->id == nd->bild) bild = this->client->loadBild(r->path); } if (bild && d) { Textur2D* textur = new Textur2D(); textur->setTexturZ(bild); model->postAction([model, d, textur]() { model->setModel(d); model->setTextur(textur); }); } else { if (bild) bild->release(); if (d) d->release(); } }); })); EditorKlient* c = client; aktionen.add([nd, c, callBack]() { if (c->saveObjekt(nd)) callBack(nd->id); else callBack(0); }); cs.unlock(); } void KarteDaten::removeObjekt(int index) { cs.lock(); int id = objekte.get(index)->id; EditorObject* obj = 0; for (auto o = welt->getMembers(); o; o++) { obj = (EditorObject*)o._; if (obj->isObjekt(EditorObject::OBJEKT, id)) break; } welt->removeObject(obj); 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) { 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) { 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) { 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) { if (i->id == id) break; index++; } cs.unlock(); return index; } int KarteDaten::getResourceAnzahl() { return resources.getEintragAnzahl(); } bool KarteDaten::hasError() const { return !error.istGleich(""); } const char* KarteDaten::getError() const { return error; } bool KarteDaten::hasAktions() const { return aktionen.getEintragAnzahl() > 0; } Welt2D* KarteDaten::getWelt() const { return dynamic_cast(welt->getThis()); } Welt2D* KarteDaten::zWelt() const { return welt; } void KarteDaten::getResourceIdFromPath(const char* path, std::function< void(int) > callBack) { for (auto r : resources) { 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) { if (r->path.istGleich(path)) return 1; } return 0; } Model2DData* KarteDaten::loadModelFromRessource(int id) { for (auto r : resources) { if (r->id == id) return client->loadModel(r->path); } return 0; } Bild* KarteDaten::loadBildFromRessource(int id) { for (auto r : resources) { 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) { if (!doesResourceExist(mp->getText())) result->add(dynamic_cast(mp->getThis())); } mapPaths->release(); callBack(result); }); cs.unlock(); } 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) { 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 void KarteDaten::stopWork() { if (run) { exit = 1; if (isRunning()) warteAufThread(INT_MAX); } }