bool basic_unit_filter_impl::matches(const unit & u, const map_location& loc, const unit * u2) const { bool matches = true; if(loc.valid()) { scoped_xy_unit auto_store("this_unit", loc, fc_.get_disp_context().units()); if (u2) { const map_location& loc2 = u2->get_location(); scoped_xy_unit auto_store("other_unit", loc2, fc_.get_disp_context().units()); matches = internal_matches_filter(u, loc, u2); } else { matches = internal_matches_filter(u, loc, u2); } } else { // If loc is invalid, then this is a recall list unit (already been scoped) matches = internal_matches_filter(u, loc, nullptr); } // Handle [and], [or], and [not] with in-order precedence for (size_t i = 0; i < cond_children_.size(); i++) { switch (cond_child_types_[i].v) { case conditional::TYPE::AND: matches = matches && cond_children_[i].matches(u,loc); break; case conditional::TYPE::OR: matches = matches || cond_children_[i].matches(u,loc); break; case conditional::TYPE::NOT: matches = matches && !cond_children_[i].matches(u,loc); } } return matches; }
static error_t vfl_vsvfl_get_info(vfl_device_t *_vfl, vfl_info_t _item, void *_result, size_t _sz) { vfl_vsvfl_device_t *vfl = CONTAINER_OF(vfl_vsvfl_device_t, vfl, _vfl); nand_device_t *nand = vfl->device; if(_sz > 4 || _sz == 3) { return EINVAL; } switch(_item) { case diPagesPerBlockTotalBanks: auto_store(_result, _sz, vfl->geometry.pages_per_sublk); return SUCCESS; case diSomeThingFromVFLCXT: auto_store(_result, _sz, vfl->contexts[0].usable_blocks_per_bank); return SUCCESS; case diFTLType: auto_store(_result, _sz, vfl->contexts[0].ftl_type); return SUCCESS; case diBytesPerPageFTL: nand_device_get_info(nand, diBytesPerPage, _result, _sz); return SUCCESS; case diMetaBytes0xC: auto_store(_result, _sz, 0xC); return SUCCESS; case diUnkn20_1: auto_store(_result, _sz, 1); return SUCCESS; case diTotalBanks: nand_device_get_info(nand, diTotalBanks_VFL, _result, _sz); return SUCCESS; default: return ENOENT; } }
bool have_unit(const vconfig& cfg) { if(resources::units == nullptr) { return false; } std::vector<std::pair<int,int> > counts = cfg.has_attribute("count") ? utils::parse_ranges(cfg["count"]) : default_counts; int match_count = 0; const unit_filter ufilt(cfg, resources::filter_con); for(const unit &i : *resources::units) { if(i.hitpoints() > 0 && ufilt(i)) { ++match_count; if(counts == default_counts) { // by default a single match is enough, so avoid extra work break; } } } if(cfg["search_recall_list"].to_bool()) { for(const team& team : resources::gameboard->teams()) { if(counts == default_counts && match_count) { break; } for(size_t t = 0; t < team.recall_list().size(); ++t) { if(counts == default_counts && match_count) { break; } scoped_recall_unit auto_store("this_unit", team.save_id(), t); if(ufilt(*team.recall_list()[t])) { ++match_count; } } } } return in_ranges(match_count, counts); }