src/ai/api/ai_transactionmode.hpp
author truelight
Sun, 19 Aug 2007 13:16:06 +0000
branchnoai
changeset 9696 4384ed3de1f0
parent 9629 66dde6412125
child 9829 80fbe02a4184
permissions -rw-r--r--
(svn r10937) [NoAI] -Add: added AIStation::GetName on request by Nickman
[NoAI] -Fix: AICompant::GetCompanyName returned \0 for invalid company instead of NULL
/* $Id$ */

/** @file ai_transactionmode.hpp class to switch the AI to Transaction mode */

#ifndef AI_TRANSACTIONMODE_HPP
#define AI_TRANSACTIONMODE_HPP

#include "ai_object.hpp"
#include <queue>

/**
 * Class to switch current mode to Transaction mode.
 * If you create an instance of this class, the mode will be switched to
 *   Transaction. The original mode is stored and recovered from when ever the
 *   instance is destroyed.
 * In Transaction mode all commands will be tested, and if not fail, queued.
 *   Later on you can execute a queue for real. The Transaction keeps on
 *   recording all commands till it is destructed or execute or stopped.
 * On execute the transaction can return false, because maps change over time.
 *   If this happens you can use the rollback feature to remove all already
 *   built things.
 */
class AITransactionMode : public AIObject {
private:
	struct AITransactionModeCommand {
		TileIndex tile;
		uint32 p1;
		uint32 p2;
		uint procc;
		char *text;
	};

	AIModeProc *last_mode;
	AIObject *last_instance;
	std::queue<AITransactionModeCommand> command_stack;
	std::queue<AITransactionModeCommand> reverse_stack;
	bool stopped;
	CommandCost costs;

protected:
	/**
	 * The callback proc for Transaction mode.
	 */
	static bool ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs);

public:
	/**
	 * The name of the class, needed by several sub-processes.
	 */
	static const char *GetClassName() { return "AITransactionMode"; }

	/**
	 * Creating instance of this class switches the build mode to Transaction.
	 * @note when the instance is destroyed, he restores the mode that was
	 *   current when the instance was created!
	 */
	AITransactionMode();

	/**
	 * Destroying this instance reset the building mode to the mode it was
	 *   in when the instance was created.
	 */
	~AITransactionMode();

	/**
	 * Execute all recorded commands.
	 * @return false if any command recorded failed to execute. All other
	 *   commands that follow won't be executed either.
	 * @note when Execute() is called, the transaction is stopped (like calling
	 *   Stop() yourself).
	 * @note Execute() is always executed, no matter what mode you gave it in
	 *   the outside world. It forces itself into executing it for real. To add
	 *   it to an other list, use Append().
	 */
	bool Execute();

	/**
	 * Stop recording the commands and switch to the last mode, like the
	 *   instance was destroyed.
	 */
	void Stop();

	/**
	 * Rollbacks rolls the whole transaction back in case Execute() returned
	 *   false. In case Execute() returned true, there won't be anything to roll
	 *   back, so this command will do nothing.
	 * It rolls back all commands by looking up the reverse of every command
	 *   issued and executes that. Of course it can happen that even that fails.
	 *   In that case the problem will be silently ignored.
	 * @note as you might want to get a costs estimate about the rollback first
	 *   you need to make sure you set the right mode yourself!
	 * @note this command isn't finished yet!!
	 */
	void Rollback();

	/**
	 * Get the costs it takes to execute this transaction (on average, real
	 *   numbers can always differ).
	 */
	Money GetCosts();

	/**
	 * Append one transaction list to an other.
	 * @param transaction the list that will be appended after the instance you call append on.
	 */
	void Append(AITransactionMode *transaction);
};

#endif /* AI_TRANSACTIONMODE_HPP */