diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 0403fb0c6..13361be82 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -105,6 +105,93 @@ void MeshCallbackTeamColor::execute(const Mesh *mesh){ } } +// =========================================================== +// class InterpolateTaskThread +// =========================================================== + +InterpolateTaskThread::InterpolateTaskThread(InterpolateTaskCallbackInterface *interpolateTaskInterface) +: BaseThread() { + this->interpolateTaskInterface = interpolateTaskInterface; + nullEntityList(); + this->taskSignalled = false; +} + +void InterpolateTaskThread::setQuitStatus(bool value) { + BaseThread::setQuitStatus(value); + if(value == true) { + semaphoreTaskSignaller.signal(); + } +} +void InterpolateTaskThread::setRunningStatus(bool value) { + BaseThread::setRunningStatus(value); + if(value == false) { + semaphoreTaskSignaller.signal(); + } +} + +void InterpolateTaskThread::setTaskSignalled(std::vector *vctEntity) { + mutexTaskSignaller.p(); + this->vctEntity = vctEntity; + mutexTaskSignaller.v(); + + if(this->vctEntity != NULL) { + semaphoreTaskSignaller.signal(); + } +} + +bool InterpolateTaskThread::getTaskSignalled() { + bool result = false; + mutexTaskSignaller.p(); + result = (vctEntity != NULL && vctEntity->size() > 0); + mutexTaskSignaller.v(); + return result; +} + +void InterpolateTaskThread::nullEntityList() { + mutexTaskSignaller.p(); + this->vctEntity = NULL; + mutexTaskSignaller.v(); +} + +void InterpolateTaskThread::execute() { + try { + setRunningStatus(true); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + for(;this->interpolateTaskInterface != NULL;) { + if(getQuitStatus() == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + break; + } + + int semValue = semaphoreTaskSignaller.waitTillSignalled(); + + if(getQuitStatus() == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + break; + } + + if(getTaskSignalled() == true) { + if(vctEntity != NULL) { + this->interpolateTaskInterface->interpolateTask(*vctEntity); + nullEntityList(); + } + } + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + catch(const exception &ex) { + setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ex.what() = [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + + throw runtime_error(ex.what()); + } + setRunningStatus(false); +} + // =========================================================== // class Renderer // =========================================================== @@ -171,9 +258,16 @@ Renderer::Renderer(){ } allowRotateUnits = config.getBool("AllowRotateUnits","0"); + + interpolateThread = new InterpolateTaskThread(this); + interpolateThread->start(); } Renderer::~Renderer(){ + BaseThread::shutdownAndWait(interpolateThread); + delete interpolateThread; + interpolateThread = NULL; + delete modelRenderer; delete textRenderer; delete particleRenderer; @@ -1240,10 +1334,7 @@ void Renderer::renderSurface(){ assertGl(); } -void Renderer::renderObjects(){ - Chrono chrono; - chrono.start(); - +void Renderer::renderObjects() { const World *world= game->getWorld(); const Map *map= world->getMap(); @@ -1251,9 +1342,6 @@ void Renderer::renderObjects(){ const Texture2D *fowTex= world->getMinimap()->getFowTexture(); Vec3f baseFogColor= world->getTileset()->getFogColor()*computeLightColor(world->getTimeFlow()->getTime()); - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - chrono.start(); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT); if(shadows==sShadowMapping){ @@ -1265,111 +1353,188 @@ void Renderer::renderObjects(){ static_cast(modelRenderer)->setDuplicateTexCoords(true); enableProjectiveTexturing(); } - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - chrono.start(); glActiveTexture(baseTexUnit); glEnable(GL_COLOR_MATERIAL); glAlphaFunc(GL_GREATER, 0.5f); - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - chrono.start(); - - modelRenderer->begin(true, true, false); + //modelRenderer->begin(true, true, false); int thisTeamIndex= world->getThisTeamIndex(); - int loopCount1 = 0; - int loopCount2 = 0; - - Chrono chrono2; - int64 sectionA = 0; - int64 sectionB = 0; - int64 sectionC = 0; - int64 sectionD = 0; - int64 sectionE = 0; - int64 sectionF = 0; - int64 sectionG = 0; - int64 sectionH = 0; + std::vector vctEntity; PosQuadIterator pqi(map, visibleQuad, Map::cellScale); while(pqi.next()){ - - chrono2.start(); - - const Vec2i pos= pqi.getPos(); - bool isPosVisible = map->isInside(pos); - - sectionG += chrono2.getMillis(); - chrono2.start(); - + const Vec2i &pos= pqi.getPos(); + bool isPosVisible = map->isInside(pos.x, pos.y); if(isPosVisible == true) { - - SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(pos)); + Vec2i mapPos = Map::toSurfCoords(pos); + SurfaceCell *sc= map->getSurfaceCell(mapPos.x, mapPos.y); Object *o= sc->getObject(); bool isExplored = (sc->isExplored(thisTeamIndex) && o!=NULL); - - sectionH += chrono2.getMillis(); - chrono2.start(); - if(isExplored == true) { - chrono2.start(); - const Model *objModel= sc->getObject()->getModel(); - Vec3f v= o->getPos(); +/* + const Model *objModel= o->getModel(); + const Vec3f &v= o->getConstPos(); //ambient and diffuse color is taken from cell color - float fowFactor= fowTex->getPixmap()->getPixelf(pos.x/Map::cellScale, pos.y/Map::cellScale); + //!!!float fowFactor= fowTex->getPixmap()->getPixelf(pos.x/Map::cellScale, pos.y/Map::cellScale); + float fowFactor= fowTex->getPixmap()->getPixelf(mapPos.x,mapPos.y); + Vec4f color= Vec4f(Vec3f(fowFactor), 1.f); glColor4fv(color.ptr()); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (color*ambFactor).ptr()); glFogfv(GL_FOG_COLOR, (baseFogColor*fowFactor).ptr()); - sectionA += chrono2.getMillis(); - chrono2.start(); - glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(v.x, v.y, v.z); glRotatef(o->getRotation(), 0.f, 1.f, 0.f); - sectionB += chrono2.getMillis(); - chrono2.start(); - objModel->updateInterpolationData(0.f, true); - sectionC += chrono2.getMillis(); - chrono2.start(); - modelRenderer->render(objModel); - sectionD += chrono2.getMillis(); - chrono2.start(); - triangleCount+= objModel->getTriangleCount(); pointCount+= objModel->getVertexCount(); glPopMatrix(); +*/ - sectionF += chrono2.getMillis(); - - loopCount2++; + //renderObject(RenderEntity(o,mapPos),baseFogColor); + vctEntity.push_back(RenderEntity(o,mapPos)); } } - - loopCount1++; } + modelRenderer->begin(true, true, false); + renderObjectList(vctEntity,baseFogColor); modelRenderer->end(); - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d loopCount1 = %d loopCount2 = %d took msecs: %d [%d,%d,%d,%d,%d,%d,%d,%d]\n",__FILE__,__FUNCTION__,__LINE__,loopCount1,loopCount2,chrono.getMillis(),sectionG,sectionH,sectionA,sectionB,sectionC,sectionD,sectionE,sectionF); - chrono.start(); - //restore static_cast(modelRenderer)->setDuplicateTexCoords(true); glPopAttrib(); +} - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); +void Renderer::interpolateTask(std::vector &vctEntity) { + for(int idx=0; idx < vctEntity.size(); ++idx) { + prepareObjectForRender(vctEntity[idx]); + } +} + +void Renderer::renderObjectList(std::vector &vctEntity,const Vec3f &baseFogColor) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); + + // Run interpolation threaded if the thread is created + if(interpolateThread != NULL) { + interpolateThread->setTaskSignalled(&vctEntity); + } + else { + interpolateTask(vctEntity); + } + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); + + std::map entityPendingLookup; + + int renderedObjectCount = 0; + for(bool done = false; done == false;) { + done = true; + for(int idx=0; idx < vctEntity.size(); ++idx) { + // already done, don't waste time + if(entityPendingLookup[idx] == true) { + continue; + } + RenderEntity &entity = vctEntity[idx]; + if(entity.getState() == resInterpolated) { + done = false; + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d\n",__FILE__,__FUNCTION__,__LINE__,idx); + + renderObject(entity,baseFogColor); + entityPendingLookup[idx] = true; + renderedObjectCount++; + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] idx = %d renderedObjectCount = %d\n",__FILE__,__FUNCTION__,__LINE__,idx,renderedObjectCount); + } + else if(entity.getState() == resNone) { + done = false; + } + } + if(done == false) { + sleep(0); + } + } + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] vctEntity.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,vctEntity.size()); +} + +void Renderer::prepareObjectForRender(RenderEntity &entity) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + Object *o = entity.o; + if(o != NULL) { + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + const Model *objModel= o->getModel(); + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(objModel != NULL) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + objModel->updateInterpolationData(0.f, true); + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + entity.setState(resInterpolated); + } + } + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void Renderer::renderObject(RenderEntity &entity,const Vec3f &baseFogColor) { + Object *o = entity.o; + Vec2i &mapPos = entity.mapPos; + if(o != NULL) { + const Model *objModel= o->getModel(); + if(objModel != NULL) { + //objModel->updateInterpolationData(0.f, true); + + const Vec3f &v= o->getConstPos(); + + //ambient and diffuse color is taken from cell color + const World *world= game->getWorld(); + const Texture2D *fowTex= world->getMinimap()->getFowTexture(); + + //!!!float fowFactor= fowTex->getPixmap()->getPixelf(pos.x/Map::cellScale, pos.y/Map::cellScale); + float fowFactor= fowTex->getPixmap()->getPixelf(mapPos.x,mapPos.y); + + Vec4f color= Vec4f(Vec3f(fowFactor), 1.f); + glColor4fv(color.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (color * ambFactor).ptr()); + glFogfv(GL_FOG_COLOR, (baseFogColor * fowFactor).ptr()); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(v.x, v.y, v.z); + glRotatef(o->getRotation(), 0.f, 1.f, 0.f); + + //objModel->updateInterpolationData(0.f, true); + + modelRenderer->render(objModel); + + triangleCount+= objModel->getTriangleCount(); + pointCount+= objModel->getVertexCount(); + + glPopMatrix(); + + entity.setState(resRendered); + } + } } void Renderer::renderWater(){ diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 30723f586..bbd115e29 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -26,6 +26,8 @@ #include "graphics_factory_gl.h" #include "font_manager.h" #include "camera.h" +#include +#include "base_thread.h" namespace Glest{ namespace Game{ @@ -49,6 +51,8 @@ using Shared::Graphics::ParticleSystem; using Shared::Graphics::Pixmap2D; using Shared::Graphics::Camera; +using namespace Shared::PlatformCommon; + //non shared classes class Config; class Game; @@ -57,6 +61,7 @@ class Console; class MenuBackground; class ChatManager; class Texture; +class Object; enum ResourceScope{ rsGlobal, @@ -72,7 +77,96 @@ enum ResourceScope{ /// OpenGL renderer, uses the shared library // =========================================================== -class Renderer{ +enum RenderEntityState { + resNone, + resInterpolated, + resRendered +}; + +class RenderEntity { +protected: + Mutex mutex; + RenderEntityState state; + + void CopyAll(const RenderEntity &obj) { + // Mutex doesn't like being copied.. DON'T do it + // Mutex mutex; + this->state = obj.state; + this->o = obj.o; + this->mapPos = obj.mapPos; + } + +public: + + RenderEntity() { + this->o = NULL; + setState(resNone); + } + RenderEntity(Object *o, Vec2i &mapPos) { + this->o = o; + this->mapPos = mapPos; + setState(resNone); + } + RenderEntity(const RenderEntity &obj) { + CopyAll(obj); + } + RenderEntity & operator=(const RenderEntity &obj) { + CopyAll(obj); + return *this; + } + + Object *o; + Vec2i mapPos; + + RenderEntityState getState() { + RenderEntityState result; + mutex.p(); + result = this->state; + mutex.v(); + + return result; + } + void setState(RenderEntityState value) { + mutex.p(); + this->state = value; + mutex.v(); + } + +}; + +// +// This interface describes the methods a callback object must implement +// +class InterpolateTaskCallbackInterface { +public: + virtual void interpolateTask(std::vector &vctEntity) = 0; +}; + +class InterpolateTaskThread : public BaseThread +{ +protected: + + InterpolateTaskCallbackInterface *interpolateTaskInterface; + + Semaphore semaphoreTaskSignaller; + Mutex mutexTaskSignaller; + bool taskSignalled; + std::vector *vctEntity; + + virtual void setQuitStatus(bool value); + virtual void setRunningStatus(bool value); + void nullEntityList(); + +public: + + InterpolateTaskThread(InterpolateTaskCallbackInterface *interpolateTaskInterface); + virtual void execute(); + void setTaskSignalled(std::vector *vctEntity); + bool getTaskSignalled(); +}; + + +class Renderer : public InterpolateTaskCallbackInterface { public: //progress bar static const int maxProgressBar; @@ -168,7 +262,8 @@ private: //water float waterAnim; - bool allowRotateUnits; + bool allowRotateUnits; + InterpolateTaskThread *interpolateThread; private: Renderer(); @@ -242,6 +337,12 @@ public: //complex rendering void renderSurface(); void renderObjects(); + void renderObject(RenderEntity &entity,const Vec3f &baseFogColor); + void prepareObjectForRender(RenderEntity &entity); + void renderObjectList(std::vector &vctEntity,const Vec3f &baseFogColor); + + virtual void interpolateTask(std::vector &vctEntity); + void renderWater(); void renderUnits(); void renderSelectionEffects(); diff --git a/source/glest_game/main/program.cpp b/source/glest_game/main/program.cpp index e36e35952..249c58eee 100644 --- a/source/glest_game/main/program.cpp +++ b/source/glest_game/main/program.cpp @@ -205,7 +205,7 @@ void Program::loopWorker() { Chrono chrono; chrono.start(); - getWindow()->makeCurrentGl(); + //getWindow()->makeCurrentGl(); //render assert(programState != NULL); diff --git a/source/glest_game/type_instances/object.cpp b/source/glest_game/type_instances/object.cpp index 440856649..57cdf33aa 100644 --- a/source/glest_game/type_instances/object.cpp +++ b/source/glest_game/type_instances/object.cpp @@ -49,7 +49,7 @@ Object::~Object(){ } const Model *Object::getModel() const{ - return objectType==NULL? resource->getType()->getModel(): objectType->getModel(variation); + return objectType==NULL ? (resource != NULL && resource->getType() != NULL ? resource->getType()->getModel() : NULL ) : objectType->getModel(variation); } bool Object::getWalkable() const{ diff --git a/source/glest_game/type_instances/object.h b/source/glest_game/type_instances/object.h new file mode 100644 index 000000000..a77ef8d40 --- /dev/null +++ b/source/glest_game/type_instances/object.h @@ -0,0 +1,60 @@ +// ============================================================== +// This file is part of Glest (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== +#ifndef _GLEST_GAME_OBJECT_H_ +#define _GLEST_GAME_OBJECT_H_ + +#include "model.h" +#include "vec.h" + +namespace Glest{ namespace Game{ + +class ObjectType; +class ResourceType; +class Resource; + +using Shared::Graphics::Model; +using Shared::Graphics::Vec2i; +using Shared::Graphics::Vec3f; + +// ===================================================== +// class Object +// +/// A map object: tree, stone... +// ===================================================== + +class Object{ +private: + ObjectType *objectType; + Resource *resource; + Vec3f pos; + float rotation; + int variation; + +public: + Object(ObjectType *objectType, const Vec3f &pos); + ~Object(); + + void setHeight(float height) {pos.y= height;} + + const ObjectType *getType() const {return objectType;} + Resource *getResource() const {return resource;} + Vec3f getPos() const {return pos;} + const Vec3f & getConstPos() const {return pos;} + float getRotation() {return rotation;} + const Model *getModel() const; + bool getWalkable() const; + + void setResource(const ResourceType *resourceType, const Vec2i &pos); +}; + +}}//end namespace + +#endif diff --git a/source/shared_lib/include/platform/common/base_thread.h b/source/shared_lib/include/platform/common/base_thread.h index 9e8c41cef..0575436ab 100644 --- a/source/shared_lib/include/platform/common/base_thread.h +++ b/source/shared_lib/include/platform/common/base_thread.h @@ -31,19 +31,19 @@ protected: bool quit; bool running; - void setRunningStatus(bool value); - void setQuitStatus(bool value); + virtual void setRunningStatus(bool value); + virtual void setQuitStatus(bool value); public: BaseThread(); ~BaseThread(); virtual void execute()=0; - void signalQuit(); - bool getQuitStatus(); - bool getRunningStatus(); + virtual void signalQuit(); + virtual bool getQuitStatus(); + virtual bool getRunningStatus(); static void shutdownAndWait(BaseThread *ppThread); - void shutdownAndWait(); + virtual void shutdownAndWait(); }; }}//end namespace diff --git a/source/shared_lib/include/platform/sdl/thread.h b/source/shared_lib/include/platform/sdl/thread.h new file mode 100644 index 000000000..a4f31757e --- /dev/null +++ b/source/shared_lib/include/platform/sdl/thread.h @@ -0,0 +1,82 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2005 Matthias Braun +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#ifndef _SHARED_PLATFORM_THREAD_H_ +#define _SHARED_PLATFORM_THREAD_H_ + +#include +#include + +// ===================================================== +// class Thread +// ===================================================== + +namespace Shared{ namespace Platform{ + +class Thread{ +public: + enum Priority { + pIdle = 0, + pLow = 1, + pNormal = 2, + pHigh = 3, + pRealTime = 4 + }; + +private: + SDL_Thread* thread; + +public: + virtual ~Thread() {} + + void start(); + virtual void execute()=0; + void setPriority(Thread::Priority threadPriority); + void suspend(); + void resume(); + +private: + static int beginExecution(void *param); +}; + +// ===================================================== +// class Mutex +// ===================================================== + +class Mutex{ +private: + SDL_mutex* mutex; + +public: + Mutex(); + ~Mutex(); + void p(); + void v(); +}; + +// ===================================================== +// class Semaphore +// ===================================================== + +class Semaphore { +private: + SDL_sem* semaphore; + +public: + Semaphore(Uint32 initialValue = 0); + ~Semaphore(); + void signal(); + int waitTillSignalled(); +}; + +}}//end namespace + +#endif diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index 7698fb004..896ecd276 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -67,7 +67,7 @@ void FileCRCPreCacheThread::execute() { SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInterface, unsigned int executionCount, unsigned int millisecsBetweenExecutions, - bool needTaskSignal) { + bool needTaskSignal) : BaseThread() { this->simpleTaskInterface = simpleTaskInterface; this->executionCount = executionCount; this->millisecsBetweenExecutions = millisecsBetweenExecutions; @@ -79,7 +79,7 @@ void SimpleTaskThread::execute() { try { setRunningStatus(true); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); unsigned int idx = 0; for(;this->simpleTaskInterface != NULL;) { @@ -93,7 +93,7 @@ void SimpleTaskThread::execute() { } if(getQuitStatus() == true) { - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); break; } @@ -108,19 +108,19 @@ void SimpleTaskThread::execute() { } } if(getQuitStatus() == true) { - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); break; } sleep(this->millisecsBetweenExecutions); } - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } catch(const exception &ex) { setRunningStatus(false); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); throw runtime_error(ex.what()); } @@ -128,24 +128,24 @@ void SimpleTaskThread::execute() { } void SimpleTaskThread::setTaskSignalled(bool value) { - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); mutexTaskSignaller.p(); taskSignalled = value; mutexTaskSignaller.v(); - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } bool SimpleTaskThread::getTaskSignalled() { - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); bool retval = false; mutexTaskSignaller.p(); retval = taskSignalled; mutexTaskSignaller.v(); - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); return retval; } diff --git a/source/shared_lib/sources/platform/sdl/thread.cpp b/source/shared_lib/sources/platform/sdl/thread.cpp new file mode 100644 index 000000000..1fae0b76f --- /dev/null +++ b/source/shared_lib/sources/platform/sdl/thread.cpp @@ -0,0 +1,89 @@ +//This file is part of Glest Shared Library (www.glest.org) +//Copyright (C) 2005 Matthias Braun + +//You can redistribute this code and/or modify it under +//the terms of the GNU General Public License as published by the Free Software +//Foundation; either version 2 of the License, or (at your option) any later +//version. + +#include "thread.h" + +#include +#include +#include + +#include "noimpl.h" + +namespace Shared{ namespace Platform{ + +// ===================================== +// Threads +// ===================================== + +void Thread::start() { + thread = SDL_CreateThread(beginExecution, this); +} + +void Thread::setPriority(Thread::Priority threadPriority) { + NOIMPL; +} + +int Thread::beginExecution(void* data) { + Thread* thread = static_cast (data); + thread->execute(); + return 0; +} + +void Thread::suspend() { + NOIMPL; +} + +void Thread::resume() { + NOIMPL; +} + +// ===================================== +// Mutex +// ===================================== + +Mutex::Mutex() { + mutex = SDL_CreateMutex(); + if(mutex == 0) + throw std::runtime_error("Couldn't initialize mutex"); +} + +Mutex::~Mutex() { + SDL_DestroyMutex(mutex); +} + +void Mutex::p() { + SDL_mutexP(mutex); +} + +void Mutex::v() { + SDL_mutexV(mutex); +} + +// ===================================================== +// class Semaphore +// ===================================================== + +Semaphore::Semaphore(Uint32 initialValue) { + semaphore = SDL_CreateSemaphore(initialValue); +} + +Semaphore::~Semaphore() { + SDL_DestroySemaphore(semaphore); + semaphore = NULL; +} + +void Semaphore::signal() { + SDL_SemPost(semaphore); +} + +int Semaphore::waitTillSignalled() { + int semValue = SDL_SemWait(semaphore); + return semValue; +} + +}}//end namespace diff --git a/source/shared_lib/sources/platform/win32/thread.cpp b/source/shared_lib/sources/platform/win32/thread.cpp new file mode 100644 index 000000000..907542b59 --- /dev/null +++ b/source/shared_lib/sources/platform/win32/thread.cpp @@ -0,0 +1,88 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2001-2008 Martio Figueroa +// +// You can redistribute this code and/or modify it under +// the terms of the GNU General Public License as published +// by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version +// ============================================================== + +#include "thread.h" + +#include "leak_dumper.h" + +namespace Shared{ namespace Platform{ + +// ===================================================== +// class Threads +// ===================================================== + +ThreadId Thread::nextThreadId= threadIdBase; + +void Thread::start(){ + threadHandle= CreateThread(NULL, 0, beginExecution, this, 0, &nextThreadId); + nextThreadId++; +} + +void Thread::setPriority(Thread::Priority threadPriority){ + SetThreadPriority(threadHandle, threadPriority); +} + +DWORD WINAPI Thread::beginExecution(void *param){ + static_cast(param)->execute(); + return 0; +} + +void Thread::suspend(){ + SuspendThread(threadHandle); +} + +void Thread::resume(){ + ResumeThread(threadHandle); +} + +// ===================================================== +// class Mutex +// ===================================================== + +Mutex::Mutex(){ + InitializeCriticalSection(&mutex); +} + +Mutex::~Mutex(){ + DeleteCriticalSection(&mutex); +} + +void Mutex::p(){ + EnterCriticalSection(&mutex); +} + +void Mutex::v(){ + LeaveCriticalSection(&mutex); +} + +// ===================================================== +// class Semaphore +// ===================================================== + +Semaphore::Semaphore(Uint32 initialValue) { + semaphore = SDL_CreateSemaphore(initialValue); +} + +Semaphore::~Semaphore() { + SDL_DestroySemaphore(semaphore); + semaphore = NULL; +} + +void Semaphore::signal() { + SDL_SemPost(semaphore); +} + +int Semaphore::waitTillSignalled() { + int semValue = SDL_SemWait(semaphore); + return semValue; +} + +}}//end namespace