From 79d2cb1a5cef1c94137264b4f0de135bd0f4c841 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 25 Oct 2012 12:44:23 +0400 Subject: [PATCH] Remove the C++ version of the job output deduction code and switch to lua. --- dfhack.init-example | 2 +- plugins/lua/workflow.lua | 18 +++- plugins/workflow.cpp | 191 ++++++--------------------------------- 3 files changed, 44 insertions(+), 167 deletions(-) diff --git a/dfhack.init-example b/dfhack.init-example index d4c7dc233..2cdb114be 100644 --- a/dfhack.init-example +++ b/dfhack.init-example @@ -79,7 +79,7 @@ keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job # workflow front-end -keybinding add Ctrl-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow +keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow ############################ # UI and game logic tweaks # diff --git a/plugins/lua/workflow.lua b/plugins/lua/workflow.lua index 391045a96..4c011b24c 100644 --- a/plugins/lua/workflow.lua +++ b/plugins/lua/workflow.lua @@ -64,12 +64,12 @@ function job_outputs.CustomReaction(callback, job) end if get_mat_prod then + local p_code = prod.get_material.product_code local mat = dfhack.matinfo.decode(mat_type, mat_index) mat_type, mat_index = -1, -1 if mat then - local p_code = prod.get_material.product_code local rp = mat.material.reaction_product local idx = utils.linear_index(rp.id, p_code) if not idx then @@ -77,7 +77,7 @@ function job_outputs.CustomReaction(callback, job) end mat_type, mat_index = rp.material.mat_type[idx], rp.material.mat_index[idx] else - if code == "SOAP_MAT" then + if p_code == "SOAP_MAT" then mat_mask = { soap = true } end end @@ -106,7 +106,7 @@ local function guess_job_material(job) local jmat = df.job_type.attrs[job.job_type].material if jmat then mat_type, mat_index = df.builtin_mats[jmat] or -1, -1 - if mat_type < 0 and df.job_material_category[jmat] then + if mat_type < 0 and df.dfhack_material_category[jmat] then mat_mask = { [jmat] = true } end end @@ -220,6 +220,18 @@ local function enum_job_outputs(callback, job) end end +function doEnumJobOutputs(native_cb, job) + local function cb(info) + native_cb( + info.item_type, info.item_subtype, + info.mat_mask, info.mat_type, info.mat_index, + info.is_craft + ) + end + + enum_job_outputs(cb, job) +end + function listJobOutputs(job) local res = {} enum_job_outputs(curry(table.insert, res), job) diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 19709b68c..8280adb54 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -379,13 +379,6 @@ static bool isSupportedJob(df::job *job) job->job_type == job_type::CollectSand); } -static void enumLiveJobs(std::map &rv) -{ - df::job_list_link *p = world->job_list.next; - for (; p; p = p->next) - rv[p->item->id] = p->item; -} - static bool isOptionEnabled(unsigned flag) { return config.isValid() && (config.ival(0) & flag) != 0; @@ -828,71 +821,6 @@ static void link_job_constraint(ProtectedJob *pj, df::item_type itype, int16_t i } } -static void compute_custom_job(ProtectedJob *pj, df::job *job) -{ - if (pj->reaction_id < 0) - pj->reaction_id = linear_index(df::reaction::get_vector(), - &df::reaction::code, job->reaction_name); - - df::reaction *r = df::reaction::find(pj->reaction_id); - if (!r) - return; - - for (size_t i = 0; i < r->products.size(); i++) - { - using namespace df::enums::reaction_product_item_flags; - - VIRTUAL_CAST_VAR(prod, df::reaction_product_itemst, r->products[i]); - if (!prod || (prod->item_type < (df::item_type)0 && !prod->flags.is_set(CRAFTS))) - continue; - - MaterialInfo mat(prod); - df::dfhack_material_category mat_mask(0); - - bool get_mat_prod = prod->flags.is_set(GET_MATERIAL_PRODUCT); - if (get_mat_prod || prod->flags.is_set(GET_MATERIAL_SAME)) - { - int reagent_idx = linear_index(r->reagents, &df::reaction_reagent::code, - prod->get_material.reagent_code); - if (reagent_idx < 0) - continue; - - int item_idx = linear_index(job->job_items, &df::job_item::reagent_index, reagent_idx); - if (item_idx >= 0) - mat.decode(job->job_items[item_idx]); - else - { - VIRTUAL_CAST_VAR(src, df::reaction_reagent_itemst, r->reagents[reagent_idx]); - if (!src) - continue; - mat.decode(src); - } - - if (get_mat_prod) - { - std::string code = prod->get_material.product_code; - - if (mat.isValid()) - { - int idx = linear_index(mat.material->reaction_product.id, code); - if (idx < 0) - continue; - - mat.decode(mat.material->reaction_product.material, idx); - } - else - { - if (code == "SOAP_MAT") - mat_mask.bits.soap = true; - } - } - } - - link_job_constraint(pj, prod->item_type, prod->item_subtype, - mat_mask, mat.type, mat.index, prod->flags.is_set(CRAFTS)); - } -} - static void guess_job_material(df::job *job, MaterialInfo &mat, df::dfhack_material_category &mat_mask) { using namespace df::enums::job_type; @@ -934,100 +862,24 @@ static void guess_job_material(df::job *job, MaterialInfo &mat, df::dfhack_mater } } -static void compute_job_outputs(color_ostream &out, ProtectedJob *pj) +static int cbEnumJobOutputs(lua_State *L) { - using namespace df::enums::job_type; - - // Custom reactions handled in another function - df::job *job = pj->job_copy; - - if (job->job_type == CustomReaction) - { - compute_custom_job(pj, job); - return; - } - - // Item type & subtype - df::item_type itype = ENUM_ATTR(job_type, item, job->job_type); - int16_t isubtype = job->item_subtype; - - if (itype == item_type::NONE && job->job_type != MakeCrafts) - return; - - // Item material & material category - MaterialInfo mat; - df::dfhack_material_category mat_mask; - guess_job_material(job, mat, mat_mask); - - // Job-specific code - switch (job->job_type) - { - case SmeltOre: - if (mat.inorganic) - { - std::vector &ores = mat.inorganic->metal_ore.mat_index; - for (size_t i = 0; i < ores.size(); i++) - link_job_constraint(pj, item_type::BAR, -1, 0, 0, ores[i]); - } - return; + auto pj = (ProtectedJob*)lua_touserdata(L, lua_upvalueindex(1)); - case ExtractMetalStrands: - if (mat.inorganic) - { - std::vector &threads = mat.inorganic->thread_metal.mat_index; - for (size_t i = 0; i < threads.size(); i++) - link_job_constraint(pj, item_type::THREAD, -1, 0, 0, threads[i]); - } - return; + lua_settop(L, 6); - case PrepareMeal: - if (job->mat_type != -1) - { - std::vector &food = df::itemdef_foodst::get_vector(); - for (size_t i = 0; i < food.size(); i++) - if (food[i]->level == job->mat_type) - link_job_constraint(pj, item_type::FOOD, i, 0, -1, -1); - return; - } - break; - - case MakeCrafts: - link_job_constraint(pj, item_type::NONE, -1, mat_mask, mat.type, mat.index, true); - return; - -#define PLANT_PROCESS_MAT(flag, tag) \ - if (mat.plant && mat.plant->flags.is_set(plant_raw_flags::flag)) \ - mat.decode(mat.plant->material_defs.type_##tag, \ - mat.plant->material_defs.idx_##tag); \ - else mat.decode(-1); - case BrewDrink: - PLANT_PROCESS_MAT(DRINK, drink); - break; - case MillPlants: - PLANT_PROCESS_MAT(MILL, mill); - break; - case ProcessPlants: - PLANT_PROCESS_MAT(THREAD, thread); - break; - case ProcessPlantsBag: - PLANT_PROCESS_MAT(LEAVES, leaves); - break; - case ProcessPlantsBarrel: - PLANT_PROCESS_MAT(EXTRACT_BARREL, extract_barrel); - break; - case ProcessPlantsVial: - PLANT_PROCESS_MAT(EXTRACT_VIAL, extract_vial); - break; - case ExtractFromPlants: - PLANT_PROCESS_MAT(EXTRACT_STILL_VIAL, extract_still_vial); - break; -#undef PLANT_PROCESS_MAT + df::dfhack_material_category mat_mask(0); + if (!lua_isnil(L, 3)) + Lua::CheckDFAssign(L, &mat_mask, 3); - default: - break; - } + link_job_constraint( + pj, + (df::item_type)luaL_optint(L, 1, -1), luaL_optint(L, 2, -1), + mat_mask, luaL_optint(L, 4, -1), luaL_optint(L, 5, -1), + lua_toboolean(L, 6) + ); - link_job_constraint(pj, itype, isubtype, mat_mask, mat.type, mat.index); + return 0; } static void map_job_constraints(color_ostream &out) @@ -1040,19 +892,32 @@ static void map_job_constraints(color_ostream &out) constraints[i]->is_active = false; } + auto L = Lua::Core::State; + Lua::StackUnwinder frame(L); + + bool ok = Lua::PushModulePublic(out, L, "plugins.workflow", "doEnumJobOutputs"); + if (!ok) + out.printerr("The workflow lua module is not available.\n"); + for (TKnownJobs::const_iterator it = known_jobs.begin(); it != known_jobs.end(); ++it) { ProtectedJob *pj = it->second; pj->constraints.clear(); - if (!pj->isLive()) + if (!ok || !pj->isLive()) continue; if (!melt_active && pj->actual_job->job_type == job_type::MeltMetalObject) melt_active = pj->isResumed(); - compute_job_outputs(out, pj); + // Call the lua module + lua_pushvalue(L, -1); + lua_pushlightuserdata(L, pj); + lua_pushcclosure(L, cbEnumJobOutputs, 1); + Lua::PushDFObject(L, pj->job_copy); + + Lua::SafeCall(out, L, 2, 0); } }