Update dfhack for specific_ref.

develop
Alexander Gavrilov 2012-05-03 11:47:04 +04:00
parent 28b5068382
commit 5afe2ca002
13 changed files with 138 additions and 50 deletions

@ -738,6 +738,14 @@ Items module
Returns true *x,y,z* of the item; may be not equal to item.pos if in inventory. Returns true *x,y,z* of the item; may be not equal to item.pos if in inventory.
* ``dfhack.items.getGeneralRef(item, type)``
Searches for a general_ref with the given type.
* ``dfhack.items.getSpecificRef(item, type)``
Searches for a specific_ref with the given type.
* ``dfhack.items.getOwner(item)`` * ``dfhack.items.getOwner(item)``
Returns the owner unit or *nil*. Returns the owner unit or *nil*.

@ -972,6 +972,12 @@ or raws. The <tt class="docutils literal">ignore_noble</tt> boolean disables the
<li><p class="first"><tt class="docutils literal">dfhack.items.getPosition(item)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.items.getPosition(item)</tt></p>
<p>Returns true <em>x,y,z</em> of the item; may be not equal to item.pos if in inventory.</p> <p>Returns true <em>x,y,z</em> of the item; may be not equal to item.pos if in inventory.</p>
</li> </li>
<li><p class="first"><tt class="docutils literal">dfhack.items.getGeneralRef(item, type)</tt></p>
<p>Searches for a general_ref with the given type.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.items.getSpecificRef(item, type)</tt></p>
<p>Searches for a specific_ref with the given type.</p>
</li>
<li><p class="first"><tt class="docutils literal">dfhack.items.getOwner(item)</tt></p> <li><p class="first"><tt class="docutils literal">dfhack.items.getOwner(item)</tt></p>
<p>Returns the owner unit or <em>nil</em>.</p> <p>Returns the owner unit or <em>nil</em>.</p>
</li> </li>

@ -682,6 +682,8 @@ static bool items_moveToContainer(df::item *item, df::item *container)
} }
static const LuaWrapper::FunctionReg dfhack_items_module[] = { static const LuaWrapper::FunctionReg dfhack_items_module[] = {
WRAPM(Items, getGeneralRef),
WRAPM(Items, getSpecificRef),
WRAPM(Items, getOwner), WRAPM(Items, getOwner),
WRAPM(Items, setOwner), WRAPM(Items, setOwner),
WRAPM(Items, getContainer), WRAPM(Items, getContainer),

@ -1103,26 +1103,39 @@ static void IndexFields(lua_State *state, int base, struct_identity *pstruct, bo
name = pstruct->getName() + ("." + name); name = pstruct->getName() + ("." + name);
lua_pop(state, 1); lua_pop(state, 1);
bool add_to_enum = true;
// Handle the field // Handle the field
switch (fields[i].mode) switch (fields[i].mode)
{ {
case struct_field_info::OBJ_METHOD: case struct_field_info::OBJ_METHOD:
AddMethodWrapper(state, base+1, base+2, name.c_str(), AddMethodWrapper(state, base+1, base+2, name.c_str(),
(function_identity_base*)fields[i].type); (function_identity_base*)fields[i].type);
break; continue;
case struct_field_info::CLASS_METHOD: case struct_field_info::CLASS_METHOD:
continue;
case struct_field_info::POINTER:
// Skip class-typed pointers within unions
if ((fields[i].count & 2) != 0 && fields[i].type &&
fields[i].type->type() == IDTYPE_CLASS)
add_to_enum = false;
break; break;
default: default:
break;
}
// Do not add invalid globals to the enumeration order // Do not add invalid globals to the enumeration order
if (!globals || *(void**)fields[i].offset) if (globals && !*(void**)fields[i].offset)
add_to_enum = false;
if (add_to_enum)
AssociateId(state, base+3, ++cnt, name.c_str()); AssociateId(state, base+3, ++cnt, name.c_str());
lua_pushlightuserdata(state, (void*)&fields[i]); lua_pushlightuserdata(state, (void*)&fields[i]);
lua_setfield(state, base+2, name.c_str()); lua_setfield(state, base+2, name.c_str());
break;
}
} }
} }

@ -26,6 +26,7 @@ distribution.
#include "Export.h" #include "Export.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include "Error.h" #include "Error.h"
#include "Types.h"
#ifndef LINUX_BUILD #ifndef LINUX_BUILD
#include <Windows.h> #include <Windows.h>
@ -124,6 +125,62 @@ std::string toLower(const std::string &str)
return rv; return rv;
} }
df::general_ref *DFHack::findRef(std::vector<df::general_ref*> &vec, df::general_ref_type type)
{
for (int i = vec.size()-1; i >= 0; i--)
{
df::general_ref *ref = vec[i];
if (ref->getType() == type)
return ref;
}
return NULL;
}
bool DFHack::removeRef(std::vector<df::general_ref*> &vec, df::general_ref_type type, int id)
{
for (int i = vec.size()-1; i >= 0; i--)
{
df::general_ref *ref = vec[i];
if (ref->getType() != type || ref->getID() != id)
continue;
vector_erase_at(vec, i);
delete ref;
return true;
}
return false;
}
df::specific_ref *DFHack::findRef(std::vector<df::specific_ref*> &vec, df::specific_ref_type type)
{
for (int i = vec.size()-1; i >= 0; i--)
{
df::specific_ref *ref = vec[i];
if (ref->type == type)
return ref;
}
return NULL;
}
bool DFHack::removeRef(std::vector<df::specific_ref*> &vec, df::specific_ref_type type, void *ptr)
{
for (int i = vec.size()-1; i >= 0; i--)
{
df::specific_ref *ref = vec[i];
if (ref->type != type || ref->object != ptr)
continue;
vector_erase_at(vec, i);
delete ref;
return true;
}
return false;
}
#ifdef LINUX_BUILD // Linux #ifdef LINUX_BUILD // Linux
uint64_t GetTimeMs64() uint64_t GetTimeMs64()
{ {

@ -28,6 +28,10 @@ distribution.
#include "Pragma.h" #include "Pragma.h"
#include "Export.h" #include "Export.h"
#include "DataDefs.h"
#include "df/general_ref.h"
#include "df/specific_ref.h"
namespace DFHack namespace DFHack
{ {
struct t_matglossPair struct t_matglossPair
@ -69,4 +73,10 @@ namespace DFHack
std::string name; std::string name;
uint32_t xpNxtLvl; uint32_t xpNxtLvl;
}; };
DFHACK_EXPORT df::general_ref *findRef(std::vector<df::general_ref*> &vec, df::general_ref_type type);
DFHACK_EXPORT bool removeRef(std::vector<df::general_ref*> &vec, df::general_ref_type type, int id);
DFHACK_EXPORT df::specific_ref *findRef(std::vector<df::specific_ref*> &vec, df::specific_ref_type type);
DFHACK_EXPORT bool removeRef(std::vector<df::specific_ref*> &vec, df::specific_ref_type type, void *ptr);
}// namespace DFHack }// namespace DFHack

@ -36,6 +36,7 @@ distribution.
#include "df/item.h" #include "df/item.h"
#include "df/item_type.h" #include "df/item_type.h"
#include "df/general_ref.h" #include "df/general_ref.h"
#include "df/specific_ref.h"
namespace df namespace df
{ {
@ -126,6 +127,10 @@ DFHACK_EXPORT bool copyItem(df::item * source, dfh_item & target);
/// write copied item back to its origin /// write copied item back to its origin
DFHACK_EXPORT bool writeItem(const dfh_item & item); DFHACK_EXPORT bool writeItem(const dfh_item & item);
/// Retrieve refs
DFHACK_EXPORT df::general_ref *getGeneralRef(df::item *item, df::general_ref_type type);
DFHACK_EXPORT df::specific_ref *getSpecificRef(df::item *item, df::specific_ref_type type);
/// Retrieve the owner of the item. /// Retrieve the owner of the item.
DFHACK_EXPORT df::unit *getOwner(df::item *item); DFHACK_EXPORT df::unit *getOwner(df::item *item);
/// Set the owner of the item. Pass NULL as unit to remove the owner. /// Set the owner of the item. Pass NULL as unit to remove the owner.

@ -421,18 +421,25 @@ bool Items::copyItem(df::item * itembase, DFHack::dfh_item &item)
return true; return true;
} }
df::unit *Items::getOwner(df::item * item) df::general_ref *Items::getGeneralRef(df::item *item, df::general_ref_type type)
{ {
CHECK_NULL_POINTER(item); CHECK_NULL_POINTER(item);
for (size_t i = 0; i < item->itemrefs.size(); i++) return findRef(item->itemrefs, type);
}
df::specific_ref *Items::getSpecificRef(df::item *item, df::specific_ref_type type)
{ {
df::general_ref *ref = item->itemrefs[i]; CHECK_NULL_POINTER(item);
if (strict_virtual_cast<df::general_ref_unit_itemownerst>(ref))
return ref->getUnit(); return findRef(item->specific_refs, type);
} }
return NULL; df::unit *Items::getOwner(df::item * item)
{
auto ref = getGeneralRef(item, general_ref_type::UNIT_ITEMOWNER);
return ref ? ref->getUnit() : NULL;
} }
bool Items::setOwner(df::item *item, df::unit *unit) bool Items::setOwner(df::item *item, df::unit *unit)
@ -478,16 +485,9 @@ bool Items::setOwner(df::item *item, df::unit *unit)
df::item *Items::getContainer(df::item * item) df::item *Items::getContainer(df::item * item)
{ {
CHECK_NULL_POINTER(item); auto ref = getGeneralRef(item, general_ref_type::CONTAINED_IN_ITEM);
for (size_t i = 0; i < item->itemrefs.size(); i++)
{
df::general_ref *ref = item->itemrefs[i];
if (ref->getType() == general_ref_type::CONTAINED_IN_ITEM)
return ref->getItem();
}
return NULL; return ref ? ref->getItem() : NULL;
} }
void Items::getContainedItems(df::item *item, std::vector<df::item*> *items) void Items::getContainedItems(df::item *item, std::vector<df::item*> *items)
@ -546,19 +546,6 @@ df::coord Items::getPosition(df::item *item)
return item->pos; return item->pos;
} }
static void removeRef(std::vector<df::general_ref*> &vec, df::general_ref_type type, int id)
{
for (int i = vec.size()-1; i >= 0; i--)
{
df::general_ref *ref = vec[i];
if (ref->getType() != type || ref->getID() != id)
continue;
vector_erase_at(vec, i);
delete ref;
}
}
static bool detachItem(MapExtras::MapCache &mc, df::item *item) static bool detachItem(MapExtras::MapCache &mc, df::item *item)
{ {
if (item->flags.bits.on_ground) if (item->flags.bits.on_ground)

@ -46,6 +46,7 @@ using namespace std;
#include "df/job.h" #include "df/job.h"
#include "df/job_item.h" #include "df/job_item.h"
#include "df/job_list_link.h" #include "df/job_list_link.h"
#include "df/specific_ref.h"
#include "df/general_ref.h" #include "df/general_ref.h"
#include "df/general_ref_unit_workerst.h" #include "df/general_ref_unit_workerst.h"
#include "df/general_ref_building_holderst.h" #include "df/general_ref_building_holderst.h"
@ -67,7 +68,7 @@ df::job *DFHack::Job::cloneJobStruct(df::job *job)
pnew->list_link = NULL; pnew->list_link = NULL;
pnew->completion_timer = -1; pnew->completion_timer = -1;
pnew->items.clear(); pnew->items.clear();
pnew->misc_links.clear(); pnew->specific_refs.clear();
// Clone refs // Clone refs
for (int i = pnew->references.size()-1; i >= 0; i--) for (int i = pnew->references.size()-1; i >= 0; i--)
@ -93,7 +94,7 @@ void DFHack::Job::deleteJobStruct(df::job *job)
return; return;
// Only allow free-floating job structs // Only allow free-floating job structs
assert(!job->list_link && job->items.empty() && job->misc_links.empty()); assert(!job->list_link && job->items.empty() && job->specific_refs.empty());
for (int i = job->references.size()-1; i >= 0; i--) for (int i = job->references.size()-1; i >= 0; i--)
delete job->references[i]; delete job->references[i];
@ -331,10 +332,10 @@ bool DFHack::Job::attachJobItem(df::job *job, df::item *item,
item->flags.bits.in_job = true; item->flags.bits.in_job = true;
} }
auto item_link = new df::item::T_jobs(); auto item_link = new df::specific_ref();
item_link->type = 2; item_link->type = specific_ref_type::JOB;
item_link->job = job; item_link->job = job;
item->jobs.push_back(item_link); item->specific_refs.push_back(item_link);
auto job_link = new df::job_item_ref(); auto job_link = new df::job_item_ref();
job_link->item = item; job_link->item = item;

@ -1 +1 @@
Subproject commit 6ce2b7120e5a246093116b48cb2ac64c35a8270d Subproject commit 5707a6aa0c035348c8769058ed77b320f9b1436c

@ -832,7 +832,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
{ {
if (is_on_break) if (is_on_break)
dwarf_info[dwarf].state = OTHER; dwarf_info[dwarf].state = OTHER;
else if (dwarfs[dwarf]->meetings.size() > 0) else if (dwarfs[dwarf]->specific_refs.size() > 0)
dwarf_info[dwarf].state = OTHER; dwarf_info[dwarf].state = OTHER;
else else
dwarf_info[dwarf].state = IDLE; dwarf_info[dwarf].state = IDLE;

@ -272,7 +272,7 @@ static command_result job_duplicate(color_ostream &out, vector <string> & parame
if (!job) if (!job)
return CR_FAILURE; return CR_FAILURE;
if (!job->misc_links.empty() || if (!job->specific_refs.empty() ||
(job->job_items.empty() && (job->job_items.empty() &&
job->job_type != job_type::CollectSand && job->job_type != job_type::CollectSand &&
job->job_type != job_type::CollectClay)) job->job_type != job_type::CollectClay))

@ -364,7 +364,7 @@ static ProtectedJob *get_known(int id)
static bool isSupportedJob(df::job *job) static bool isSupportedJob(df::job *job)
{ {
return job->misc_links.empty() && return job->specific_refs.empty() &&
Job::getHolder(job) && Job::getHolder(job) &&
(!job->job_items.empty() || (!job->job_items.empty() ||
job->job_type == job_type::CollectClay || job->job_type == job_type::CollectClay ||
@ -1083,12 +1083,11 @@ static bool itemInRealJob(df::item *item)
if (!item->flags.bits.in_job) if (!item->flags.bits.in_job)
return false; return false;
if (item->jobs.size() != 1 || auto ref = Items::getSpecificRef(item, specific_ref_type::JOB);
item->jobs[0]->type != 2 || if (!ref || !ref->job)
item->jobs[0]->job == NULL)
return true; return true;
return ENUM_ATTR(job_type, type, item->jobs[0]->job->job_type) return ENUM_ATTR(job_type, type, ref->job->job_type)
!= job_type_class::Hauling; != job_type_class::Hauling;
} }