aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2010-03-29 07:30:52 +0200
committerAlexander Sulfrian <alexander@sulfrian.net>2013-01-05 17:17:47 +0100
commit15c0132fd080003f2bf47749e30e1f724b249341 (patch)
tree1d09f54e344d19e99df9e0fc89643f071881c6ae
parent0779a60f3e31a31db71614134ddd7eedc5e385d9 (diff)
downloadusdx-15c0132fd080003f2bf47749e30e1f724b249341.tar.gz
usdx-15c0132fd080003f2bf47749e30e1f724b249341.tar.xz
usdx-15c0132fd080003f2bf47749e30e1f724b249341.zip
dynamic registration of songloading_strategies with static template
-rw-r--r--src/base/songloading/songloader.cpp27
-rw-r--r--src/base/songloading/songloader.hpp6
-rw-r--r--src/base/songloading/songloading_strategy.hpp9
-rw-r--r--src/base/songloading/songloading_strategy_base_factory.cpp41
-rw-r--r--src/base/songloading/songloading_strategy_base_factory.hpp55
-rw-r--r--src/base/songloading/songloading_strategy_factory.hpp66
-rw-r--r--src/base/songloading/songloading_strategy_txt.cpp8
-rw-r--r--src/base/songloading/songloading_strategy_txt.hpp10
-rw-r--r--src/base/songloading/songloading_strategy_xml.hpp5
-rw-r--r--test/base/songloading.cpp2
10 files changed, 202 insertions, 27 deletions
diff --git a/src/base/songloading/songloader.cpp b/src/base/songloading/songloader.cpp
index 2f3d3508..0524d18c 100644
--- a/src/base/songloading/songloader.cpp
+++ b/src/base/songloading/songloader.cpp
@@ -37,22 +37,10 @@ namespace usdx
Songloader::Songloader(void)
{
- // add different strategies to map
- strategies[L".txt"] = new SongloadingStrategyTxt();
- strategies[L".xml"] = new SongloadingStrategyXml();
- }
-
- void remove_element(std::pair<std::wstring, SongloadingStrategy*> e)
- {
- delete e.second;
- e.second = NULL;
}
Songloader::~Songloader(void)
{
- // clear memory for all elements in the map
- std::for_each(strategies.begin(), strategies.end(),
- remove_element);
strategies.clear();
// remove reference from singleton to make regeneration possible
@@ -71,24 +59,31 @@ namespace usdx
Song *Songloader::load_header(const boost::filesystem::wpath& filename)
{
std::wstring ext = extension(filename);
- std::map<std::wstring, SongloadingStrategy*>::iterator it = strategies.find(ext);
+ std::map<std::wstring, SongloadingStrategyBaseFactory*>::iterator it = strategies.find(ext);
if (it == strategies.end()) {
LOG4CXX_WARN(log, L"No SongloadingStrategy found for file extension: '" << ext << L"'");
throw NoStrategyException("Unknown file format.");
}
- return it->second->load_header(filename);
+ return it->second->get_songloader()->load_header(filename);
}
Song* Songloader::load_song(Song* song)
{
std::wstring ext = extension(song->get_filename());
- std::map<std::wstring, SongloadingStrategy*>::iterator it = strategies.find(ext);
+ std::map<std::wstring, SongloadingStrategyBaseFactory*>::iterator it = strategies.find(ext);
if (it == strategies.end()) {
LOG4CXX_WARN(log, L"No SongloadingStrategy found for file extension: '" << ext << L"'");
throw NoStrategyException("Unknown file format.");
}
- return it->second->load_song(song);
+ return it->second->get_songloader()->load_song(song);
+ }
+
+ void Songloader::add_strategy(SongloadingStrategyBaseFactory *factory)
+ {
+ if (factory) {
+ strategies[factory->get_fileextension()] = factory;
+ }
}
};
diff --git a/src/base/songloading/songloader.hpp b/src/base/songloading/songloader.hpp
index 0e8a6bd1..ac18f41d 100644
--- a/src/base/songloading/songloader.hpp
+++ b/src/base/songloading/songloader.hpp
@@ -30,9 +30,9 @@
#include <map>
#include <boost/filesystem.hpp>
#include <log4cxx/logger.h>
-#include "songloading_strategy.hpp"
#include "song.hpp"
#include "utils/base_exception.hpp"
+#include "songloading_strategy_base_factory.hpp"
namespace usdx
{
@@ -50,7 +50,7 @@ namespace usdx
Songloader(void);
- std::map<std::wstring, SongloadingStrategy*> strategies;
+ std::map<std::wstring, SongloadingStrategyBaseFactory*> strategies;
/**
* Singleton
@@ -64,6 +64,8 @@ namespace usdx
Song* load_header(const boost::filesystem::wpath& filename);
Song* load_song(Song* song);
+
+ void add_strategy(SongloadingStrategyBaseFactory* strategie);
};
};
diff --git a/src/base/songloading/songloading_strategy.hpp b/src/base/songloading/songloading_strategy.hpp
index 48e115b7..3178f6ed 100644
--- a/src/base/songloading/songloading_strategy.hpp
+++ b/src/base/songloading/songloading_strategy.hpp
@@ -31,6 +31,15 @@
#include <boost/filesystem.hpp>
#include "song.hpp"
+#define _USDX_JOIN(strategy, line) _USDX_JOIN1(strategy, line)
+#define _USDX_JOIN1(strategy, line) autoregistration__strategy__##line
+
+/* Macros to simplify registration of SongLoadingStrategy */
+#define REGISTER_SONGLOADING_STRATEGY(strategy) \
+ static SongloadingStrategyFactory<strategy> \
+ _USDX_JOIN(strategy, __LINE__)
+
+
namespace usdx
{
class SongloadingStrategy
diff --git a/src/base/songloading/songloading_strategy_base_factory.cpp b/src/base/songloading/songloading_strategy_base_factory.cpp
new file mode 100644
index 00000000..9f8333b4
--- /dev/null
+++ b/src/base/songloading/songloading_strategy_base_factory.cpp
@@ -0,0 +1,41 @@
+/*
+ * UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "songloading_strategy_base_factory.hpp"
+#include "songloader.hpp"
+
+namespace usdx
+{
+ SongloadingStrategyBaseFactory::SongloadingStrategyBaseFactory(std::wstring fileextension) : fileextension(fileextension)
+ {
+ Songloader::get_instance()->add_strategy(this);
+ }
+
+ std::wstring SongloadingStrategyBaseFactory::get_fileextension(void)
+ {
+ return fileextension;
+ }
+};
diff --git a/src/base/songloading/songloading_strategy_base_factory.hpp b/src/base/songloading/songloading_strategy_base_factory.hpp
new file mode 100644
index 00000000..ae20b1ce
--- /dev/null
+++ b/src/base/songloading/songloading_strategy_base_factory.hpp
@@ -0,0 +1,55 @@
+/*
+ * UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef SONGLOADING_STRATEGY_BASE_FACTORY_HPP
+#define SONGLOADING_STRATEGY_BASE_FACTORY_HPP
+
+#include <string>
+#include "songloading_strategy.hpp"
+
+namespace usdx
+{
+ class SongloadingStrategyBaseFactory
+ {
+ private:
+ /// no copy
+ SongloadingStrategyBaseFactory(SongloadingStrategyBaseFactory&) {};
+
+ /// no copy
+ void operator=(SongloadingStrategyBaseFactory&) {};
+
+ std::wstring fileextension;
+
+ public:
+ SongloadingStrategyBaseFactory(std::wstring fileextension);
+ virtual ~SongloadingStrategyBaseFactory(void) {};
+
+ virtual SongloadingStrategy *get_songloader(void) = 0;
+ std::wstring get_fileextension(void);
+ };
+};
+
+#endif
diff --git a/src/base/songloading/songloading_strategy_factory.hpp b/src/base/songloading/songloading_strategy_factory.hpp
new file mode 100644
index 00000000..e523560d
--- /dev/null
+++ b/src/base/songloading/songloading_strategy_factory.hpp
@@ -0,0 +1,66 @@
+/*
+ * UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 2
+ * 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#ifndef SONGLOADING_STRATEGY_FACTORY_HPP
+#define SONGLOADING_STRATEGY_FACTORY_HPP
+
+#include "songloading_strategy_base_factory.hpp"
+
+namespace usdx
+{
+ template <typename T>
+ class SongloadingStrategyFactory : public SongloadingStrategyBaseFactory
+ {
+ private:
+ T *songloader;
+
+ public:
+ SongloadingStrategyFactory(void) :
+ SongloadingStrategyBaseFactory(T::get_fileextension()),
+ songloader(NULL)
+ {
+ }
+
+ virtual ~SongloadingStrategyFactory(void)
+ {
+ if (songloader) {
+ delete songloader;
+ songloader = NULL;
+ }
+ }
+
+ T *get_songloader(void)
+ {
+ if (!songloader) {
+ songloader = new T();
+ }
+
+ return songloader;
+ }
+ };
+};
+
+#endif
diff --git a/src/base/songloading/songloading_strategy_txt.cpp b/src/base/songloading/songloading_strategy_txt.cpp
index 7560a9c2..b80289ee 100644
--- a/src/base/songloading/songloading_strategy_txt.cpp
+++ b/src/base/songloading/songloading_strategy_txt.cpp
@@ -32,7 +32,7 @@
#include <boost/algorithm/string.hpp>
#include "songloading_strategy_txt.hpp"
-#include "utils/file.hpp"
+#include "utils/unicode_file.hpp"
#include "utils/locale_independent_float.hpp"
namespace usdx
@@ -83,7 +83,7 @@ namespace usdx
{
LOG4CXX_DEBUG(log, L"Starting loading song from file: " << song->get_filename());
- File file(song->get_filename());
+ UnicodeFile file(song->get_filename());
int line_number = 0;
while (file.stream().good() && parse_line(song, file, ++line_number));
@@ -93,7 +93,7 @@ namespace usdx
return song;
}
- bool SongloadingStrategyTxt::parse_line(Song* song, File& file, const int line_number)
+ bool SongloadingStrategyTxt::parse_line(Song* song, UnicodeFile& file, const int line_number)
{
try {
std::wstring line;
@@ -191,7 +191,7 @@ namespace usdx
Song* SongloadingStrategyTxt::load_header(const boost::filesystem::wpath& filename)
{
- File file(filename);
+ UnicodeFile file(filename);
std::wstring line;
std::map<std::wstring, std::wstring> header_fields;
diff --git a/src/base/songloading/songloading_strategy_txt.hpp b/src/base/songloading/songloading_strategy_txt.hpp
index 13851e6e..6177a5d3 100644
--- a/src/base/songloading/songloading_strategy_txt.hpp
+++ b/src/base/songloading/songloading_strategy_txt.hpp
@@ -31,7 +31,8 @@
#include <boost/filesystem.hpp>
#include <log4cxx/logger.h>
#include "songloading_strategy.hpp"
-#include "utils/file.hpp"
+#include "songloading_strategy_factory.hpp"
+#include "utils/unicode_file.hpp"
namespace usdx
{
@@ -45,19 +46,22 @@ namespace usdx
*/
std::pair<std::wstring, std::wstring> split_header_field(std::wstring &line);
- bool parse_line(Song* song, File& file, const int line_number);
+ bool parse_line(Song* song, UnicodeFile& file, const int line_number);
void parse_newline(Song* song, std::wistringstream& linestream, const int line_number);
void parse_bpm(Song* song, std::wistringstream& linestream, const int line_number);
void parse_note(Song* song, wchar_t type, std::wistringstream& linestream, const int line_number);
-
public:
SongloadingStrategyTxt();
virtual ~SongloadingStrategyTxt();
virtual Song* load_song(Song* song);
virtual Song* load_header(const boost::filesystem::wpath& filename);
+
+ static std::wstring get_fileextension(void) { return L".txt"; };
};
+
+ REGISTER_SONGLOADING_STRATEGY(SongloadingStrategyTxt);
};
#endif
diff --git a/src/base/songloading/songloading_strategy_xml.hpp b/src/base/songloading/songloading_strategy_xml.hpp
index 76e3f76e..38637646 100644
--- a/src/base/songloading/songloading_strategy_xml.hpp
+++ b/src/base/songloading/songloading_strategy_xml.hpp
@@ -29,6 +29,7 @@
#include <boost/filesystem.hpp>
#include "songloading_strategy.hpp"
+#include "songloading_strategy_factory.hpp"
namespace usdx
{
@@ -40,7 +41,11 @@ namespace usdx
virtual Song* load_song(Song* song);
virtual Song* load_header(const boost::filesystem::wpath& filename);
+
+ static std::wstring get_fileextension(void) { return L".xml"; };
};
+
+ REGISTER_SONGLOADING_STRATEGY(SongloadingStrategyXml);
};
#endif
diff --git a/test/base/songloading.cpp b/test/base/songloading.cpp
index 2d5ca19e..5be46fe6 100644
--- a/test/base/songloading.cpp
+++ b/test/base/songloading.cpp
@@ -57,8 +57,6 @@ namespace usdx
// set old loglevel in case we did disable logging
using namespace log4cxx;
Logger::getRootLogger()->setLevel(Level::toLevel(oldLogLevel));
-
- delete Songloader::get_instance();
}
void testSongloadingTxtHeader()