diff --git a/plugins/lua/workflow.lua b/plugins/lua/workflow.lua index 19ca0a84a..b3bcf3d08 100644 --- a/plugins/lua/workflow.lua +++ b/plugins/lua/workflow.lua @@ -8,10 +8,11 @@ local utils = require 'utils' * isEnabled() * setEnabled(enable) - * listConstraints([job]) -> {...} + * listConstraints([job[,with_history]]) -> {{...},...} * findConstraint(token) -> {...} or nil * setConstraint(token[, by_count, goal, gap]) -> {...} * deleteConstraint(token) -> true/false + * getCountHistory(token) -> {{...},...} or nil --]] diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 05fdca55b..12174af5c 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -291,6 +291,15 @@ int ProtectedJob::cur_tick_idx = 0; typedef std::map, bool> TMaterialCache; +static const size_t MAX_HISTORY_SIZE = 28; + +enum HistoryItem { + HIST_COUNT = 0, + HIST_AMOUNT, + HIST_INUSE_COUNT, + HIST_INUSE_AMOUNT +}; + struct ItemConstraint { PersistentDataItem config; PersistentDataItem history; @@ -360,36 +369,29 @@ public: size_t history_size() { return history.data_size() / hist_entry_size; } - size_t history_base(int idx) { + int history_value(int idx, HistoryItem item) { size_t hsize = history_size(); - return ((history.ival(0)+hsize-idx) % hsize) * hist_entry_size; - } - int history_count(int idx) { - return history.get_int28(history_base(idx) + 0*int28_size); - } - int history_amount(int idx) { - return history.get_int28(history_base(idx) + 1*int28_size); - } - int history_inuse_count(int idx) { - return history.get_int28(history_base(idx) + 2*int28_size); - } - int history_inuse_amount(int idx) { - return history.get_int28(history_base(idx) + 3*int28_size); + size_t base = ((history.ival(0)+1+idx) % hsize) * hist_entry_size; + return history.get_int28(base + item*int28_size); } + int history_count(int idx) { return history_value(idx, HIST_COUNT); } + int history_amount(int idx) { return history_value(idx, HIST_AMOUNT); } + int history_inuse_count(int idx) { return history_value(idx, HIST_INUSE_COUNT); } + int history_inuse_amount(int idx) { return history_value(idx, HIST_INUSE_AMOUNT); } void updateHistory() { size_t buffer_size = history_size(); - if (buffer_size < 28) - history.ensure_data(hist_entry_size*buffer_size++, hist_entry_size); + if (buffer_size < MAX_HISTORY_SIZE && size_t(history.ival(0)+1) == buffer_size) + history.ensure_data(hist_entry_size*++buffer_size); history.ival(0) = (history.ival(0)+1) % buffer_size; size_t base = history.ival(0) * hist_entry_size; - history.set_int28(base + 0*int28_size, item_count); - history.set_int28(base + 1*int28_size, item_amount); - history.set_int28(base + 2*int28_size, item_inuse_count); - history.set_int28(base + 3*int28_size, item_inuse_amount); + history.set_int28(base + HIST_COUNT*int28_size, item_count); + history.set_int28(base + HIST_AMOUNT*int28_size, item_amount); + history.set_int28(base + HIST_INUSE_COUNT*int28_size, item_inuse_count); + history.set_int28(base + HIST_INUSE_AMOUNT*int28_size, item_inuse_amount); } }; @@ -1384,6 +1386,25 @@ static void setEnabled(color_ostream &out, bool enable) } } +static void push_count_history(lua_State *L, ItemConstraint *icv) +{ + size_t hsize = icv->history_size(); + + lua_createtable(L, hsize, 0); + + for (size_t i = 0; i < hsize; i++) + { + lua_createtable(L, 0, 4); + + Lua::SetField(L, icv->history_amount(i), -1, "cur_amount"); + Lua::SetField(L, icv->history_count(i), -1, "cur_count"); + Lua::SetField(L, icv->history_inuse_amount(i), -1, "cur_in_use_amount"); + Lua::SetField(L, icv->history_inuse_count(i), -1, "cur_in_use_count"); + + lua_rawseti(L, -2, i+1); + } +} + static void push_constraint(lua_State *L, ItemConstraint *cv) { lua_newtable(L); @@ -1430,19 +1451,31 @@ static void push_constraint(lua_State *L, ItemConstraint *cv) lua_newtable(L); + bool resumed = false, want_resumed = false; + for (size_t i = 0, j = 0; i < cv->jobs.size(); i++) { if (!cv->jobs[i]->isLive()) continue; Lua::PushDFObject(L, cv->jobs[i]->actual_job); lua_rawseti(L, -2, ++j); + + if (cv->jobs[i]->want_resumed) { + want_resumed = true; + resumed = resumed || cv->jobs[i]->isActuallyResumed(); + } } lua_setfield(L, ctable, "jobs"); + + if (want_resumed && !resumed) + Lua::SetField(L, true, ctable, "is_delayed"); } static int listConstraints(lua_State *L) { + lua_settop(L, 2); auto job = Lua::CheckDFObject(L, 1); + bool with_history = lua_toboolean(L, 2); lua_pushnil(L); @@ -1467,6 +1500,13 @@ static int listConstraints(lua_State *L) for (size_t i = 0; i < vec.size(); i++) { push_constraint(L, vec[i]); + + if (with_history) + { + push_count_history(L, vec[i]); + lua_setfield(L, -2, "history"); + } + lua_rawseti(L, -2, i+1); } @@ -1525,23 +1565,7 @@ static int getCountHistory(lua_State *L) ItemConstraint *icv = get_constraint(out, token, NULL, false); if (icv) - { - size_t hsize = icv->history_size(); - - lua_createtable(L, hsize, 0); - - for (int i = hsize-1; i >= 0; i--) - { - lua_createtable(L, 0, 4); - - Lua::SetField(L, icv->history_amount(i), -1, "cur_amount"); - Lua::SetField(L, icv->history_count(i), -1, "cur_count"); - Lua::SetField(L, icv->history_inuse_amount(i), -1, "cur_in_use_amount"); - Lua::SetField(L, icv->history_inuse_count(i), -1, "cur_in_use_count"); - - lua_rawseti(L, -2, hsize-i); // reverse order - } - } + push_count_history(L, icv); else lua_pushnil(L);