void load_resolutions(const config& cfg) { config::const_child_itors itors = cfg.child_range("resolution"); FOREACH(const AUTO & resolution, itors) { resolutions.push_back(new T(resolution)); }
void item_palette::setup(const config& cfg) { for (const config& group : cfg.child_range("item_group")) { groups_.push_back(item_group(group)); for (const config& item : group.child_range("item")) { item_map_.insert(std::pair<std::string, overlay>(item["id"], overlay(item))); group_map_[group["id"]].push_back(item["id"]); if (!group["core"].to_bool(false)) non_core_items_.insert(item["id"]); } nmax_items_ = std::max(nmax_items_, group_map_[group["id"]].size()); } select_fg_item("anvil"); select_bg_item("altar"); // Set the default group set_group("items"); if(active_group().empty()) { ERR_ED << "No items found." << std::endl; } }
static void verify(const unit_map& units, const config& cfg) { std::stringstream errbuf; LOG_REPLAY << "verifying unit structure...\n"; const size_t nunits = cfg["num_units"].to_size_t(); if(nunits != units.size()) { errbuf << "SYNC VERIFICATION FAILED: number of units from data source differ: " << nunits << " according to data source. " << units.size() << " locally\n"; std::set<map_location> locs; BOOST_FOREACH(const config &u, cfg.child_range("unit")) { const map_location loc(u, resources::gamedata); locs.insert(loc); if(units.count(loc) == 0) { errbuf << "data source says there is a unit at " << loc << " but none found locally\n"; } } for(unit_map::const_iterator j = units.begin(); j != units.end(); ++j) { if (locs.count(j->get_location()) == 0) { errbuf << "local unit at " << j->get_location() << " but none in data source\n"; } } replay::process_error(errbuf.str()); errbuf.clear(); }
void editor_controller::init_tods(const config& game_config) { BOOST_FOREACH(const config &schedule, game_config.child_range("editor_times")) { const std::string& schedule_id = schedule["id"]; const std::string& schedule_name = schedule["name"]; if (schedule_id.empty()) { ERR_ED << "Missing ID attribute in a TOD Schedule.\n"; continue; } tods_map::iterator times = tods_.find(schedule_id); if (times == tods_.end()) { std::pair<tods_map::iterator, bool> new_times = tods_.insert( std::pair<std::string, std::pair<std::string, std::vector<time_of_day> > > (schedule_id, std::pair<std::string, std::vector<time_of_day> >(schedule_name, std::vector<time_of_day>())) ); times = new_times.first; } else { ERR_ED << "Duplicate TOD Schedule ids.\n"; continue; } BOOST_FOREACH(const config &time, schedule.child_range("time")) { times->second.second.push_back(time_of_day(time)); } } if (tods_.empty()) { ERR_ED << "No editor time-of-day defined\n"; } }
void game_state::place_sides_in_preferred_locations(const config& level) { std::vector<placing_info> placings; int num_pos = board_.map().num_valid_starting_positions(); int side_num = 1; BOOST_FOREACH(const config &side, level.child_range("side")) { for(int p = 1; p <= num_pos; ++p) { const map_location& pos = board_.map().starting_position(p); int score = placing_score(side, board_.map(), pos); placing_info obj; obj.side = side_num; obj.score = score; obj.pos = pos; placings.push_back(obj); } ++side_num; } std::stable_sort(placings.begin(),placings.end()); std::set<int> placed; std::set<map_location> positions_taken; for (std::vector<placing_info>::const_iterator i = placings.begin(); i != placings.end() && int(placed.size()) != side_num - 1; ++i) { if(placed.count(i->side) == 0 && positions_taken.count(i->pos) == 0) { placed.insert(i->side); positions_taken.insert(i->pos); board_.map_->set_starting_position(i->side,i->pos); LOG_NG << "placing side " << i->side << " at " << i->pos << std::endl; } } }
unit_race::unit_race(const config& cfg) : id_(cfg["id"]), plural_name_(cfg["plural_name"].t_str()), description_(cfg["description"].t_str()), ntraits_(cfg["num_traits"]), chain_size_(cfg["markov_chain_size"]), traits_(cfg.child_range("trait")), global_traits_(!cfg["ignore_global_traits"].to_bool()) { if (id_.empty()) { lg::wml_error << "[race] '" << cfg["name"] << "' is missing an id field."; } if (plural_name_.empty()) { lg::wml_error << "[race] '" << cfg["name"] << "' is missing a plural_name field."; plural_name_ = (cfg["name"]); } // use "name" if "male_name" or "female_name" aren't available name_[MALE] = cfg["male_name"]; if(name_[MALE].empty()) { name_[MALE] = (cfg["name"]); } name_[FEMALE] = cfg["female_name"]; if(name_[FEMALE].empty()) { name_[FEMALE] = (cfg["name"]); } if(chain_size_ <= 0) chain_size_ = 2; //std::vector<std::string> names = ; next_[MALE] = markov_prefixes(utils::split(cfg["male_names"]), chain_size_); next_[FEMALE] = markov_prefixes(utils::split(cfg["female_names"]), chain_size_); }
static std::vector<std::map<std::string, string_map>> parse_list_data(const config& data, const unsigned int req_cols) { std::vector<std::map<std::string, string_map>> list_data; for(const auto & row : data.child_range("row")) { auto cols = row.child_range("column"); VALIDATE(static_cast<unsigned>(cols.size()) == req_cols, _("'list_data' must have the same number of columns as the 'list_definition'.")); for(const auto & c : cols) { list_data.emplace_back(); for(const auto & i : c.attribute_range()) { list_data.back()[""][i.first] = i.second; } for(const auto& w : c.child_range("widget")) { VALIDATE(w.has_attribute("id"), missing_mandatory_wml_key("[list_data][row][column][widget]", "id")); for(const auto& i : w.attribute_range()) { list_data.back()[w["id"]][i.first] = i.second; } } } } return list_data; }
void addon_info::read(const config& cfg) { this->id = cfg["name"].str(); this->title = cfg["title"].str(); this->description = cfg["description"].str(); this->icon = cfg["icon"].str(); this->version = cfg["version"].str(); this->author = cfg["author"].str(); this->size = cfg["size"]; this->downloads = cfg["downloads"]; this->uploads = cfg["uploads"]; this->type = get_addon_type(cfg["type"].str()); const config::const_child_itors& locales_as_configs = cfg.child_range("translation"); for(const config& locale : locales_as_configs) { this->locales.push_back(locale["language"].str()); } this->core = cfg["core"].str(); this->depends = utils::split(cfg["dependencies"].str()); this->feedback_url = cfg["feedback_url"].str(); this->updated = cfg["timestamp"].to_time_t(); this->created = cfg["original_timestamp"].to_time_t(); }
void editor_controller::init_mouse_actions(const config& game_config) { mouse_actions_.insert(std::make_pair(hotkey::HOTKEY_EDITOR_TOOL_PAINT, new mouse_action_paint(foreground_terrain_, background_terrain_, &brush_, key_))); mouse_actions_.insert(std::make_pair(hotkey::HOTKEY_EDITOR_TOOL_FILL, new mouse_action_fill(foreground_terrain_, background_terrain_, key_))); mouse_actions_.insert(std::make_pair(hotkey::HOTKEY_EDITOR_TOOL_SELECT, new mouse_action_select(&brush_, key_))); mouse_actions_.insert(std::make_pair(hotkey::HOTKEY_EDITOR_TOOL_STARTING_POSITION, new mouse_action_starting_position(key_))); mouse_actions_.insert(std::make_pair(hotkey::HOTKEY_EDITOR_PASTE, new mouse_action_paste(clipboard_, key_))); foreach (const theme::menu& menu, gui().get_theme().menus()) { if (menu.items().size() == 1) { hotkey::HOTKEY_COMMAND hk = hotkey::get_hotkey(menu.items().front()).get_id(); mouse_action_map::iterator i = mouse_actions_.find(hk); if (i != mouse_actions_.end()) { i->second->set_toolbar_button(&menu); } } } foreach (const config &c, game_config.child_range("editor_tool_hint")) { mouse_action_map::iterator i = mouse_actions_.find(hotkey::get_hotkey(c["id"]).get_id()); if (i != mouse_actions_.end()) { mouse_action_hints_.insert(std::make_pair(i->first, c["text"])); } } }
void terrain_palette::setup(const config& cfg) { // Get the available terrains temporary in items t_translation::t_list items = map().get_terrain_list(); //move "invalid" items to the end std::stable_partition(items.begin(), items.end(), is_valid_terrain); // Get the available groups and add them to the structure std::set<std::string> group_names; BOOST_FOREACH(const config &group, cfg.child_range("editor_group")) { if (group_names.find(group["id"]) == group_names.end()) { config cfg; cfg["id"] = group["id"]; cfg["name"] = group["name"]; cfg["icon"] = "icons/terrain/terrain_" + group["icon"].str(); cfg["core"] = group["core"]; groups_.push_back(item_group(cfg)); group_names.insert(groups_.back().id); } } std::map<std::string, item_group*> id_to_group; BOOST_FOREACH(item_group& group, groups_) { id_to_group.insert(std::make_pair(group.id, &group)); }
/** * Read the undo_list from the provided config. * Currently, this is only used when the undo_list is empty, but in theory * it could be used to append the config to the current data. */ void undo_list::read(const config & cfg) { // Merge header data. side_ = cfg["side"].to_int(side_); committed_actions_ = committed_actions_ || cfg["committed"].to_bool(); // Build the undo stack. for (const config & child : cfg.child_range("undo")) { try { undo_action_base * action = create_action(child); if ( action ) { undos_.push_back(action); } } catch (bad_lexical_cast &) { ERR_NG << "Error when parsing undo list from config: bad lexical cast." << std::endl; ERR_NG << "config was: " << child.debug() << std::endl; ERR_NG << "Skipping this undo action..." << std::endl; } catch (config::error& e) { ERR_NG << "Error when parsing undo list from config: " << e.what() << std::endl; ERR_NG << "config was: " << child.debug() << std::endl; ERR_NG << "Skipping this undo action..." << std::endl; } } // Build the redo stack. for (const config & child : cfg.child_range("redo")) { try { undo_action_base * action = create_action(child); if ( undo_action* undoable_action = dynamic_cast<undo_action*>(action)) { redos_.push_back(undoable_action); } else { delete action; ERR_NG << "Error: redo contained action that is not undoable" << std::endl; ERR_NG << "config was: " << child.debug() << std::endl; ERR_NG << "Skipping this redo action..." << std::endl; } } catch (bad_lexical_cast &) { ERR_NG << "Error when parsing redo list from config: bad lexical cast." << std::endl; ERR_NG << "config was: " << child.debug() << std::endl; ERR_NG << "Skipping this redo action..." << std::endl; } catch (config::error& e) { ERR_NG << "Error when parsing redo list from config: " << e.what() << std::endl; ERR_NG << "config was: " << child.debug() << std::endl; ERR_NG << "Skipping this redo action..." << std::endl; } } }
editor_controller::editor_controller(const config &game_config, CVideo& video, hero_map& heros, int mode) : controller_base(SDL_GetTicks(), game_config, video) , heros_(heros) , mode_(mode) , mouse_handler_base() , rng_(NULL) , rng_setter_(NULL) , map_contexts_() , current_context_index_(0) , gui_(NULL) , map_generators_() , tods_() , palette_() , floating_label_manager_(NULL) , do_quit_(false) , quit_mode_(EXIT_ERROR) , brushes_() , brush_(NULL) , mouse_actions_() , mouse_action_hints_() , mouse_action_(NULL) , toolbar_dirty_(true) , foreground_terrain_(t_translation::MOUNTAIN) , background_terrain_(t_translation::GRASS_LAND) , clipboard_() , auto_update_transitions_(preferences::editor::auto_update_transitions()) , use_mdi_(preferences::editor::use_mdi()) , default_dir_(preferences::editor::default_dir()) { create_default_context(); if (default_dir_.empty()) { default_dir_ = get_dir(get_dir(get_user_data_dir() + "/editor") + "/maps"); } init_gui(video); init_brushes(game_config); init_mouse_actions(game_config); init_map_generators(game_config); init_tods(game_config); init_sidebar(game_config); init_music(game_config); hotkey_set_mouse_action(gui2::teditor_theme::HOTKEY_EDITOR_TOOL_PAINT); rng_.reset(new rand_rng::rng()); rng_setter_.reset(new rand_rng::set_random_generator(rng_.get())); get_map_context().set_starting_position_labels(gui()); cursor::set(cursor::NORMAL); image::set_color_adjustment(preferences::editor::tod_r(), preferences::editor::tod_g(), preferences::editor::tod_b()); refresh_all(); events::raise_draw_event(); map_type = tmap_type(); if (mode_ != NONE) { BOOST_FOREACH (const config& type, game_config.child_range("map_type")) { const std::string& id = type["id"]; if (mode == SIEGE && id == "siege") { map_type = tmap_type(*gui_, type); } } }
void manager::read_scenario(const config& scenario_cfg) { BOOST_FOREACH(const config &ev, scenario_cfg.child_range("event")) { add_event_handler(ev); } BOOST_FOREACH(const std::string &id, utils::split(scenario_cfg["unit_wml_ids"])) { unit_wml_ids_.insert(id); }
void room_info::process_room_members(const config& data) { members_.clear(); for(const auto & m : data.child_range("member")) { members_.insert(m["name"]); } }
void config::append_children(const config &cfg, const std::string& key) { check_valid(cfg); for (const config &value : cfg.child_range(key)) { add_child(key, value); } }
void config::append_children(const config &cfg, const std::string& key) { check_valid(cfg); BOOST_FOREACH(const config &value, cfg.child_range(key)) { add_child(key, value); } }
void add_color_info(const config &v) { BOOST_FOREACH (const config &teamC, v.child_range("color_range")) { const config::attribute_value *a1 = teamC.get("id"), *a2 = teamC.get("rgb"); if (!a1 || !a2) continue; std::string id = *a1; std::vector<Uint32> temp = string2rgb(*a2); team_rgb_range.insert(std::make_pair(id,color_range(temp))); team_rgb_name.push_back(std::make_pair(id, teamC["name"].t_str())); //generate palette of same name; std::vector<Uint32> tp = palette(team_rgb_range[id]); if (tp.empty()) continue; team_rgb_colors.insert(std::make_pair(id,tp)); //if this is being used, output log of palette for artists use. std::ostringstream str; str << id << " = "; for (std::vector<Uint32>::const_iterator r = tp.begin(), r_end = tp.end(), r_beg = r; r != r_end; ++r) { int red = ((*r) & 0x00FF0000) >> 16; int green = ((*r) & 0x0000FF00) >> 8; int blue = ((*r) & 0x000000FF); if (r != r_beg) str << ','; str << red << ',' << green << ',' << blue; } } std::map<std::string, color_range >& team_rgb_range_p = team_rgb_range; std::vector<std::pair<std::string, t_string > >& team_rgb_name_p = team_rgb_name; std::map<std::string, std::vector<Uint32> >& team_rgb_colors_p = team_rgb_colors; BOOST_FOREACH (const config &cp, v.child_range("color_palette")) { BOOST_FOREACH (const config::attribute &rgb, cp.attribute_range()) { try { team_rgb_colors.insert(std::make_pair(rgb.first, string2rgb(rgb.second))); } catch (bad_lexical_cast&) { // throw config::error(_("Invalid team color: ") + rgb_it->second); // ERR_NG << "Invalid team color: " << rgb.second << "\n"; } } } }
void room_info::process_room_members(const config& data) { members_.clear(); FOREACH(const AUTO & m, data.child_range("member")) { members_.insert(m["name"]); } }
/** * Returns a config with all partial resolutions of a theme expanded. * * @param theme The original object, whose objects need to be * expanded. * * @returns A new object with the expanded resolutions in * a theme. This object no longer contains * partial resolutions. */ static config expand_partialresolution(const config& theme) { config result; // Add all the resolutions for(const auto& resolution : theme.child_range("resolution")) { result.add_child("resolution", resolution); } // Resolve all the partialresolutions for(const auto& part : theme.child_range("partialresolution")) { config resolution = get_resolution(result, part["inherits"]); resolution.merge_attributes(part); for(const auto& remove : part.child_range("remove")) { VALIDATE(!remove["id"].empty() , missing_mandatory_wml_key( "[theme][partialresolution][remove]" , "id")); find_ref(remove["id"], resolution, true); } for(const auto& change : part.child_range("change")) { VALIDATE(!change["id"].empty() , missing_mandatory_wml_key( "[theme][partialresolution][change]" , "id")); config& target = find_ref(change["id"], resolution, false); target.merge_attributes(change); } // cannot add [status] sub-elements, but who cares for(const auto& add : part.child_range("add")) { for(const auto& child : add.all_children_range()) { resolution.add_child(child.key, child.cfg); } } result.add_child("resolution", resolution); } return result; }
static void unarchive_dir(const std::string& path, const config& cfg) { std::string dir; if (cfg["name"].empty()) dir = path; else dir = path + '/' + cfg["name"].str(); make_directory(dir); BOOST_FOREACH(const config &d, cfg.child_range("dir")) { unarchive_dir(dir, d); } BOOST_FOREACH(const config &f, cfg.child_range("file")) { unarchive_file(dir, f); } }
void read_stats(const config& cfg) { fresh_stats(); mid_scenario = cfg["mid_scenario"].to_bool(); BOOST_FOREACH(const config &s, cfg.child_range("scenario")) { master_stats.push_back(scenario_stats(s)); } }
static void unarchive_dir(const std::string& path, const config& cfg) { std::string dir; if (cfg["name"].empty()) dir = path; else dir = path + '/' + cfg["name"].str(); filesystem::make_directory(dir); for(const config &d : cfg.child_range("dir")) { unarchive_dir(dir, d); } for(const config &f : cfg.child_range("file")) { unarchive_file(dir, f); } }
void theme::modify(const config &cfg) { std::map<std::string,std::string> title_stash; std::vector<theme::menu>::iterator m; for (m = menus_.begin(); m != menus_.end(); ++m) { if (!m->title().empty() && !m->get_id().empty()) title_stash[m->get_id()] = m->title(); } std::vector<theme::action>::iterator a; for (a = actions_.begin(); a != actions_.end(); ++a) { if (!a->title().empty() && !a->get_id().empty()) title_stash[a->get_id()] = a->title(); } // Change existing theme objects. for(const config &c : cfg.child_range("change")) { std::string id = c["id"]; std::string ref_id = c["ref"]; theme::object &element = find_element(id); if (element.get_id() == id) set_object_location(element, c["rect"], ref_id); } // Add new theme objects. for(const config &c : cfg.child_range("add")) { add_object(c); } // Remove existent theme objects. for(const config &c : cfg.child_range("remove")) { remove_object(c["id"]); } for (m = menus_.begin(); m != menus_.end(); ++m) { if (title_stash.find(m->get_id()) != title_stash.end()) m->set_title(title_stash[m->get_id()]); } for (a = actions_.begin(); a != actions_.end(); ++a) { if (title_stash.find(a->get_id()) != title_stash.end()) a->set_title(title_stash[a->get_id()]); } }
void load_hotkeys(const config& cfg) { BOOST_FOREACH (const config &hk, cfg.child_range(hotkey_tag_name)) { hotkey_item& h = get_hotkey(hk["command"].str()); if(h.get_id() != HOTKEY_NULL) { h.load_from_config(hk); } } }
builder_menu_button::builder_menu_button(const config& cfg) : builder_styled_widget(cfg) , retval_id_(cfg["return_value_id"]) , retval_(cfg["return_value"]) , options_() { for(const auto& option : cfg.child_range("option")) { options_.push_back(option); } }
void load_hotkeys(const config& cfg) { foreach (const config &hk, cfg.child_range(hotkey_tag_name)) { hotkey_item& h = get_hotkey(hk["command"]); if(h.get_id() != HOTKEY_NULL) { h.load_from_config(hk); } } }
/** * Returns a copy of the wanted resolution. * * The function returns a copy since our caller uses a copy of this resolution * as base to expand a partial resolution. * * @param resolutions A config object containing the expanded * resolutions. * @param id The id of the resolution to return. * * @throw config::error If the @p id is not found. * * @returns A copy of the resolution config. */ static config get_resolution(const config& resolutions, const std::string& id) { for(const auto& resolution : resolutions.child_range("resolution")) { if(resolution["id"] == id) { return resolution; } } throw config::error("[partialresolution] refers to non-existent [resolution] " + id); }
cutter::surface_map cutter::cut_surface(surface surf, const config& conf) { surface_map res; BOOST_FOREACH(const config &part, conf.child_range("part")) { add_sub_image(surf, res, &part); } return res; }
/** Go to the next tips-of-the-day */ static void next_tip_of_day(config& tips_of_day, bool reverse = false) { // we just rotate the tip list, to avoid the need to keep track // of the current one, and keep it valid, cycle it, etc... config::child_itors tips = tips_of_day.child_range("tip"); if (tips.first != tips.second) { config::child_iterator direction = reverse ? tips.first+1 : tips.second-1; std::rotate(tips.first, direction, tips.second); } }
// config就三个成员变量, values, children, orderer_children. orderer_child_ren可由children推出 // config被组织成一个树状结构 void wml_config_to_file(const std::string &fname, config &cfg, uint32_t nfiles, uint32_t sum_size, uint32_t modified) { posix_file_t fp = INVALID_FILE; uint32_t max_str_len, bytertd, u32n; std::vector<std::string> tdomain; posix_print("<xwml.cpp>::wml_config_to_file------fname: %s\n", fname.c_str()); posix_fopen(fname.c_str(), GENERIC_WRITE, CREATE_ALWAYS, fp); if (fp == INVALID_FILE) { posix_print("------<xwml.cpp>::wml_config_to_file, cannot create %s for wrtie\n", fname.c_str()); goto exit; } // max_str_len = posix_max(WMLBIN_MARK_CONFIG_LEN, WMLBIN_MARK_VALUE_LEN); posix_fseek(fp, 16 + sizeof(max_str_len) + sizeof(u32n), 0); // write [textdomain] BOOST_FOREACH (const config &d, cfg.child_range("textdomain")) { if (std::find(tdomain.begin(), tdomain.end(), d.get("name")->str()) != tdomain.end()) { continue; } tdomain.push_back(d.get("name")->str()); u32n = tdomain.back().size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, tdomain.back().c_str(), u32n, bytertd); } wml_config_to_fp(fp, cfg, &max_str_len, tdomain, 0); // update max_str_len/textdomain_count posix_fseek(fp, 0, 0); // 0--15 u32n = mmioFOURCC('X', 'W', 'M', 'L'); posix_fwrite(fp, &u32n, 4, bytertd); posix_fwrite(fp, &nfiles, 4, bytertd); posix_fwrite(fp, &sum_size, 4, bytertd); posix_fwrite(fp, &modified, 4, bytertd); // 16--19(max_str_len) posix_fwrite(fp, &max_str_len, sizeof(max_str_len), bytertd); // 20--23(textdomain_count) u32n = tdomain.size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_print("------<xwml.cpp>::wml_config_to_file, return\n"); exit: if (fp != INVALID_FILE) { posix_fclose(fp); } return; }