diff options
Diffstat (limited to 'src')
27 files changed, 358 insertions, 37 deletions
diff --git a/src/common/event.h b/src/common/event.h index 0d9aa7c..54086d4 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -19,8 +19,8 @@ #pragma once -#include "common/key.h" -#include "math/point.h" +#include <common/key.h> +#include <math/point.h> #include <string.h> diff --git a/src/common/iman.h b/src/common/iman.h index 38e5f37..89b5206 100644 --- a/src/common/iman.h +++ b/src/common/iman.h @@ -18,8 +18,8 @@ #pragma once -#include "common/singleton.h" -#include "common/misc.h" +#include <common/singleton.h> +#include <common/misc.h> diff --git a/src/common/logger.cpp b/src/common/logger.cpp index a0dcca0..be73ec7 100644 --- a/src/common/logger.cpp +++ b/src/common/logger.cpp @@ -24,20 +24,6 @@ template<> CLogger* CSingleton<CLogger>::mInstance = nullptr; -CLogger& CLogger::GetInstance() -{ - assert(mInstance); - return *mInstance; -} - - -CLogger* CLogger::GetInstancePointer() -{ - assert(mInstance); - return mInstance; -} - - CLogger::CLogger() { mFile = NULL; diff --git a/src/common/logger.h b/src/common/logger.h index 2d0ab3e..4febff0 100644 --- a/src/common/logger.h +++ b/src/common/logger.h @@ -91,9 +91,6 @@ class CLogger : public CSingleton<CLogger> */ void SetLogLevel(LogType level); - static CLogger& GetInstance(); - static CLogger* GetInstancePointer(); - private: std::string mFilename; FILE *mFile; diff --git a/src/common/profile.cpp b/src/common/profile.cpp index 467e991..29a68e1 100644 --- a/src/common/profile.cpp +++ b/src/common/profile.cpp @@ -27,6 +27,7 @@ CProfile::CProfile() { m_ini = new CSimpleIniA(); m_ini->SetUnicode(); + m_ini->SetMultiKey(); } @@ -39,8 +40,8 @@ CProfile::~CProfile() bool CProfile::InitCurrentDirectory() { - m_ini->LoadFile("colobot.ini"); - return true; + bool result = m_ini->LoadFile("colobot.ini") == SI_OK; + return result; } @@ -86,3 +87,19 @@ bool CProfile::GetLocalProfileFloat(std::string section, std::string key, float value = m_ini->GetDoubleValue(section.c_str(), key.c_str(), 0.0d); return true; } + + +std::vector< std::string > CProfile::GetLocalProfileSection(std::string section, std::string key) +{ + std::vector< std::string > ret_list; + + CSimpleIniA::TNamesDepend values; + m_ini->GetAllValues(section.c_str(), key.c_str(), values); + values.sort(CSimpleIniA::Entry::LoadOrder()); + + for (auto item : values) { + ret_list.push_back(item.pItem); + } + + return ret_list; +} diff --git a/src/common/profile.h b/src/common/profile.h index ae67e52..0886522 100644 --- a/src/common/profile.h +++ b/src/common/profile.h @@ -19,31 +19,96 @@ #pragma once #include <cstdlib> +#include <vector> +#include <utility> #include <lib/simpleini/SimpleIni.h> #include <common/singleton.h> +/** + * @file common/profile.h + * @brief Class for loading profile (currently for loading ini config file) + */ + +/** +* @class CProfile +* +* @brief Class for loading profile (currently for loading ini config file) +* +*/ class CProfile : public CSingleton<CProfile> { public: CProfile(); ~CProfile(); + /** Loads colobot.ini from current directory + * @return return true on success + */ bool InitCurrentDirectory(); + + /** Sets string value in section under specified key + * @param std::string section + * @param std::string key + * @param std::string value + * @return return true on success + */ bool SetLocalProfileString(std::string section, std::string key, std::string value); + + /** Gets string value in section under specified key + * @param std::string section + * @param std::string key + * @param std::string& buffer + * @return return true on success + */ bool GetLocalProfileString(std::string section, std::string key, std::string& buffer); + /** Sets int value in section under specified key + * @param std::string section + * @param std::string key + * @param int value + * @return return true on success + */ bool SetLocalProfileInt(std::string section, std::string key, int value); + + /** Gets int value in section under specified key + * @param std::string section + * @param std::string key + * @param int& value + * @return return true on success + */ bool GetLocalProfileInt(std::string section, std::string key, int &value); + /** Sets float value in section under specified key + * @param std::string section + * @param std::string key + * @param float value + * @return return true on success + */ bool SetLocalProfileFloat(std::string section, std::string key, float value); + + /** Gets float value in section under specified key + * @param std::string section + * @param std::string key + * @param float& value + * @return return true on success + */ bool GetLocalProfileFloat(std::string section, std::string key, float &value); - static CProfile& GetInstance(); - static CProfile* GetInstancePointer(); + /** Gets all values in section under specified key + * @param std::string section + * @param std::string key + * @return vector of values + */ + std::vector< std::string > GetLocalProfileSection(std::string section, std::string key); private: CSimpleIniA *m_ini; }; + +//! Global function to get profile instance +inline CProfile* GetProfile() { + return CProfile::GetInstancePointer(); +} diff --git a/src/common/test/CMakeLists.txt b/src/common/test/CMakeLists.txt index 3adca4e..d81acab 100644 --- a/src/common/test/CMakeLists.txt +++ b/src/common/test/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0 -std=c++11") include_directories("../../") include_directories("../../../") -#add_executable(image_test ../image.cpp image_test.cpp) +add_executable(image_test ../image.cpp image_test.cpp) add_executable(profile_test ../profile.cpp profile_test.cpp) add_test(profile_test ./profile_test) diff --git a/src/common/test/colobot.ini b/src/common/test/colobot.ini index c4d2162..f6a5f96 100644 --- a/src/common/test/colobot.ini +++ b/src/common/test/colobot.ini @@ -6,3 +6,10 @@ string_value=Hello world [test_int] int_value=42 + +[test_multi] +entry=1 +entry=2 +entry=3 +entry=4 +entry=5 diff --git a/src/common/test/profile_test.cpp b/src/common/test/profile_test.cpp index 3ba0fad..65e20c5 100644 --- a/src/common/test/profile_test.cpp +++ b/src/common/test/profile_test.cpp @@ -2,6 +2,7 @@ #include <iostream> #include <string> +#include <vector> using namespace std; @@ -31,5 +32,12 @@ int main() return 1; } + vector<string> list; + list = profile.GetLocalProfileSection("test_multi", "entry"); + if (list.size() != 5) { + cout << "GetLocalProfileSection failed!" << endl; + return 1; + } + return 0; } diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index fb68152..668be87 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -722,7 +722,7 @@ CRobotMain::CRobotMain(CInstanceManager* iMan) g_unit = 4.0f; m_gamerName[0] = 0; - GetLocalProfileString("Gamer", "LastName", m_gamerName, 100); + GetProfile()->GetLocalProfileString("Gamer", "LastName", m_gamerName, 100); SetGlobalGamerName(m_gamerName); ReadFreeParam(); m_dialog->SetupRecall(); diff --git a/src/plugins/pluginloader.cpp b/src/plugins/pluginloader.cpp index 337c0ce..8893b56 100644 --- a/src/plugins/pluginloader.cpp +++ b/src/plugins/pluginloader.cpp @@ -95,3 +95,21 @@ bool CPluginLoader::LoadPlugin() mLoaded = true; return true; } + + +bool CPluginLoader::SetFilename(std::string filename) +{ + bool ok = true; + if (mLoaded) + ok = UnloadPlugin(); + + if (ok) + mFilename = filename; + return ok; +} + + +std::string CPluginLoader::GetFilename() +{ + return mFilename; +} diff --git a/src/plugins/pluginloader.h b/src/plugins/pluginloader.h index d9ee041..873d30a 100644 --- a/src/plugins/pluginloader.h +++ b/src/plugins/pluginloader.h @@ -29,14 +29,16 @@ class CPluginLoader { public: - CPluginLoader(std::string filename); - + CPluginLoader(std::string); + char* GetName(); int GetVersion(); bool UnloadPlugin(); bool LoadPlugin(); bool IsLoaded(); - + bool SetFilename(std::string); + std::string GetFilename(); + private: CPluginInterface* mInterface; diff --git a/src/plugins/pluginmanager.cpp b/src/plugins/pluginmanager.cpp new file mode 100644 index 0000000..ab9d8ad --- /dev/null +++ b/src/plugins/pluginmanager.cpp @@ -0,0 +1,122 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// pluginmanager.cpp + + +#include "pluginmanager.h" + + +template<> CPluginManager* CSingleton<CPluginManager>::mInstance = nullptr; + + +CPluginManager::CPluginManager() +{ + lt_dlinit(); +} + + +CPluginManager::~CPluginManager() +{ + UnloadAllPlugins(); + lt_dlexit(); +} + + + +void CPluginManager::LoadFromProfile() +{ + std::vector< std::string > dirs = GetProfile()->GetLocalProfileSection("Plugins", "Path"); + std::vector< std::string > plugins = GetProfile()->GetLocalProfileSection("Plugins", "File"); + + for (std::string dir : dirs) + m_folders.insert(dir); + + for (std::string plugin : plugins) { + GetLogger()->Info("Trying to load plugin %s...\n", plugin.c_str()); + LoadPlugin(plugin); + } +} + + +bool CPluginManager::LoadPlugin(std::string filename) +{ + bool result = false; + CPluginLoader *loader = new CPluginLoader(""); + for (std::string dir : m_folders) { + loader->SetFilename(dir + "/" + filename); + result = loader->LoadPlugin(); + if (result) { + GetLogger()->Info("Plugin %s (%s) version %0.2f loaded!\n", filename.c_str(), loader->GetName(), loader->GetVersion() / 100.0f); + m_plugins.push_back(loader); + break; + } + } + return result; +} + + +bool CPluginManager::UnloadPlugin(std::string filename) +{ + std::vector<CPluginLoader *>::iterator it; + GetLogger()->Info("Trying to unload plugin %s...\n", filename.c_str()); + for (it = m_plugins.begin(); it != m_plugins.end(); it++) { + CPluginLoader *plugin = *it; + if (NameEndsWith(plugin->GetFilename(), filename)) { + m_plugins.erase(it); + plugin->UnloadPlugin(); + delete plugin; + return true; + } + } + return false; +} + + +bool CPluginManager::AddSearchDirectory(std::string dir) +{ + m_folders.insert(dir); + return true; +} + + +bool CPluginManager::RemoveSearchDirectory(std::string dir) +{ + m_folders.erase(dir); + return false; +} + + +bool CPluginManager::UnloadAllPlugins() +{ + for (CPluginLoader *plugin : m_plugins) { + GetLogger()->Info("Trying to unload plugin %s (%s)...\n", plugin->GetFilename().c_str(), plugin->GetName()); + plugin->UnloadPlugin(); + delete plugin; + } + m_plugins.clear(); + return true; +} + + +bool CPluginManager::NameEndsWith(std::string filename, std::string ending) +{ + if (filename.length() > ending.length()) { + std::string fileEnd = filename.substr(filename.length() - ending.length()); + return (fileEnd == ending); + } + return false; +} diff --git a/src/plugins/pluginmanager.h b/src/plugins/pluginmanager.h new file mode 100644 index 0000000..d267238 --- /dev/null +++ b/src/plugins/pluginmanager.h @@ -0,0 +1,55 @@ +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// pluginmanager.h + + +#pragma once + +#include <string> +#include <set> +#include <vector> + +#include <common/logger.h> +#include <common/profile.h> + +#include <common/singleton.h> + +#include "pluginloader.h" + + +class CPluginManager : public CSingleton<CPluginManager> { + public: + CPluginManager(); + ~CPluginManager(); + + void LoadFromProfile(); + + bool LoadPlugin(std::string); + bool UnloadPlugin(std::string); + + bool AddSearchDirectory(std::string); + bool RemoveSearchDirectory(std::string); + + bool UnloadAllPlugins(); + + private: + bool NameEndsWith(std::string, std::string); + + std::set< std::string > m_folders; + std::vector<CPluginLoader *> m_plugins; +}; + diff --git a/src/plugins/test/CMakeLists.txt b/src/plugins/test/CMakeLists.txt index cd4e6be..5f86b6f 100644 --- a/src/plugins/test/CMakeLists.txt +++ b/src/plugins/test/CMakeLists.txt @@ -3,8 +3,10 @@ cmake_minimum_required(VERSION 2.8) set(CMAKE_BUILD_TYPE debug) set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0 -std=c++11 -rdynamic") -add_executable(plugin_test plugin_test.cpp ../../common/iman.cpp ../../common/logger.cpp ../pluginloader.cpp) +add_executable(manager_test manager_test.cpp ../../common/logger.cpp ../../common/profile.cpp ../../common/iman.cpp ../pluginmanager.cpp ../pluginloader.cpp) +include_directories(".") include_directories("../../") +include_directories("../../../") -target_link_libraries(plugin_test ltdl) +target_link_libraries(manager_test ltdl) diff --git a/src/plugins/test/colobot.ini b/src/plugins/test/colobot.ini new file mode 100644 index 0000000..08956be --- /dev/null +++ b/src/plugins/test/colobot.ini @@ -0,0 +1,3 @@ +[Plugins] +Path=. +File=libopenalsound.so diff --git a/src/plugins/test/manager_test.cpp b/src/plugins/test/manager_test.cpp new file mode 100644 index 0000000..9b3f472 --- /dev/null +++ b/src/plugins/test/manager_test.cpp @@ -0,0 +1,24 @@ +#include <common/logger.h> +#include <common/profile.h> +#include <common/iman.h> +#include <plugins/pluginmanager.h> +#include <sound/sound.h> + + +int main() { + new CLogger(); + new CProfile(); + new CInstanceManager(); + CPluginManager *mgr = new CPluginManager(); + + if (!GetProfile()->InitCurrentDirectory()) { + GetLogger()->Error("Config not found!\n"); + return 1; + } + mgr->LoadFromProfile(); + CSoundInterface *sound = static_cast<CSoundInterface*>(CInstanceManager::GetInstancePointer()->SearchInstance(CLASS_SOUND)); + sound->Create(true); + mgr->UnloadAllPlugins(); + + return 0; +} diff --git a/src/plugins/sound/oalsound/CMakeLists.txt b/src/sound/plugins/oalsound/CMakeLists.txt index e36f3ac..e36f3ac 100644 --- a/src/plugins/sound/oalsound/CMakeLists.txt +++ b/src/sound/plugins/oalsound/CMakeLists.txt diff --git a/src/plugins/sound/oalsound/alsound.cpp b/src/sound/plugins/oalsound/alsound.cpp index 19da66a..a1d4801 100644 --- a/src/plugins/sound/oalsound/alsound.cpp +++ b/src/sound/plugins/oalsound/alsound.cpp @@ -41,13 +41,17 @@ int ALSound::PluginVersion() void ALSound::InstallPlugin()
{
- CInstanceManager::GetInstancePointer()->AddInstance(CLASS_SOUND, this);
+ auto pointer = CInstanceManager::GetInstancePointer();
+ if (pointer != nullptr)
+ CInstanceManager::GetInstancePointer()->AddInstance(CLASS_SOUND, this);
}
void ALSound::UninstallPlugin()
{
- CInstanceManager::GetInstancePointer()->DeleteInstance(CLASS_SOUND, this);
+ auto pointer = CInstanceManager::GetInstancePointer();
+ if (pointer != nullptr)
+ CInstanceManager::GetInstancePointer()->DeleteInstance(CLASS_SOUND, this);
CleanUp();
}
diff --git a/src/plugins/sound/oalsound/alsound.h b/src/sound/plugins/oalsound/alsound.h index 6d4e5b6..9265e2c 100644 --- a/src/plugins/sound/oalsound/alsound.h +++ b/src/sound/plugins/oalsound/alsound.h @@ -78,7 +78,7 @@ class ALSound : public CSoundInterface int PluginVersion();
void InstallPlugin();
void UninstallPlugin();
-
+
private:
void CleanUp();
int RetPriority(Sound);
diff --git a/src/plugins/sound/oalsound/buffer.cpp b/src/sound/plugins/oalsound/buffer.cpp index 37211e9..37211e9 100644 --- a/src/plugins/sound/oalsound/buffer.cpp +++ b/src/sound/plugins/oalsound/buffer.cpp diff --git a/src/plugins/sound/oalsound/buffer.h b/src/sound/plugins/oalsound/buffer.h index 6eefe72..6eefe72 100644 --- a/src/plugins/sound/oalsound/buffer.h +++ b/src/sound/plugins/oalsound/buffer.h diff --git a/src/plugins/sound/oalsound/channel.cpp b/src/sound/plugins/oalsound/channel.cpp index 4476dee..4476dee 100644 --- a/src/plugins/sound/oalsound/channel.cpp +++ b/src/sound/plugins/oalsound/channel.cpp diff --git a/src/plugins/sound/oalsound/channel.h b/src/sound/plugins/oalsound/channel.h index 3099931..3099931 100644 --- a/src/plugins/sound/oalsound/channel.h +++ b/src/sound/plugins/oalsound/channel.h diff --git a/src/plugins/sound/oalsound/check.h b/src/sound/plugins/oalsound/check.h index cb6b4a1..cb6b4a1 100644 --- a/src/plugins/sound/oalsound/check.h +++ b/src/sound/plugins/oalsound/check.h diff --git a/src/sound/plugins/oalsound/test/CMakeLists.txt b/src/sound/plugins/oalsound/test/CMakeLists.txt new file mode 100644 index 0000000..d10169b --- /dev/null +++ b/src/sound/plugins/oalsound/test/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.8) + +set(CMAKE_BUILD_TYPE debug) +set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0 -std=c++11 -rdynamic") + +add_executable(plugin_test plugin_test.cpp ../../../../common/iman.cpp ../../../../common/logger.cpp ../../../../plugins/pluginloader.cpp) + +include_directories(".") +include_directories("../../../../") + +target_link_libraries(plugin_test ltdl) diff --git a/src/plugins/test/plugin_test.cpp b/src/sound/plugins/oalsound/test/plugin_test.cpp index 9aadfac..40c1cd2 100644 --- a/src/plugins/test/plugin_test.cpp +++ b/src/sound/plugins/oalsound/test/plugin_test.cpp @@ -22,7 +22,7 @@ int main() { sound->CacheAll(); sound->Play((Sound)8); sound->Play((Sound)18); - + sleep(10); /* while (1) @@ -34,7 +34,7 @@ int main() { }*/ plugin->UnloadPlugin(); } - + lt_dlexit(); return 0; } |