diff options
-rw-r--r-- | src/common/iman.cpp | 15 | ||||
-rw-r--r-- | src/common/iman.h | 6 | ||||
-rw-r--r-- | src/plugins/plugin.cpp | 97 | ||||
-rw-r--r-- | src/plugins/plugin.h | 25 | ||||
-rw-r--r-- | src/plugins/plugininterface.h | 37 | ||||
-rw-r--r-- | src/plugins/sound/oalsound/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/plugins/sound/oalsound/alsound.cpp | 20 | ||||
-rw-r--r-- | src/plugins/sound/oalsound/alsound.h | 2 | ||||
-rw-r--r-- | src/plugins/test/CMakeLists.txt | 11 | ||||
-rw-r--r-- | src/plugins/test/plugin_test.cpp | 40 | ||||
-rw-r--r-- | src/sound/sound.h | 9 |
11 files changed, 246 insertions, 19 deletions
diff --git a/src/common/iman.cpp b/src/common/iman.cpp index 28ee3d3..9e94f24 100644 --- a/src/common/iman.cpp +++ b/src/common/iman.cpp @@ -23,6 +23,21 @@ #include "common/iman.h" +template<> CInstanceManager* CSingleton<CInstanceManager>::mInstance = 0; + + +CInstanceManager& CInstanceManager::GetInstance() +{ + assert(mInstance); + return *mInstance; +} + + +CInstanceManager* CInstanceManager::GetInstancePointer() +{ + assert(mInstance); + return mInstance; +} // Object's constructor. diff --git a/src/common/iman.h b/src/common/iman.h index 7a7b499..38e5f37 100644 --- a/src/common/iman.h +++ b/src/common/iman.h @@ -18,7 +18,7 @@ #pragma once - +#include "common/singleton.h" #include "common/misc.h" @@ -32,7 +32,7 @@ struct BaseClass -class CInstanceManager +class CInstanceManager : public CSingleton<CInstanceManager> { public: CInstanceManager(); @@ -44,6 +44,8 @@ public: bool DeleteInstance(ClassType classType, void* pointer); void* SearchInstance(ClassType classType, int rank=0); + static CInstanceManager& GetInstance(); + static CInstanceManager* GetInstancePointer(); protected: void Compress(ClassType classType); diff --git a/src/plugins/plugin.cpp b/src/plugins/plugin.cpp new file mode 100644 index 0000000..ca0fe0e --- /dev/null +++ b/src/plugins/plugin.cpp @@ -0,0 +1,97 @@ +// * 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/. + +// plugin.cpp + + +#include "plugin.h" + + +CPlugin::CPlugin(std::string filename) +{ + mInterface = nullptr; + mFilename = filename; + mLoaded = false; +} + + +char* CPlugin::GetName() +{ + if (mLoaded) + return mInterface->PluginName(); + return nullptr; +} + + +int CPlugin::GetVersion() +{ + if (mLoaded) + return mInterface->PluginVersion(); + return 0; +} + + +bool CPlugin::IsLoaded() +{ + return mLoaded; +} + + +bool CPlugin::UnloadPlugin() +{ + if (!mLoaded) { + GetLogger()->Warn("Plugin %s is not loaded.\n"); + return true; + } + + void (*uninstall)() = (void (*)()) lt_dlsym(mHandle, "UninstallPluginEntry"); + if (!uninstall) { + GetLogger()->Error("Error getting UninstallPluginEntry for plugin %s: %s\n", mFilename.c_str(), lt_dlerror()); + return false; + } + + lt_dlclose(mHandle); + mLoaded = false; + return true; +} + + +bool CPlugin::LoadPlugin() +{ + mHandle = lt_dlopenext(mFilename.c_str()); + if (!mHandle) { + GetLogger()->Error("Error loading plugin %s: %s\n", mFilename.c_str(), lt_dlerror()); + return false; + } + + void (*install)() = (void (*)()) lt_dlsym(mHandle, "InstallPluginEntry"); + if (!install) { + GetLogger()->Error("Error getting InstallPluginEntry for plugin %s: %s\n", mFilename.c_str(), lt_dlerror()); + return false; + } + + CPluginInterface* (*getInterface)() = (CPluginInterface* (*)()) lt_dlsym(mHandle, "GetPluginInterfaceEntry"); + + if (!getInterface) { + GetLogger()->Error("Error getting GetPluginInterfaceEntry for plugin %s: %s\n", mFilename.c_str(), lt_dlerror()); + return false; + } + + install(); + mInterface = getInterface(); + mLoaded = true; + return true; +} diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h index f238122..e7d4b12 100644 --- a/src/plugins/plugin.h +++ b/src/plugins/plugin.h @@ -19,15 +19,28 @@ #pragma once +#include <ltdl.h> +#include <string> -#define PLUGIN_INTERFACE(class_type, interface_type) \ - extern "C" interface_type* installPlugin() { return (interface_type *)new class_type(); } \ - extern "C" void uninstallPlugin(class_type *_class) { delete _class; } +#include <common/logger.h> + +#include "plugininterface.h" class CPlugin { public: - virtual char* PluginName() = 0; - virtual int PluginVersion() = 0; + CPlugin(std::string filename); + + char* GetName(); + int GetVersion(); + bool UnloadPlugin(); + bool LoadPlugin(); + bool IsLoaded(); + + + private: + CPluginInterface* mInterface; + std::string mFilename; + lt_dlhandle mHandle; + bool mLoaded; }; - diff --git a/src/plugins/plugininterface.h b/src/plugins/plugininterface.h new file mode 100644 index 0000000..bf4e040 --- /dev/null +++ b/src/plugins/plugininterface.h @@ -0,0 +1,37 @@ +// * 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/. + +// plugininterface.h + + +#pragma once + + +#define PLUGIN_INTERFACE(class_type) \ + static class_type* Plugin##class_type; \ + extern "C" void InstallPluginEntry() { Plugin##class_type = new class_type(); Plugin##class_type->InstallPlugin(); } \ + extern "C" void UninstallPluginEntry() { Plugin##class_type->UninstallPlugin(); delete Plugin##class_type; } \ + extern "C" CPluginInterface* GetPluginInterfaceEntry() { return static_cast<CPluginInterface*>(Plugin##class_type); } + + +class CPluginInterface { + public: + virtual char* PluginName() = 0; + virtual int PluginVersion() = 0; + virtual void InstallPlugin() = 0; + virtual void UninstallPlugin() = 0; +}; + diff --git a/src/plugins/sound/oalsound/CMakeLists.txt b/src/plugins/sound/oalsound/CMakeLists.txt index 6056590..e36f3ac 100644 --- a/src/plugins/sound/oalsound/CMakeLists.txt +++ b/src/plugins/sound/oalsound/CMakeLists.txt @@ -4,10 +4,9 @@ set(SOURCES alsound.cpp buffer.cpp channel.cpp - ../../../common/logger.cpp ) -SET (CMAKE_CXX_FLAGS "-Wall -g -std=c++0x") +SET (CMAKE_CXX_FLAGS "-Wall -g -std=c++0x -fPIC") include(FindPkgConfig) include(FindOpenAL) diff --git a/src/plugins/sound/oalsound/alsound.cpp b/src/plugins/sound/oalsound/alsound.cpp index 0e15a40..19da66a 100644 --- a/src/plugins/sound/oalsound/alsound.cpp +++ b/src/plugins/sound/oalsound/alsound.cpp @@ -1,6 +1,6 @@ // * This file is part of the COLOBOT source code
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// * Copyright (C) 2012, Polish Portal of Colobot (PPC)
+// * 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
@@ -24,7 +24,7 @@ #define MIN(a, b) (a > b ? b : a)
-PLUGIN_INTERFACE(ALSound, CSoundInterface)
+PLUGIN_INTERFACE(ALSound)
char* ALSound::PluginName()
@@ -39,6 +39,19 @@ int ALSound::PluginVersion() }
+void ALSound::InstallPlugin()
+{
+ CInstanceManager::GetInstancePointer()->AddInstance(CLASS_SOUND, this);
+}
+
+
+void ALSound::UninstallPlugin()
+{
+ CInstanceManager::GetInstancePointer()->DeleteInstance(CLASS_SOUND, this);
+ CleanUp();
+}
+
+
ALSound::ALSound()
{
mEnabled = false;
@@ -58,11 +71,12 @@ void ALSound::CleanUp() {
if (mEnabled) {
GetLogger()->Info("Unloading files and closing device...\n");
- mEnabled = false;
+ StopAll();
for (auto item : mSounds)
delete item.second;
+ mEnabled = false;
alutExit();
}
}
diff --git a/src/plugins/sound/oalsound/alsound.h b/src/plugins/sound/oalsound/alsound.h index 982d3a3..6d4e5b6 100644 --- a/src/plugins/sound/oalsound/alsound.h +++ b/src/plugins/sound/oalsound/alsound.h @@ -76,6 +76,8 @@ class ALSound : public CSoundInterface // plugin interface
char* PluginName();
int PluginVersion();
+ void InstallPlugin();
+ void UninstallPlugin();
private:
void CleanUp();
diff --git a/src/plugins/test/CMakeLists.txt b/src/plugins/test/CMakeLists.txt new file mode 100644 index 0000000..551daeb --- /dev/null +++ b/src/plugins/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 ../plugin.cpp) + +# Change to DirectX SDK directory +include_directories("../../") + +target_link_libraries(plugin_test ltdl)
\ No newline at end of file diff --git a/src/plugins/test/plugin_test.cpp b/src/plugins/test/plugin_test.cpp new file mode 100644 index 0000000..7175773 --- /dev/null +++ b/src/plugins/test/plugin_test.cpp @@ -0,0 +1,40 @@ +#include <string> +#include <cstdio> +#include <unistd.h> + +#include <common/logger.h> +#include <common/iman.h> +#include <sound/sound.h> +#include <plugins/plugin.h> + + +int main() { + new CLogger(); + new CInstanceManager(); + + lt_dlinit(); + + CPlugin *plugin = new CPlugin("libopenalsound"); + if (plugin->LoadPlugin()) { + CSoundInterface *sound = static_cast<CSoundInterface*>(CInstanceManager::GetInstancePointer()->SearchInstance(CLASS_SOUND)); + + sound->Create(true); + sound->CacheAll(); + sound->Play((Sound)8); + sound->Play((Sound)18); + + sleep(10); + /* + while (1) + { + // just a test, very slow + plugin->FrameMove(0); + //if ('n' == getchar()) + // break; + }*/ + plugin->UnloadPlugin(); + } + + lt_dlexit(); + return 0; +} diff --git a/src/sound/sound.h b/src/sound/sound.h index 598ffe3..1bf9ae5 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -26,7 +26,7 @@ #include <math/vector.h>
-#include <plugins/plugin.h>
+#include <plugins/plugininterface.h>
/*!
* Maximum possible audio volume
@@ -145,13 +145,10 @@ enum SoundNext * @brief Sound plugin interface
*
*/
-class CSoundInterface : public CPlugin
+class CSoundInterface : public CPluginInterface
{
public:
- CSoundInterface() {
- //CInstanceManager::getInstance().AddInstance(CLASS_SOUND, this);
- //m_iMan->AddInstance(CLASS_SOUND, this);
- };
+ CSoundInterface() {};
virtual ~CSoundInterface() = 0;
/** Function to initialize sound device
|