--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/core/ai_factory.hpp Wed Mar 14 22:55:57 2007 +0000
@@ -0,0 +1,124 @@
+/* $Id$ */
+
+/** @file ai_factory.hpp declaration of class for AIFactory class */
+
+#ifndef AI_FACTORY_HPP
+#define AI_FACTORY_HPP
+
+#include <string>
+#include <map>
+#include <assert.h>
+
+#include "ai_base.hpp"
+
+class AIController;
+
+class AIFactoryBase {
+private:
+ const char *name;
+ typedef std::map<std::string, AIFactoryBase *> Factories;
+
+ static Factories &GetFactories()
+ {
+ static Factories s_factories;
+ return s_factories;
+ }
+
+protected:
+ /**
+ * This registers your AI to the main system so we know about you.
+ */
+ void RegisterFactory(AIFactoryBase *instance, const char *name)
+ {
+ std::pair<Factories::iterator, bool> P = GetFactories().insert(Factories::value_type(name, this));
+ assert(P.second);
+ this->name = name;
+ }
+
+public:
+ virtual ~AIFactoryBase() { GetFactories().erase(this->name); }
+
+ static AIController *SelectRandomAI()
+ {
+ if (GetFactories().size() == 0) return NULL;
+
+ /* Find a random AI */
+ uint i;
+ if (_networking) i = InteractiveRandomRange(GetFactories().size());
+ else i = RandomRange(GetFactories().size());
+
+ /* Find the Nth item from the array */
+ Factories::iterator it = GetFactories().begin();
+ Factories::iterator first_it;
+ for (; i > 0; i--) it++;
+ first_it = it;
+ AIFactoryBase *f = (*it).second;
+
+ if (!f->AllowStartup()) {
+ /* We can't start this AI, try to find the next best */
+ do {
+ if (it == GetFactories().end()) it = GetFactories().begin();
+ else it++;
+ /* Back at the beginning? Drop out! */
+ if (first_it == it) break;
+ f = (*it).second;
+ } while (!f->AllowStartup());
+ /* Unable to start any AI */
+ if (first_it == it) return NULL;
+ }
+ return f->CreateInstance();
+ }
+
+
+
+ /**
+ * Get the author of the AI.
+ */
+ virtual const char *GetAuthor() = 0;
+
+ /**
+ * Get a short name for the AI.
+ */
+ virtual const char *GetName() = 0;
+
+ /**
+ * Get a description of the AI.
+ */
+ virtual const char *GetDescription() = 0;
+
+ /**
+ * Get the version of this AI.
+ */
+ virtual int GetVersion() = 0;
+
+ /**
+ * Get the date of the version.
+ * @return A string like '2007-08-29'.
+ */
+ virtual const char *GetDate() = 0;
+
+ /**
+ * Create an instance of your AI.
+ */
+ virtual AIController *CreateInstance() = 0;
+
+ /**
+ * In this function you can do some very limited querying of the game.
+ * If you for example only supply road-vehicle-based AI, and RVs are
+ * disabled, you return 'false', so you won't boot.
+ */
+ virtual bool AllowStartup() { return true; }
+};
+
+/**
+ * The template to define your AIFactory. This makes sure RegisterFactory
+ * works correctly on initialization.
+ * Example: class FYourClass: public AIFactory<FYourClass> { }
+ */
+template <class T>
+class AIFactory: public AIFactoryBase {
+public:
+ AIFactory() { this->RegisterFactory(this, ((T *)this)->GetName()); }
+};
+
+#endif /* AI_FACTORY_HPP */