Allow plugins to define subclasses of dfhack_viewscreen that have their own virtual_identity.

develop
Ben Lubar 2020-02-07 16:00:14 -06:00
parent 359cc2275a
commit 0243e422e5
No known key found for this signature in database
GPG Key ID: 92939677AB59EDA4
3 changed files with 32 additions and 14 deletions

@ -226,12 +226,24 @@ std::string df::buffer_container_identity::getFullName(type_identity *item)
virtual_identity::virtual_identity(size_t size, TAllocateFn alloc, virtual_identity::virtual_identity(size_t size, TAllocateFn alloc,
const char *dfhack_name, const char *original_name, const char *dfhack_name, const char *original_name,
virtual_identity *parent, const struct_field_info *fields) virtual_identity *parent, const struct_field_info *fields,
bool is_plugin)
: struct_identity(size, alloc, NULL, dfhack_name, parent, fields), original_name(original_name), : struct_identity(size, alloc, NULL, dfhack_name, parent, fields), original_name(original_name),
vtable_ptr(NULL) vtable_ptr(NULL), is_plugin(is_plugin)
{ {
// Plugins are initialized after Init was called, so they need to be added to the name table here
if (is_plugin)
{
doInit(&Core::getInstance());
}
} }
/* Vtable name to identity lookup. */
static std::map<std::string, virtual_identity*> name_lookup;
/* Vtable pointer to identity lookup. */
std::map<void*, virtual_identity*> virtual_identity::known;
virtual_identity::~virtual_identity() virtual_identity::~virtual_identity()
{ {
// Remove interpose entries, so that they don't try accessing this object later // Remove interpose entries, so that they don't try accessing this object later
@ -239,13 +251,16 @@ virtual_identity::~virtual_identity()
if (it->second) if (it->second)
it->second->on_host_delete(this); it->second->on_host_delete(this);
interpose_list.clear(); interpose_list.clear();
}
/* Vtable name to identity lookup. */ // Remove global lookup table entries if we're from a plugin
static std::map<std::string, virtual_identity*> name_lookup; if (is_plugin)
{
name_lookup.erase(getOriginalName());
/* Vtable pointer to identity lookup. */ if (vtable_ptr)
std::map<void*, virtual_identity*> virtual_identity::known; known.erase(vtable_ptr);
}
}
void virtual_identity::doInit(Core *core) void virtual_identity::doInit(Core *core)
{ {

@ -321,6 +321,8 @@ namespace DFHack
void *vtable_ptr; void *vtable_ptr;
bool is_plugin;
friend class VMethodInterposeLinkBase; friend class VMethodInterposeLinkBase;
std::map<int,VMethodInterposeLinkBase*> interpose_list; std::map<int,VMethodInterposeLinkBase*> interpose_list;
@ -337,7 +339,8 @@ namespace DFHack
public: public:
virtual_identity(size_t size, TAllocateFn alloc, virtual_identity(size_t size, TAllocateFn alloc,
const char *dfhack_name, const char *original_name, const char *dfhack_name, const char *original_name,
virtual_identity *parent, const struct_field_info *fields); virtual_identity *parent, const struct_field_info *fields,
bool is_plugin = false);
~virtual_identity(); ~virtual_identity();
virtual identity_type type() { return IDTYPE_CLASS; } virtual identity_type type() { return IDTYPE_CLASS; }

@ -591,7 +591,12 @@ std::string Gui::getFocusString(df::viewscreen *top)
if (!top) if (!top)
return ""; return "";
if (virtual_identity *id = virtual_identity::get(top)) if (dfhack_viewscreen::is_instance(top))
{
auto name = static_cast<dfhack_viewscreen*>(top)->getFocusString();
return name.empty() ? "dfhack" : "dfhack/"+name;
}
else if (virtual_identity *id = virtual_identity::get(top))
{ {
std::string name = getNameChunk(id, 11, 2); std::string name = getNameChunk(id, 11, 2);
@ -601,11 +606,6 @@ std::string Gui::getFocusString(df::viewscreen *top)
return name; return name;
} }
else if (dfhack_viewscreen::is_instance(top))
{
auto name = static_cast<dfhack_viewscreen*>(top)->getFocusString();
return name.empty() ? "dfhack" : "dfhack/"+name;
}
else else
{ {
Core &core = Core::getInstance(); Core &core = Core::getInstance();