replay.hpp

Go to the documentation of this file.
00001 /* $Id: replay.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2003 - 2012 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  *  @file
00018  *  Replay control code.
00019  */
00020 
00021 #ifndef REPLAY_H_INCLUDED
00022 #define REPLAY_H_INCLUDED
00023 
00024 #include "config.hpp"
00025 #include "map_location.hpp"
00026 #include "rng.hpp"
00027 
00028 #include <deque>
00029 
00030 class game_display;
00031 class terrain_label;
00032 class unit_map;
00033 class play_controller;
00034 struct time_of_day;
00035 
00036 class chat_msg {
00037 public:
00038     const std::string &text() const { return text_; }
00039     const std::string &nick() const { return nick_; }
00040     const std::string &color() const { return color_; }
00041     chat_msg(const config &cfg);
00042     virtual ~chat_msg();
00043 private:
00044     std::string color_;
00045     std::string nick_;
00046     std::string text_;
00047 };
00048 
00049 class replay: public rand_rng::rng
00050 {
00051 public:
00052     replay();
00053     explicit replay(const config& cfg);
00054 
00055     void append(const config& cfg);
00056 
00057     void set_skip(bool skip);
00058     bool is_skipping() const;
00059 
00060     void add_start();
00061     void add_recruit(int unit_index, const map_location& loc, const map_location& from);
00062     void add_recall(const std::string& unit_id, const map_location& loc, const map_location& from);
00063     void add_disband(const std::string& unit_id);
00064     void add_countdown_update(int value,int team);
00065     void add_movement(const std::vector<map_location>& steps);
00066     void add_attack(const map_location& a, const map_location& b,
00067         int att_weapon, int def_weapon, const std::string& attacker_type_id,
00068         const std::string& defender_type_id, int attacker_lvl,
00069         int defender_lvl, const size_t turn, const time_of_day &t);
00070     void add_seed(const char* child_name, int seed);
00071     void user_input(const std::string &, const config &);
00072     void add_label(const terrain_label*);
00073     void clear_labels(const std::string&, bool);
00074     void add_rename(const std::string& name, const map_location& loc);
00075     void init_side();
00076     void end_turn();
00077     void add_event(const std::string& name,
00078         const map_location& loc=map_location::null_location);
00079     void add_unit_checksum(const map_location& loc,config* const cfg);
00080     void add_checksum_check(const map_location& loc);
00081     void add_log_data(const std::string &key, const std::string &var);
00082     void add_log_data(const std::string &category, const std::string &key, const std::string &var);
00083     void add_log_data(const std::string &category, const std::string &key, const config& c);
00084 
00085     /**
00086      * Mark an expected advancement adding it to the queue
00087      */
00088     void add_expected_advancement(const map_location& loc);
00089 
00090     /**
00091      * Access to the expected advancements queue.
00092      */
00093     const std::deque<map_location>& expected_advancements() const;
00094 
00095     /**
00096      * Remove the front expected advancement from the queue
00097      */
00098     void pop_expected_advancement();
00099 
00100     /**
00101      * Adds an advancement to the replay, the following option command
00102      * determines which advancement option has been chosen
00103      */
00104     void add_advancement(const map_location& loc);
00105 
00106     void add_chat_message_location();
00107     void speak(const config& cfg);
00108     const std::vector<chat_msg>& build_chat_log();
00109 
00110     //get data range will get a range of moves from the replay system.
00111     //if data_type is 'ALL_DATA' then it will return all data in this range
00112     //except for undoable data that has already been sent. If data_type is
00113     //NON_UNDO_DATA, then it will only retrieve undoable data, and will mark
00114     //it as already sent.
00115     //undoable data includes moves such as placing a label or speaking, which is
00116     //ignored by the undo system.
00117     enum DATA_TYPE { ALL_DATA, NON_UNDO_DATA };
00118     config get_data_range(int cmd_start, int cmd_end, DATA_TYPE data_type=ALL_DATA);
00119     config get_last_turn(int num_turns=1);
00120     const config& get_replay_data() const { return cfg_; }
00121 
00122     void undo();
00123 
00124     void start_replay();
00125     void revert_action();
00126     config* get_next_action();
00127     void pre_replay();
00128 
00129     bool at_end() const;
00130     void set_to_end();
00131 
00132     void clear();
00133     bool empty();
00134 
00135     enum MARK_SENT { MARK_AS_UNSENT, MARK_AS_SENT };
00136     void add_config(const config& cfg, MARK_SENT mark=MARK_AS_UNSENT);
00137 
00138     int ncommands() const;
00139 
00140     static void process_error(const std::string& msg);
00141 
00142 private:
00143     //generic for add_movement and add_attack
00144     void add_pos(const std::string& type,
00145                  const map_location& a, const map_location& b);
00146 
00147     void add_chat_log_entry(const config &speak, std::back_insert_iterator< std::vector<chat_msg> > &i) const;
00148 
00149     config &command(int);
00150     void remove_command(int);
00151     /** Adds a new empty command to the command list.
00152      *
00153      * @param update_random_context  If set to false, do not update the
00154      *           random context variables: all random generation will take
00155      *           place in the previous random context. Used for commands
00156      *           for which "random context" is pointless, and which can be
00157      *           issued while some other commands are still taking place,
00158      *           like, for example, messages during combats.
00159      *
00160      * @return a pointer to the added command
00161      */
00162     config* add_command(bool update_random_context=true);
00163     config cfg_;
00164     int pos_;
00165 
00166     config* current_;
00167 
00168     bool skip_;
00169 
00170     std::vector<int> message_locations;
00171 
00172     /**
00173      * A queue of units (locations) that are supposed to advance but the
00174      * relevant advance (choice) message has not yet been received
00175      */
00176     std::deque<map_location> expected_advancements_;
00177 };
00178 
00179 replay& get_replay_source();
00180 
00181 extern replay recorder;
00182 
00183 //replays up to one turn from the recorder object
00184 //returns true if it got to the end of the turn without data running out
00185 bool do_replay(int side_num, replay *obj = NULL);
00186 
00187 bool do_replay_handle(int side_num, const std::string &do_untill);
00188 
00189 //an object which can be made to undo a recorded move
00190 //unless the transaction is confirmed
00191 struct replay_undo
00192 {
00193     replay_undo(replay& obj) : obj_(&obj) {}
00194     ~replay_undo() { if(obj_) obj_->undo(); }
00195     void confirm_transaction() { obj_ = NULL; }
00196 
00197 private:
00198     replay* obj_;
00199 };
00200 
00201 class replay_network_sender
00202 {
00203 public:
00204     replay_network_sender(replay& obj);
00205     ~replay_network_sender();
00206 
00207     void sync_non_undoable();
00208     void commit_and_sync();
00209 private:
00210     replay& obj_;
00211     int upto_;
00212 };
00213 
00214 namespace mp_sync {
00215 
00216 /**
00217  * Interface for querying local choices.
00218  * It has to support querying the user and making a random choice from a
00219  * preseeded random generator.
00220  */
00221 struct user_choice
00222 {
00223     virtual ~user_choice() {}
00224     virtual config query_user() const = 0;
00225     virtual config random_choice(rand_rng::simple_rng &) const = 0;
00226 };
00227 
00228 /**
00229  * Performs a choice for WML events.
00230  *
00231  * The choice is synchronized across all the multiplayer clients and
00232  * stored into the replay. The function object is called if the local
00233  * client is responsible for making the choice.
00234  * @param name Tag used for storing the choice into the replay.
00235  * @param side The number of the side responsible for making the choice.
00236  *             If zero, it defaults to the currently active side.
00237  * @param force_sp If true, user choice will happen in prestart and start
00238  *                 events too. But if used for these events in multiplayer,
00239  *                 an exception will be thrown instead.
00240  *
00241  * @note In order to prevent issues with sync, crash, or infinite loop, a
00242  *       number of precautions must be taken when getting a choice from a
00243  *       specific side.
00244  *       - The calling function must enter a loop to wait for network sync
00245  *         if the side is non-local. This loop must end when a response is
00246  *         received in the replay.
00247  *       - The server must recognize @name replay commands as legal from
00248  *         non-active players. Preferably the server should be notified
00249  *         about which player the data is expected from, and discard data
00250  *         from unexpected players.
00251  *       - do_replay_handle must ignore the @name replay command when the
00252  *         originating player's turn is reached.
00253  */
00254 config get_user_choice(const std::string &name, const user_choice &uch,
00255     int side = 0, bool force_sp = false);
00256 
00257 }
00258 
00259 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:08 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs