#include "util/reader.hpp"
#include "supertux/object_factory.hpp"
-GameObject* create_object(const std::string& name, const Reader& reader)
+#include "badguy/angrystone.hpp"
+#include "badguy/badguy.hpp"
+#include "badguy/bomb.hpp"
+#include "badguy/bouncing_snowball.hpp"
+#include "badguy/captainsnowball.hpp"
+#include "badguy/crystallo.hpp"
+#include "badguy/dart.hpp"
+#include "badguy/darttrap.hpp"
+#include "badguy/dispenser.hpp"
+#include "badguy/fish.hpp"
+#include "badguy/flame.hpp"
+#include "badguy/flyingsnowball.hpp"
+#include "badguy/ghosttree.hpp"
+#include "badguy/igel.hpp"
+#include "badguy/jumpy.hpp"
+#include "badguy/kamikazesnowball.hpp"
+#include "badguy/kugelblitz.hpp"
+#include "badguy/mole.hpp"
+#include "badguy/mole_rock.hpp"
+#include "badguy/mrbomb.hpp"
+#include "badguy/mriceblock.hpp"
+#include "badguy/mrrocket.hpp"
+#include "badguy/mrtree.hpp"
+#include "badguy/plant.hpp"
+#include "badguy/poisonivy.hpp"
+#include "badguy/root.hpp"
+#include "badguy/skullyhop.hpp"
+#include "badguy/smartball.hpp"
+#include "badguy/snail.hpp"
+#include "badguy/snowball.hpp"
+#include "badguy/spidermite.hpp"
+#include "badguy/spiky.hpp"
+#include "badguy/sspiky.hpp"
+#include "badguy/stalactite.hpp"
+#include "badguy/stumpy.hpp"
+#include "badguy/toad.hpp"
+#include "badguy/totem.hpp"
+#include "badguy/treewillowisp.hpp"
+#include "badguy/walking_badguy.hpp"
+#include "badguy/walkingleaf.hpp"
+#include "badguy/willowisp.hpp"
+#include "badguy/yeti.hpp"
+#include "badguy/yeti_stalactite.hpp"
+#include "badguy/zeekling.hpp"
+
+#include "object/ambient_sound.hpp"
+#include "object/anchor_point.hpp"
+#include "object/background.hpp"
+#include "object/bicycle_platform.hpp"
+#include "object/block.hpp"
+#include "object/bonus_block.hpp"
+#include "object/bouncy_coin.hpp"
+#include "object/brick.hpp"
+#include "object/broken_brick.hpp"
+#include "object/bullet.hpp"
+#include "object/camera.hpp"
+#include "object/candle.hpp"
+#include "object/cloud_particle_system.hpp"
+#include "object/coin.hpp"
+#include "object/comet_particle_system.hpp"
+#include "object/decal.hpp"
+#include "object/display_effect.hpp"
+#include "object/electrifier.hpp"
+#include "object/endsequence_fireworks.hpp"
+#include "object/endsequence.hpp"
+#include "object/endsequence_walkleft.hpp"
+#include "object/endsequence_walkright.hpp"
+#include "object/explosion.hpp"
+#include "object/falling_coin.hpp"
+#include "object/firefly.hpp"
+#include "object/fireworks.hpp"
+#include "object/floating_image.hpp"
+#include "object/floating_text.hpp"
+#include "object/flower.hpp"
+#include "object/ghost_particle_system.hpp"
+#include "object/gradient.hpp"
+#include "object/growup.hpp"
+#include "object/hurting_platform.hpp"
+#include "object/icecrusher.hpp"
+#include "object/infoblock.hpp"
+#include "object/invisible_block.hpp"
+#include "object/invisible_wall.hpp"
+#include "object/ispy.hpp"
+#include "object/lantern.hpp"
+#include "object/level_time.hpp"
+#include "object/light.hpp"
+#include "object/magicblock.hpp"
+#include "object/moving_sprite.hpp"
+#include "object/oneup.hpp"
+#include "object/particles.hpp"
+#include "object/particlesystem.hpp"
+#include "object/particlesystem_interactive.hpp"
+#include "object/path.hpp"
+#include "object/path_walker.hpp"
+#include "object/platform.hpp"
+#include "object/player.hpp"
+#include "object/pneumatic_platform.hpp"
+#include "object/portable.hpp"
+#include "object/powerup.hpp"
+#include "object/pulsing_light.hpp"
+#include "object/pushbutton.hpp"
+#include "object/rain_particle_system.hpp"
+#include "object/rainsplash.hpp"
+#include "object/rock.hpp"
+#include "object/scripted_object.hpp"
+#include "object/skull_tile.hpp"
+#include "object/smoke_cloud.hpp"
+#include "object/snow_particle_system.hpp"
+#include "object/specialriser.hpp"
+#include "object/spotlight.hpp"
+#include "object/sprite_particle.hpp"
+#include "object/star.hpp"
+#include "object/text_object.hpp"
+#include "object/thunderstorm.hpp"
+#include "object/tilemap.hpp"
+#include "object/trampoline.hpp"
+#include "object/unstable_tile.hpp"
+#include "object/weak_block.hpp"
+#include "object/wind.hpp"
+
+#include "trigger/climbable.hpp"
+#include "trigger/door.hpp"
+#include "trigger/scripttrigger.hpp"
+#include "trigger/secretarea_trigger.hpp"
+#include "trigger/sequence_trigger.hpp"
+#include "trigger/switch.hpp"
+
+ObjectFactory&
+ObjectFactory::instance()
+{
+ static ObjectFactory instance_;
+ return instance_;
+}
+
+ObjectFactory::ObjectFactory() :
+ factories()
{
- Factory::Factories::iterator i = Factory::get_factories().find(name);
- if(i == Factory::get_factories().end()) {
+ init_factories();
+}
+
+ObjectFactory::~ObjectFactory()
+{
+}
+
+void
+ObjectFactory::init_factories()
+{
+ // badguys
+ add_factory<AngryStone>("angrystone");
+ add_factory<BouncingSnowball>("bouncingsnowball");
+ add_factory<CaptainSnowball>("captainsnowball");
+ add_factory<Crystallo>("crystallo");
+ add_factory<Dart>("dart");
+ add_factory<DartTrap>("darttrap");
+ add_factory<Dispenser>("dispenser");
+ add_factory<Fish>("fish");
+ add_factory<Flame>("flame");
+ add_factory<FlyingSnowBall>("flyingsnowball");
+ add_factory<GhostTree>("ghosttree");
+ add_factory<Igel>("igel");
+ add_factory<Jumpy>("jumpy");
+ add_factory<KamikazeSnowball>("kamikazesnowball");
+ add_factory<Kugelblitz>("kugelblitz");
+ add_factory<Mole>("mole");
+ add_factory<MoleRock>("mole_rock");
+ add_factory<MrBomb>("mrbomb");
+ add_factory<MrIceBlock>("mriceblock");
+ add_factory<MrRocket>("mrrocket");
+ add_factory<MrTree>("mrtree");
+ add_factory<Plant>("plant");
+ add_factory<PoisonIvy>("poisonivy");
+ add_factory<SSpiky>("sspiky");
+ add_factory<SkullyHop>("skullyhop");
+ add_factory<SmartBall>("smartball");
+ add_factory<Snail>("snail");
+ add_factory<SnowBall>("snowball");
+ add_factory<SpiderMite>("spidermite");
+ add_factory<Spiky>("spiky");
+ add_factory<Stalactite>("stalactite");
+ add_factory<Stumpy>("stumpy");
+ add_factory<Toad>("toad");
+ add_factory<Totem>("totem");
+ add_factory<WalkingLeaf>("walkingleaf");
+ add_factory<WillOWisp>("willowisp");
+ add_factory<Yeti>("yeti");
+ add_factory<YetiStalactite>("yeti_stalactite");
+ add_factory<Zeekling>("zeekling");
+
+ // other objects
+ add_factory<AmbientSound>("ambient_sound");
+ add_factory<Background>("background");
+ add_factory<BicyclePlatform>("bicycle-platform");
+ add_factory<BonusBlock>("bonusblock");
+ add_factory<Candle>("candle");
+ add_factory<Coin>("coin");
+ add_factory<Decal>("decal");
+ add_factory<Explosion>("explosion");
+ add_factory<Firefly>("firefly");
+ add_factory<Gradient>("gradient");
+ add_factory<HurtingPlatform>("hurting_platform");
+ add_factory<IceCrusher>("icecrusher");
+ add_factory<InfoBlock>("infoblock");
+ add_factory<InvisibleWall>("invisible_wall");
+ add_factory<Ispy>("ispy");
+ add_factory<Lantern>("lantern");
+ add_factory<LevelTime>("leveltime");
+ add_factory<MagicBlock>("magicblock");
+ add_factory<Platform>("platform");
+ add_factory<PneumaticPlatform>("pneumatic-platform");
+ add_factory<PowerUp>("powerup");
+ add_factory<PushButton>("pushbutton");
+ add_factory<Rock>("rock");
+ add_factory<ScriptedObject>("scriptedobject");
+ add_factory<SkullTile>("skull_tile");
+ add_factory<Spotlight>("spotlight");
+ add_factory<Thunderstorm>("thunderstorm");
+ add_factory<TileMap>("tilemap");
+ add_factory<Trampoline>("trampoline");
+ add_factory<UnstableTile>("unstable_tile");
+ add_factory<WeakBlock>("weak_block");
+ add_factory<Wind>("wind");
+
+ // trigger
+ add_factory<Climbable>("climbable");
+ add_factory<Door>("door");
+ add_factory<ScriptTrigger>("scripttrigger");
+ add_factory<SecretAreaTrigger>("secretarea");
+ add_factory<SequenceTrigger>("sequencetrigger");
+ add_factory<Switch>("switch");
+}
+
+GameObject*
+ObjectFactory::create(const std::string& name, const Reader& reader)
+{
+ Factories::iterator i = factories.find(name);
+
+ if (i == factories.end())
+ {
std::stringstream msg;
msg << "No factory for object '" << name << "' found.";
throw std::runtime_error(msg.str());
}
-
- return i->second->create_object(reader);
+ else
+ {
+ return i->second->create(reader);
+ }
}
-GameObject* create_object(const std::string& name, const Vector& pos, const Direction dir)
+GameObject*
+ObjectFactory::create(const std::string& name, const Vector& pos, const Direction dir)
{
std::stringstream lisptext;
lisptext << "((x " << pos.x << ")"
lisp::Parser parser;
const lisp::Lisp* lisp = parser.parse(lisptext, "create_object");
- GameObject* object = create_object(name, *(lisp->get_car()));
-
+
+ GameObject* object = create(name, *(lisp->get_car()));
return object;
}
#define HEADER_SUPERTUX_SUPERTUX_OBJECT_FACTORY_HPP
#include <map>
+#include <assert.h>
#include "supertux/direction.hpp"
#include "util/reader_fwd.hpp"
class Vector;
class GameObject;
-class Factory
+class AbstractObjectFactory
{
public:
- virtual ~Factory()
+ virtual ~AbstractObjectFactory()
{ }
/** Creates a new gameobject from a lisp node.
* Remember to delete the objects later
*/
- virtual GameObject* create_object(const Reader& reader) = 0;
+ virtual GameObject* create(const Reader& reader) = 0;
+};
+
+template<class C>
+class ConcreteObjectFactory : public AbstractObjectFactory
+{
+public:
+ ConcreteObjectFactory() {}
+ ~ConcreteObjectFactory() {}
- typedef std::map<std::string, Factory*> Factories;
- static Factories &get_factories()
+ GameObject* create(const Reader& reader)
{
- static Factories object_factories;
- return object_factories;
+ return new C(reader);
}
};
-GameObject* create_object(const std::string& name, const Reader& reader);
-GameObject* create_object(const std::string& name, const Vector& pos, const Direction dir = AUTO);
+class ObjectFactory
+{
+public:
+ static ObjectFactory& instance();
+
+private:
+ typedef std::map<std::string, AbstractObjectFactory*> Factories;
+ Factories factories;
-/** comment from Matze:
- * Yes I know macros are evil, but in this specific case they save
- * A LOT of typing and evil code duplication.
- * I'll happily accept alternatives if someone can present me one that does
- * not involve typing 4 or more lines for each object class
- */
-#define IMPLEMENT_FACTORY(CLASS, NAME) \
- class INTERN_##CLASS##Factory : public Factory \
- { \
- public: \
- INTERN_##CLASS##Factory() \
- { \
- get_factories()[NAME] = this; \
- } \
- \
- ~INTERN_##CLASS##Factory() \
- { \
- get_factories().erase(NAME); \
- } \
- \
- virtual GameObject* create_object(const Reader& reader) \
- { \
- return new CLASS(reader); \
- } \
- }; \
- static INTERN_##CLASS##Factory factory_##CLASS
+public:
+ ObjectFactory();
+ ~ObjectFactory();
+
+ GameObject* create(const std::string& name, const Reader& reader);
+ GameObject* create(const std::string& name, const Vector& pos, const Direction dir = AUTO);
+
+private:
+ template<class C>
+ void add_factory(const char* name)
+ {
+ assert(factories.find(name) == factories.end());
+ factories[name] = new ConcreteObjectFactory<C>();
+ }
+ void init_factories();
+};
#endif