truelight@9474: /* $Id$ */ truelight@9474: truebrain@9829: /** @file ai_transactionmode.hpp Switch the AI to Transaction Mode. */ truelight@9474: truelight@9474: #ifndef AI_TRANSACTIONMODE_HPP truelight@9474: #define AI_TRANSACTIONMODE_HPP truelight@9474: truelight@9474: #include "ai_object.hpp" truelight@9474: #include truelight@9474: truelight@9474: /** truelight@9474: * Class to switch current mode to Transaction mode. truelight@9474: * If you create an instance of this class, the mode will be switched to truelight@9474: * Transaction. The original mode is stored and recovered from when ever the truelight@9474: * instance is destroyed. truelight@9474: * In Transaction mode all commands will be tested, and if not fail, queued. truelight@9474: * Later on you can execute a queue for real. The Transaction keeps on truelight@9474: * recording all commands till it is destructed or execute or stopped. truelight@9474: * On execute the transaction can return false, because maps change over time. truelight@9474: * If this happens you can use the rollback feature to remove all already truelight@9474: * built things. truelight@9474: */ truelight@9474: class AITransactionMode : public AIObject { truebrain@9829: public: truebrain@9829: static const char *GetClassName() { return "AITransactionMode"; } truebrain@9829: truelight@9474: private: truelight@9474: struct AITransactionModeCommand { truelight@9474: TileIndex tile; truelight@9474: uint32 p1; truelight@9474: uint32 p2; truelight@9474: uint procc; truelight@9474: char *text; truelight@9474: }; truelight@9474: truelight@9474: AIModeProc *last_mode; truelight@9474: AIObject *last_instance; truelight@9474: std::queue command_stack; truelight@9474: std::queue reverse_stack; truelight@9474: bool stopped; glx@9629: CommandCost costs; truelight@9474: truelight@9474: protected: truelight@9475: /** truelight@9475: * The callback proc for Transaction mode. truelight@9475: */ glx@9629: static bool ModeProc(TileIndex tile, uint32 p1, uint32 p2, uint procc, CommandCost costs); truelight@9474: truelight@9474: public: truelight@9474: /** truelight@9474: * Creating instance of this class switches the build mode to Transaction. truebrain@9839: * @note When the instance is destroyed, he restores the mode that was truelight@9474: * current when the instance was created! truelight@9474: */ truelight@9474: AITransactionMode(); truelight@9474: truelight@9474: /** truelight@9474: * Destroying this instance reset the building mode to the mode it was truelight@9474: * in when the instance was created. truelight@9474: */ truelight@9474: ~AITransactionMode(); truelight@9474: truelight@9474: /** truelight@9474: * Execute all recorded commands. truebrain@9839: * @return False if any command recorded failed to execute. All other truelight@9474: * commands that follow won't be executed either. truebrain@9839: * @note When Execute() is called, the transaction is stopped (like calling truelight@9474: * Stop() yourself). truelight@9474: * @note Execute() is always executed, no matter what mode you gave it in truelight@9474: * the outside world. It forces itself into executing it for real. To add truelight@9474: * it to an other list, use Append(). truelight@9474: */ truelight@9474: bool Execute(); truelight@9474: truelight@9474: /** truelight@9474: * Stop recording the commands and switch to the last mode, like the truelight@9474: * instance was destroyed. truelight@9474: */ truelight@9474: void Stop(); truelight@9474: truelight@9474: /** truelight@9474: * Rollbacks rolls the whole transaction back in case Execute() returned truelight@9474: * false. In case Execute() returned true, there won't be anything to roll truelight@9474: * back, so this command will do nothing. truelight@9474: * It rolls back all commands by looking up the reverse of every command truelight@9474: * issued and executes that. Of course it can happen that even that fails. truelight@9474: * In that case the problem will be silently ignored. truebrain@9839: * @note As you might want to get a costs estimate about the rollback first truelight@9474: * you need to make sure you set the right mode yourself! truebrain@9839: * @note This command isn't finished yet!! truelight@9474: */ truelight@9474: void Rollback(); truelight@9474: truelight@9474: /** truelight@9474: * Get the costs it takes to execute this transaction (on average, real truelight@9474: * numbers can always differ). rubidium@9843: * @return The costs of this transaction. truelight@9474: */ glx@9629: Money GetCosts(); truelight@9474: truelight@9474: /** truelight@9474: * Append one transaction list to an other. truebrain@9839: * @param transaction The list that will be appended after the instance you call append on. truelight@9474: */ truelight@9474: void Append(AITransactionMode *transaction); truelight@9474: }; truelight@9474: truelight@9474: #endif /* AI_TRANSACTIONMODE_HPP */