11#include < variant>
2+ #include < functional>
23
34#include " Debug.h"
45#include " LuaTools.h"
1314#include " df/widget_unit_list.h"
1415#include " df/world.h"
1516
17+
1618using std::vector;
1719using std::string;
1820
@@ -28,7 +30,8 @@ namespace DFHack {
2830}
2931
3032using item_or_unit = std::variant<df::unit*, df::item*>;
31- using filter_vec_type = std::vector<std::function<bool (item_or_unit)>>;
33+ using filter_func = bool (item_or_unit);
34+ using filter_vec_type = std::vector<std::function<filter_func>>;
3235
3336// recreated here since our autogenerated df::sort_entry lacks template params
3437struct sort_entry {
@@ -42,19 +45,10 @@ static const string DFHACK_SORT_IDENT = "dfhack_sort";
4245// filter logic
4346//
4447
45- static bool probing = false ;
46- static bool probe_result = false ;
47-
4848static bool do_filter (const char *module_name, const char *fn_name, const item_or_unit &elem) {
4949 if (std::holds_alternative<df::item*>(elem)) return true ;
5050 auto unit = std::get<df::unit*>(elem);
5151
52- if (probing) {
53- TRACE (log).print (" probe successful\n " );
54- probe_result = true ;
55- return false ;
56- }
57-
5852 bool ret = true ;
5953 color_ostream &out = Core::getInstance ().getConsole ();
6054 Lua::CallLuaModuleFunction (out, module_name, fn_name, std::make_tuple (unit),
@@ -78,35 +72,28 @@ static bool do_work_animal_assignment_filter(item_or_unit elem) {
7872 return do_filter (" plugins.sort.info" , " do_work_animal_assignment_filter" , elem);
7973}
8074
81- static int32_t our_filter_idx (df::widget_unit_list *unitlist) {
82- if (world->units .active .empty ())
83- return -1 ;
84-
85- df::unit *u = world->units .active [0 ]; // any unit will do; we just need a sentinel
86- if (!u)
87- return -1 ;
88-
89- probing = true ;
90- probe_result = false ;
75+ static int32_t our_filter_idx (filter_func* filter, df::widget_unit_list* unitlist)
76+ {
9177 int32_t idx = 0 ;
9278
93- filter_vec_type * filter_vec = reinterpret_cast <filter_vec_type *>(&unitlist->filter_func );
79+ filter_vec_type* filter_vec = reinterpret_cast <filter_vec_type*>(&unitlist->filter_func );
9480
9581 TRACE (log).print (" probing for our filter function\n " );
96- for (auto & fn : *filter_vec) {
97- fn (item_or_unit (u));
98- if (probe_result) {
82+
83+ for (auto & fn : *filter_vec)
84+ {
85+ auto t = fn.target <decltype (filter)>();
86+ if (t && *t == filter)
87+ {
9988 TRACE (log).print (" found our filter function at idx %d\n " , idx);
100- break ;
89+ return idx ;
10190 }
10291 ++idx;
10392 }
104-
105- probing = false ;
106- return probe_result ? idx : -1 ;
93+ return -1 ;
10794}
10895
109- static df::widget_unit_list * get_squad_unit_list () {
96+ static df::widget_unit_list* get_squad_unit_list () {
11097 return virtual_cast<df::widget_unit_list>(
11198 Gui::getWidget (&game->main_interface .unit_selector , " Unit selector" ));
11299}
@@ -182,8 +169,8 @@ DFhackCExport command_result plugin_init(color_ostream &out, vector<PluginComman
182169 return CR_OK;
183170}
184171
185- static void remove_filter_function (color_ostream &out, const char *which, df::widget_unit_list *unitlist) {
186- int32_t idx = our_filter_idx (unitlist);
172+ static void remove_filter_function (color_ostream &out, filter_func* filter, const char *which, df::widget_unit_list *unitlist) {
173+ int32_t idx = our_filter_idx (filter, unitlist);
187174 if (idx >= 0 ) {
188175 DEBUG (log,out).print (" removing %s filter function\n " , which);
189176 filter_vec_type *filter_vec = reinterpret_cast <filter_vec_type *>(&unitlist->filter_func );
@@ -202,22 +189,22 @@ static void remove_sort_function(color_ostream &out, const char *which, df::widg
202189
203190DFhackCExport command_result plugin_shutdown (color_ostream &out) {
204191 if (auto unitlist = get_squad_unit_list ()) {
205- remove_filter_function (out, " squad" , unitlist);
192+ remove_filter_function (out, do_squad_filter, " squad" , unitlist);
206193 remove_sort_function (out, " squad" , unitlist);
207194 }
208195
209196 if (auto unitlist = get_interrogate_unit_list (" Open cases" ))
210- remove_filter_function (out, " open cases interrogate" , unitlist);
197+ remove_filter_function (out, do_justice_filter, " open cases interrogate" , unitlist);
211198 if (auto unitlist = get_interrogate_unit_list (" Cold cases" ))
212- remove_filter_function (out, " cold cases interrogate" , unitlist);
199+ remove_filter_function (out, do_justice_filter, " cold cases interrogate" , unitlist);
213200
214201 if (auto unitlist = get_convict_unit_list (" Open cases" ))
215- remove_filter_function (out, " open cases convict" , unitlist);
202+ remove_filter_function (out, do_justice_filter, " open cases convict" , unitlist);
216203 if (auto unitlist = get_convict_unit_list (" Cold cases" ))
217- remove_filter_function (out, " cold cases convict" , unitlist);
204+ remove_filter_function (out, do_justice_filter, " cold cases convict" , unitlist);
218205
219206 if (auto unitlist = get_work_animal_assignment_unit_list ())
220- remove_filter_function (out, " work animal assignment" , unitlist);
207+ remove_filter_function (out, do_work_animal_assignment_filter, " work animal assignment" , unitlist);
221208
222209 return CR_OK;
223210}
@@ -228,7 +215,7 @@ DFhackCExport command_result plugin_shutdown(color_ostream &out) {
228215
229216static void sort_set_squad_filter_fn (color_ostream &out) {
230217 auto unitlist = get_squad_unit_list ();
231- if (unitlist && our_filter_idx (unitlist) == -1 ) {
218+ if (unitlist && our_filter_idx (do_squad_filter, unitlist) == -1 ) {
232219 DEBUG (log).print (" adding squad filter function\n " );
233220 auto filter_vec = reinterpret_cast <filter_vec_type *>(&unitlist->filter_func );
234221 filter_vec->emplace_back (do_squad_filter);
@@ -240,7 +227,7 @@ static void sort_set_squad_filter_fn(color_ostream &out) {
240227}
241228
242229static void sort_set_justice_filter_fn (color_ostream &out, df::widget_unit_list *unitlist) {
243- if (unitlist && our_filter_idx (unitlist) == -1 ) {
230+ if (unitlist && our_filter_idx (do_justice_filter, unitlist) == -1 ) {
244231 DEBUG (log).print (" adding justice filter function\n " );
245232 auto filter_vec = reinterpret_cast <filter_vec_type *>(&unitlist->filter_func );
246233 filter_vec->emplace_back (do_justice_filter);
@@ -249,7 +236,7 @@ static void sort_set_justice_filter_fn(color_ostream &out, df::widget_unit_list
249236}
250237
251238static void sort_set_work_animal_assignment_filter_fn (color_ostream &out, df::widget_unit_list *unitlist) {
252- if (unitlist && our_filter_idx (unitlist) == -1 ) {
239+ if (unitlist && our_filter_idx (do_work_animal_assignment_filter, unitlist) == -1 ) {
253240 DEBUG (log).print (" adding work animal assignment filter function\n " );
254241 auto filter_vec = reinterpret_cast <filter_vec_type *>(&unitlist->filter_func );
255242 filter_vec->emplace_back (do_work_animal_assignment_filter);
0 commit comments