From 0243e422e53823f9149ffa6a851113e2917c8ffe Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 7 Feb 2020 16:00:14 -0600 Subject: [PATCH] Allow plugins to define subclasses of dfhack_viewscreen that have their own virtual_identity. --- library/DataDefs.cpp | 29 ++++++++++++++++++++++------- library/include/DataDefs.h | 5 ++++- library/modules/Gui.cpp | 12 ++++++------ 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp index 3d802638f..5952e3da1 100644 --- a/library/DataDefs.cpp +++ b/library/DataDefs.cpp @@ -226,12 +226,24 @@ std::string df::buffer_container_identity::getFullName(type_identity *item) virtual_identity::virtual_identity(size_t size, TAllocateFn alloc, 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), - 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 name_lookup; + +/* Vtable pointer to identity lookup. */ +std::map virtual_identity::known; + virtual_identity::~virtual_identity() { // Remove interpose entries, so that they don't try accessing this object later @@ -239,13 +251,16 @@ virtual_identity::~virtual_identity() if (it->second) it->second->on_host_delete(this); interpose_list.clear(); -} -/* Vtable name to identity lookup. */ -static std::map name_lookup; + // Remove global lookup table entries if we're from a plugin + if (is_plugin) + { + name_lookup.erase(getOriginalName()); -/* Vtable pointer to identity lookup. */ -std::map virtual_identity::known; + if (vtable_ptr) + known.erase(vtable_ptr); + } +} void virtual_identity::doInit(Core *core) { diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 7c3b534b6..750c4d70a 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -321,6 +321,8 @@ namespace DFHack void *vtable_ptr; + bool is_plugin; + friend class VMethodInterposeLinkBase; std::map interpose_list; @@ -337,7 +339,8 @@ namespace DFHack public: virtual_identity(size_t size, TAllocateFn alloc, 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_type type() { return IDTYPE_CLASS; } diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index 758395f40..b4c4a7693 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -591,7 +591,12 @@ std::string Gui::getFocusString(df::viewscreen *top) if (!top) return ""; - if (virtual_identity *id = virtual_identity::get(top)) + if (dfhack_viewscreen::is_instance(top)) + { + auto name = static_cast(top)->getFocusString(); + return name.empty() ? "dfhack" : "dfhack/"+name; + } + else if (virtual_identity *id = virtual_identity::get(top)) { std::string name = getNameChunk(id, 11, 2); @@ -601,11 +606,6 @@ std::string Gui::getFocusString(df::viewscreen *top) return name; } - else if (dfhack_viewscreen::is_instance(top)) - { - auto name = static_cast(top)->getFocusString(); - return name.empty() ? "dfhack" : "dfhack/"+name; - } else { Core &core = Core::getInstance();