This commit is contained in:
Vladislav Khorev 2013-02-03 13:11:16 +00:00
parent a8e01ed69d
commit c9b7f21be5
11 changed files with 228 additions and 13 deletions

View File

@ -55,6 +55,8 @@
<ClInclude Include="..\include\Utils\FileUtils\FileUtils.h" />
<ClInclude Include="..\include\Utils\PngHelper.h" />
<ClInclude Include="..\include\Utils\SerializeInterface\SerializeInterface.h" />
<ClInclude Include="..\include\Utils\ThreadUtils.h" />
<ClInclude Include="..\include\Utils\ThreadUtilsImpl.h" />
<ClInclude Include="..\include\Utils\Utils.h" />
<ClInclude Include="..\include\Utils\WinApi\WinApi.h" />
</ItemGroup>
@ -96,6 +98,7 @@
<ClCompile Include="..\src\Utils\PngHelper.cpp" />
<ClCompile Include="..\src\Utils\SerializeInterface\SerializeInterface.cpp" />
<ClCompile Include="..\src\Utils\SimpleTimer.cpp" />
<ClCompile Include="..\src\Utils\ThreadUtils.cpp" />
<ClCompile Include="..\src\Utils\WinApi\WinApi.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">

View File

@ -56,6 +56,13 @@ protected:
public:
std::string PathToResources;
boost::thread::id MainThreadId;
std::vector<boost::function<void()>> MainThreadAsyncFunctionArr;
boost::mutex FuncListMutex;
std::list<TFuncToPerform> MainThreadSyncFunctionList;
TTextureListClass TexList;
TModelManager ModelManager;
TFlexModelManager FlexModelManager;
@ -79,7 +86,9 @@ public:
TSoundManagerIos SoundManager;
#endif
~TResourceManager() { }
void Update(cardinal timer);
~TResourceManager();
};

View File

@ -65,4 +65,6 @@ int MainLoop(TApplication& application);
//This file includes templates that call any of three singletones: Console, ResourceManager or Renderer
#include "include/GUIManager/WidgetTemplatesImpl.h"
#include "include/Utils/ThreadUtilsImpl.h"

View File

@ -58,12 +58,14 @@ protected:
bool CreateTexDataFromBmp32(const std::string& filename, TTextureData& texData);
bool CreateTexDataFromTga(const std::string& filename, TTextureData& texData);
bool CreateTexDataFromPng(const std::string& filename, TTextureData& texData);
cardinal AddTextureBmp24Data(const TTextureData& texData);
cardinal AddTextureBmp32Data(const TTextureData& texData);
cardinal AddCubemapTextureBmp24Data(TTextureData* texData);
//cardinal AddCubemapTextureBmp32Data(TTextureData* texData); Not implemented yet
void InnerClear();
public:
TTextureListClass();
~TTextureListClass();
@ -84,7 +86,8 @@ public:
cardinal GetTextureWidth(const std::string& texName);
cardinal AddTextureDirectly(const std::string& filename, std::string texName = ""); //Loads texture directly from this file or fails
cardinal AddTexture(const std::string& fileName, std::string texName = ""); //Adds path to resources to the filename then call previous one
cardinal AddTexture(const std::string& fileName);
cardinal AddTexture(const std::string& fileName, std::string texName); //Adds path to resources to the filename then call previous one
cardinal AddTextureFromUserdata(const std::string& fileName, std::string texName = ""); //Same as above but checks if file is created in user data
cardinal AddCubemapTexture(std::string filename[6]); // "posx.bmp","negx.bmp","posy.bmp","negy.bmp","posz.bmp","negz.bmp"

View File

@ -0,0 +1,36 @@
#ifndef THREAD_UTILS_H_INCLUDED
#define THREAD_UTILS_H_INCLUDED
#include "boost/signal.hpp"
#include "boost/thread.hpp"
namespace SE
{
struct TFuncToPerform
{
private:
public:
TFuncToPerform()
: LockerPtr(new boost::mutex)
{
}
bool Executed;
std::shared_ptr<boost::mutex> LockerPtr;
boost::function<void()> Func;
};
void AssertIfInMainThread();
void PerformInMainThreadAsync(boost::function<void()> f);
template<typename RETURNTYPE>
RETURNTYPE PerformInMainThread(boost::function<RETURNTYPE()> f);
} //namespace SE
#endif

View File

@ -0,0 +1,65 @@
#ifndef THREAD_UTILS_IMPL_H_INCLUDED
#define THREAD_UTILS_IMPL_H_INCLUDED
#include "include/Engine.h"
namespace SE
{
template<typename RETURNTYPE>
struct TCoverFunc
{
public:
typedef void result_type;
boost::function<RETURNTYPE()> Func;
void operator()(RETURNTYPE& rx)
{
rx = Func();
}
};
template<typename RETURNTYPE>
RETURNTYPE PerformInMainThread(boost::function<RETURNTYPE()> f)
{
if (boost::this_thread::get_id() == ResourceManager->MainThreadId)
{
return f();
}
else
{
RETURNTYPE result;
TCoverFunc<RETURNTYPE> cover_f;
cover_f.Func = f;
TFuncToPerform funcToPerform;
funcToPerform.Executed = false;
funcToPerform.Func = boost::bind(cover_f, boost::ref(result));
funcToPerform.LockerPtr->lock();
ResourceManager->FuncListMutex.lock();
auto itr = ResourceManager->MainThreadSyncFunctionList.insert(ResourceManager->MainThreadSyncFunctionList.end(), funcToPerform);
ResourceManager->FuncListMutex.unlock();
itr->LockerPtr->lock(); //wait until lock will be released
itr->LockerPtr->unlock();
ResourceManager->FuncListMutex.lock();
ResourceManager->MainThreadSyncFunctionList.erase(itr);
ResourceManager->FuncListMutex.unlock();
return result;
}
}
} //namespace SE
#endif

View File

@ -25,6 +25,7 @@ This code combines additional routines (such as console/log, exceptions, math ut
#include "include/Utils/BindableVar.h"
#include "include/Utils/SimpleTimer.h"
#include "include/Utils/ThreadUtils.h"
#ifdef TARGET_WIN32
#include "WinApi/WinApi.h"

View File

@ -11,6 +11,8 @@ TApplicationInterface::TApplicationInterface()
void TApplicationInterface::OuterInit(int screenWidth, int screenHeight, float matrixWidth, float matrixHeight)
{
ResourceManager->MainThreadId = boost::this_thread::get_id();
ResourceManager->ScriptManager.BindBasicFunctions();
Renderer->InitOpenGL(screenWidth, screenHeight, matrixWidth, matrixHeight);

View File

@ -21,6 +21,46 @@ TSalmonRendererIos* Renderer;
TResourceManager* ResourceManager;
void TResourceManager::Update(cardinal timer)
{
FuncListMutex.lock();
SoundManager.Update(timer);
GUIManager.Update(timer);
if (MainThreadAsyncFunctionArr.size() != 0)
{
MainThreadAsyncFunctionArr[0]();
MainThreadAsyncFunctionArr.erase(MainThreadAsyncFunctionArr.begin());
}
auto itr = MainThreadSyncFunctionList.begin();
while (itr != MainThreadSyncFunctionList.end() && itr->Executed)
{
itr++;
}
if (itr != MainThreadSyncFunctionList.end())
{
itr->Func();
itr->Executed = true;
itr->LockerPtr->unlock();
}
FuncListMutex.unlock();
}
TResourceManager::~TResourceManager()
{
}
TApplicationAncestor::TApplicationAncestor()
{
@ -63,9 +103,7 @@ void TApplicationAncestor::OuterDraw()
void TApplicationAncestor::OuterUpdate(cardinal timer)
{
ResourceManager->SoundManager.Update(timer);
ResourceManager->GUIManager.Update(timer);
ResourceManager->Update(timer);
InnerUpdate(timer);

View File

@ -37,6 +37,13 @@ TTextureListClass::~TTextureListClass()
void TTextureListClass::Clear()
{
PerformInMainThreadAsync(boost::bind(&TTextureListClass::InnerClear, this));
}
void TTextureListClass::InnerClear()
{
AssertIfInMainThread();
if (TexMap.size() != 0)
{
@ -50,7 +57,6 @@ void TTextureListClass::Clear()
*Console<<"ResourceManager::TexList cleared";
}
}
void TTextureListClass::Serialize(boost::property_tree::ptree& propertyTree)
@ -397,7 +403,7 @@ bool TTextureListClass::CreateTexDataFromPng(const std::string& filename, TTextu
cardinal TTextureListClass::AddTextureBmp24Data(const TTextureData& texData)
{
AssertIfInMainThread();
cardinal TexID = 0;
@ -424,6 +430,8 @@ cardinal TTextureListClass::AddTextureBmp24Data(const TTextureData& texData)
cardinal TTextureListClass::AddTextureBmp32Data(const TTextureData& texData)
{
AssertIfInMainThread();
cardinal TexID;
glGenTextures(1, &TexID);
if (TexID == 0)
@ -448,6 +456,8 @@ cardinal TTextureListClass::AddTextureBmp32Data(const TTextureData& texData)
cardinal TTextureListClass::AddCubemapTextureBmp24Data(TTextureData* texData)
{
AssertIfInMainThread();
cardinal TexID;
glGenTextures(1, &TexID);
glBindTexture(GL_TEXTURE_CUBE_MAP, TexID);
@ -492,6 +502,7 @@ cardinal TTextureListClass::GetTextureWidth(const std::string& texName)
cardinal TTextureListClass::AddTextureDirectly(const std::string& filename, std::string texName)
{
AssertIfInMainThread();
cardinal TexID;
@ -545,12 +556,18 @@ cardinal TTextureListClass::AddTextureDirectly(const std::string& filename, std:
}
cardinal TTextureListClass::AddTexture(const std::string& fileName)
{
return AddTexture(fileName, "");
}
cardinal TTextureListClass::AddTexture(const std::string& fileName, std::string texName)
{
std::string fullFileName = ResourceManager->PathToResources + fileName;
return AddTextureDirectly(fullFileName, texName);
boost::function<cardinal()> f = boost::bind(&TTextureListClass::AddTextureDirectly, this, fullFileName, texName);
return PerformInMainThread<cardinal>(f);
}
@ -565,13 +582,16 @@ cardinal TTextureListClass::AddTextureFromUserdata(const std::string& fileName,
std::string fullFileName = GetFilePathUserData(fileName);
return AddTextureDirectly(fullFileName.c_str(), texName);
boost::function<cardinal()> f = boost::bind(&TTextureListClass::AddTextureDirectly, this, fullFileName, texName);
return PerformInMainThread<cardinal>(f);
}
cardinal TTextureListClass::AddCubemapTexture(std::string filename[6])
{
AssertIfInMainThread();
filename[0] = ResourceManager->PathToResources + filename[0];
filename[1] = ResourceManager->PathToResources + filename[1];
@ -643,6 +663,8 @@ cardinal TTextureListClass::AddCubemapTexture(std::string filename[6])
cardinal TTextureListClass::AddEmptyTexture(const std::string& texName,cardinal width,cardinal height)
{
AssertIfInMainThread();
cardinal texID;
if (TexMap.count(texName) == 0)
@ -680,6 +702,8 @@ cardinal TTextureListClass::AddEmptyTexture(const std::string& texName,cardinal
cardinal TTextureListClass::AddEmptyCubemapTexture(const std::string& texName,cardinal width,cardinal height)
{
AssertIfInMainThread();
cardinal texID;
if (TexMap.count(texName) == 0)
@ -734,6 +758,8 @@ cardinal TTextureListClass::AddEmptyCubemapTexture(const std::string& texName,ca
cardinal TTextureListClass::AddDepthTexture(const std::string& texName,cardinal width,cardinal height)
{
AssertIfInMainThread();
#ifdef TARGET_WIN32
cardinal texID;
@ -783,6 +809,8 @@ cardinal TTextureListClass::AddDepthTexture(const std::string& texName,cardinal
void TTextureListClass::DeleteTexture(const std::string& texName)
{
AssertIfInMainThread();
if (TexMap.count(texName) != 0)
{
--TexMap[texName].RefCount;
@ -801,6 +829,8 @@ void TTextureListClass::DeleteTexture(const std::string& texName)
void TTextureListClass::DeleteTexture(cardinal texID)
{
AssertIfInMainThread();
TTextureMap::iterator i = TexMap.begin();
while (i != TexMap.end())

26
src/Utils/ThreadUtils.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "include/Engine.h"
namespace SE
{
void AssertIfInMainThread()
{
if (boost::this_thread::get_id() != ResourceManager->MainThreadId)
{
throw ErrorToLog("ERROR! AssertIfInMainThread failed!");
}
}
void PerformInMainThreadAsync(boost::function<void()> f)
{
if (boost::this_thread::get_id() == ResourceManager->MainThreadId)
{
f();
}
else
{
ResourceManager->MainThreadAsyncFunctionArr.push_back(f);
}
}
} //namespace SE