src/ai/core/ai_factory.hpp
branchnoai
changeset 9390 4042c17c8055
child 9391 2d6da2e48112
--- /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 */