@ -293,6 +293,7 @@ typedef std::map<std::pair<int,int>, bool> TMaterialCache;
struct ItemConstraint {
PersistentDataItem config ;
PersistentDataItem history ;
// Fixed key parsed into fields
bool is_craft ;
@ -308,7 +309,7 @@ struct ItemConstraint {
int weight ;
std : : vector < ProtectedJob * > jobs ;
int item_amount , item_count , item_inuse ;
int item_amount , item_count , item_inuse _amount, item_inuse_count ;
bool request_suspend , request_resume ;
bool is_active , cant_resume_reported ;
@ -318,7 +319,7 @@ struct ItemConstraint {
public :
ItemConstraint ( )
: is_craft ( false ) , min_quality ( item_quality : : Ordinary ) , is_local ( false ) ,
weight ( 0 ) , item_amount ( 0 ) , item_count ( 0 ) , item_inuse ( 0 ) ,
weight ( 0 ) , item_amount ( 0 ) , item_count ( 0 ) , item_inuse _amount( 0 ) , item_inuse_count ( 0 ) ,
is_active ( false ) , cant_resume_reported ( false )
{ }
@ -352,6 +353,44 @@ public:
request_resume = ( size < = goalCount ( ) - goalGap ( ) ) ;
request_suspend = ( size > = goalCount ( ) ) ;
}
static const size_t int28_size = PersistentDataItem : : int28_size ;
static const size_t hist_entry_size = PersistentDataItem : : int28_size * 4 ;
size_t history_size ( ) {
return history . data_size ( ) / hist_entry_size ;
}
size_t history_base ( int idx ) {
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 ) ;
}
void updateHistory ( )
{
size_t buffer_size = history_size ( ) ;
if ( buffer_size < 28 )
history . ensure_data ( hist_entry_size * buffer_size + + , hist_entry_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 ) ;
}
} ;
/******************************
@ -649,6 +688,9 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out)
update_job_data ( out ) ;
process_constraints ( out ) ;
for ( size_t i = 0 ; i < constraints . size ( ) ; i + + )
constraints [ i ] - > updateHistory ( ) ;
}
}
@ -659,6 +701,10 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out)
* ITEM COUNT CONSTRAINT *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static std : : string history_key ( PersistentDataItem & config ) {
return stl_sprintf ( " workflow/history/%d " , config . entry_id ( ) ) ;
}
static ItemConstraint * get_constraint ( color_ostream & out , const std : : string & str , PersistentDataItem * cfg , bool create )
{
std : : vector < std : : string > tokens ;
@ -776,6 +822,8 @@ static ItemConstraint *get_constraint(color_ostream &out, const std::string &str
nct - > init ( str ) ;
}
nct - > history = World : : GetPersistentData ( history_key ( nct - > config ) , NULL ) ;
constraints . push_back ( nct ) ;
return nct ;
}
@ -787,6 +835,7 @@ static void delete_constraint(ItemConstraint *cv)
vector_erase_at ( constraints , idx ) ;
World : : DeletePersistentData ( cv - > config ) ;
World : : DeletePersistentData ( cv - > history ) ;
delete cv ;
}
@ -1064,7 +1113,8 @@ static void map_job_items(color_ostream &out)
{
constraints [ i ] - > item_amount = 0 ;
constraints [ i ] - > item_count = 0 ;
constraints [ i ] - > item_inuse = 0 ;
constraints [ i ] - > item_inuse_amount = 0 ;
constraints [ i ] - > item_inuse_count = 0 ;
}
meltable_count = 0 ;
@ -1177,7 +1227,8 @@ static void map_job_items(color_ostream &out)
isAssignedSquad ( item ) )
{
is_invalid = true ;
cv - > item_inuse + + ;
cv - > item_inuse_count + + ;
cv - > item_inuse_amount + = item - > getStackSize ( ) ;
}
else
{
@ -1367,7 +1418,8 @@ static void push_constraint(lua_State *L, ItemConstraint *cv)
Lua : : SetField ( L , cv - > item_amount , ctable , " cur_amount " ) ;
Lua : : SetField ( L , cv - > item_count , ctable , " cur_count " ) ;
Lua : : SetField ( L , cv - > item_inuse , ctable , " cur_in_use " ) ;
Lua : : SetField ( L , cv - > item_inuse_amount , ctable , " cur_in_use_amount " ) ;
Lua : : SetField ( L , cv - > item_inuse_count , ctable , " cur_in_use_count " ) ;
// Current state value
@ -1463,6 +1515,40 @@ static int setConstraint(lua_State *L)
return 1 ;
}
static int getCountHistory ( lua_State * L )
{
auto token = luaL_checkstring ( L , 1 ) ;
color_ostream & out = * Lua : : GetOutput ( L ) ;
update_data_structures ( out ) ;
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
}
}
else
lua_pushnil ( L ) ;
return 1 ;
}
DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION ( isEnabled ) ,
DFHACK_LUA_FUNCTION ( setEnabled ) ,
@ -1474,6 +1560,7 @@ DFHACK_PLUGIN_LUA_COMMANDS {
DFHACK_LUA_COMMAND ( listConstraints ) ,
DFHACK_LUA_COMMAND ( findConstraint ) ,
DFHACK_LUA_COMMAND ( setConstraint ) ,
DFHACK_LUA_COMMAND ( getCountHistory ) ,
DFHACK_LUA_END
} ;
@ -1521,10 +1608,10 @@ static void print_constraint(color_ostream &out, ItemConstraint *cv, bool no_job
< < cv - > goalCount ( ) < < " (gap " < < cv - > goalGap ( ) < < " ) " < < endl ;
out . reset_color ( ) ;
if ( cv - > item_count | | cv - > item_inuse )
if ( cv - > item_count | | cv - > item_inuse _count )
out < < prefix < < " items: amount " < < cv - > item_amount < < " ; "
< < cv - > item_count < < " stacks available, "
< < cv - > item_inuse < < " in use. " < < endl ;
< < cv - > item_inuse _count < < " in use. " < < endl ;
if ( no_job ) return ;