/** * Returns whether or not *this matches the given @a filter. */ bool attack_type::matches_filter(const config& filter) const { // Handle the basic filter. bool matches = matches_simple_filter(*this, filter); // Handle [and], [or], and [not] with in-order precedence BOOST_FOREACH( const config::any_child &condition, filter.all_children_range() ) { // Handle [and] if ( condition.key == "and" ) matches = matches && matches_filter(condition.cfg); // Handle [or] else if ( condition.key == "or" ) matches = matches || matches_filter(condition.cfg); // Handle [not] else if ( condition.key == "not" ) matches = matches && !matches_filter(condition.cfg); } return matches; }
static void write_internal(config const &cfg, std::ostream &out, std::string& textdomain, size_t tab = 0) { if (tab > max_recursion_levels) throw config::error("Too many recursion levels in config write"); for (const config::attribute &i : cfg.attribute_range()) { if (!config::valid_id(i.first)) { ERR_CF << "Config contains invalid attribute name '" << i.first << "', skipping...\n"; continue; } write_key_val(out, i.first, i.second, tab, textdomain); } for (const config::any_child &item : cfg.all_children_range()) { if (!config::valid_id(item.key)) { ERR_CF << "Config contains invalid tag name '" << item.key << "', skipping...\n"; continue; } write_open_child(out, item.key, tab); write_internal(item.cfg, out, textdomain, tab + 1); write_close_child(out, item.key, tab); } }
tbuilder_widget_ptr create_builder_widget(const config& cfg) { config::all_children_itors children = cfg.all_children_range(); size_t nb_children = std::distance(children.first, children.second); VALIDATE(nb_children == 1, "Grid cell does not have exactly 1 child."); typedef std::pair< std::string , boost::function<tbuilder_widget_ptr(config)> > thack; BOOST_FOREACH(const thack& item, builder_widget_lookup()) { if (item.first == "window" || item.first == "tooltip") { continue; } if (const config& c = cfg.child(item.first)) { return item.second(c); } } if(const config &c = cfg.child("grid")) { return new tbuilder_grid(c); } /* * This is rather odd, when commented out the classes no longer seem to be in * the executable, no real idea why, except maybe of an overzealous optimizer * while linking. It seems that all these classes aren't explicitly * instantiated but only implicitly. Also when looking at the symbols in * libwesnoth-game.a the repeating button is there regardless of this #if but * in the final binary only if the #if is enabled. * * If this code is executed, which it will cause an assertion failure. */ #if 1 #define TRY(name) \ do { \ if(const config &c = cfg.child(#name)) { \ tbuilder_widget_ptr p = new implementation::tbuilder_##name(c);\ assert(false); \ } \ } while (0) TRY(stacked_widget); TRY(scrollbar_panel); TRY(horizontal_scrollbar); TRY(vertical_scrollbar); TRY(label); TRY(report); TRY(image); TRY(toggle_button); TRY(slider); TRY(scroll_label); TRY(scroll_text_box); TRY(minimap); TRY(button); TRY(drawing); TRY(password_box); TRY(progress_bar); TRY(tree_view); TRY(track); #undef TRY #endif std::cerr << cfg; ERROR_LOG(false); }
tbuilder_widget_ptr create_builder_widget(const config& cfg) { config::all_children_itors children = cfg.all_children_range(); size_t nb_children = std::distance(children.first, children.second); VALIDATE(nb_children == 1, "Grid cell does not have exactly 1 child."); for(const auto & item : builder_widget_lookup()) { if(item.first == "window" || item.first == "tooltip") { continue; } if(const config& c = cfg.child(item.first)) { return item.second(c); } } if(const config& c = cfg.child("grid")) { return new tbuilder_grid(c); } if(const config& instance = cfg.child("instance")) { return new implementation::tbuilder_instance(instance); } if(const config& pane = cfg.child("pane")) { return new implementation::tbuilder_pane(pane); } if(const config& viewport = cfg.child("viewport")) { return new implementation::tbuilder_viewport(viewport); } /* * This is rather odd, when commented out the classes no longer seem to be in * the executable, no real idea why, except maybe of an overzealous optimizer * while linking. It seems that all these classes aren't explicitly * instantiated but only implicitly. Also when looking at the symbols in * libwesnoth-game.a the repeating button is there regardless of this #if but * in the final binary only if the #if is enabled. * * If this code is executed, which it will cause an assertion failure. * * Its likeley that this happens becasue some build this as a library file * which is then used by the wesnoth executable. For msvc a good try to fix * this issue is to add __pragma(comment(linker, "/include:" #TYPE)) or * similar in the REGISTER_WIDGET3 macro. For gcc and similar this can only * be fixed by using --whole-archive flag when linking this library. */ #if 1 #define TRY(name) \ do { \ if(const config& c = cfg.child(#name)) { \ tbuilder_widget_ptr p = new implementation::tbuilder_##name(c); \ assert(false); \ } \ } while(0) TRY(stacked_widget); TRY(scrollbar_panel); TRY(horizontal_scrollbar); TRY(repeating_button); TRY(vertical_scrollbar); TRY(label); TRY(image); TRY(toggle_button); TRY(slider); TRY(scroll_label); TRY(matrix); TRY(minimap); TRY(button); TRY(combobox); TRY(drawing); TRY(password_box); TRY(unit_preview_pane); #undef TRY #endif std::cerr << cfg; ERROR_LOG(false); }
// @deep: 嵌套深度, 顶层: 0 void wml_config_to_fp(posix_file_t fp, const config &cfg, uint32_t *max_str_len, std::vector<std::string> &td, uint16_t deep) { uint32_t u32n, bytertd; int first; // config::child_list::const_iterator ichildlist; // string_map::const_iterator istrmap; // recursively resolve children BOOST_FOREACH (const config::any_child &value, cfg.all_children_range()) { // save {[cfg]}{len}{name} posix_fwrite(fp, WMLBIN_MARK_CONFIG, WMLBIN_MARK_CONFIG_LEN, bytertd); u32n = posix_mku32(value.key.size(), deep); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, value.key.c_str(), posix_lo16(u32n), bytertd); *max_str_len = posix_max(*max_str_len, value.key.size()); // save {[val]}{len}{name0}{len}{val0}{len}{name1}{len}{val1}{...} // string_map &values = value.cfg.gvalues(); // for (istrmap = values.begin(); istrmap != values.end(); istrmap ++) { first = 1; BOOST_FOREACH (const config::attribute &istrmap, value.cfg.attribute_range()) { if (first) { posix_fwrite(fp, WMLBIN_MARK_VALUE, WMLBIN_MARK_VALUE_LEN, bytertd); first = 0; } u32n = istrmap.first.size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, istrmap.first.c_str(), u32n, bytertd); *max_str_len = posix_max(*max_str_len, u32n); if (istrmap.second.t_str().translatable()) { // parse translatable string std::vector<t_string_base::trans_str> trans = istrmap.second.t_str().valuex(); for (std::vector<t_string_base::trans_str>::const_iterator ti = trans.begin(); ti != trans.end(); ti ++) { if (ti == trans.begin()) { if (ti->td.empty()) { u32n = posix_mku32(0, posix_mku16(0, trans.size())); } else { u32n = posix_mku32(0, posix_mku16(tstring_textdomain_idx(ti->td.c_str(), td), trans.size())); } } else { if (ti->td.empty()) { u32n = posix_mku32(0, 0); } else { u32n = posix_mku32(0, posix_mku16(tstring_textdomain_idx(ti->td.c_str(), td), 0)); } } // flag posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); // length of value u32n = ti->str.size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, ti->str.c_str(), u32n, bytertd); } } else { // flag u32n = 0; posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); // length of value u32n = istrmap.second.str().size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, istrmap.second.str().c_str(), u32n, bytertd); } *max_str_len = posix_max(*max_str_len, u32n); } wml_config_to_fp(fp, value.cfg, max_str_len, td, deep + 1); } return; }