summaryrefslogtreecommitdiff
path: root/library/include
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-09-22 13:14:06 +0400
committerAlexander Gavrilov2012-09-22 13:14:06 +0400
commit038d62367eea44ba625989b8cd4c1380ba544607 (patch)
treef37b265b9b881296ddf1a8b9ef532c5a65ba465b /library/include
parentf7e414e397e2f3ee70805a6bbe68a40551e05f2a (diff)
downloaddfhack-038d62367eea44ba625989b8cd4c1380ba544607.tar.gz
dfhack-038d62367eea44ba625989b8cd4c1380ba544607.tar.bz2
dfhack-038d62367eea44ba625989b8cd4c1380ba544607.tar.xz
Implement explicit hook priority in vmethod interpose.
This resolves a getName order conflict between power-meter and rename.
Diffstat (limited to 'library/include')
-rw-r--r--library/include/VTableInterpose.h19
1 files changed, 13 insertions, 6 deletions
diff --git a/library/include/VTableInterpose.h b/library/include/VTableInterpose.h
index 7ba6b67a..aeb407a8 100644
--- a/library/include/VTableInterpose.h
+++ b/library/include/VTableInterpose.h
@@ -87,7 +87,8 @@ namespace DFHack
with code defined by DFHack, while retaining ability to
call the original code. The API can be safely used from
plugins, and multiple hooks for the same vmethod are
- automatically chained in undefined order.
+ automatically chained (subclass before superclass; at same
+ level highest priority called first; undefined order otherwise).
Usage:
@@ -105,6 +106,8 @@ namespace DFHack
};
IMPLEMENT_VMETHOD_INTERPOSE(my_hack, foo);
+ or
+ IMPLEMENT_VMETHOD_INTERPOSE_PRIO(my_hack, foo, priority);
void init() {
if (!INTERPOSE_HOOK(my_hack, foo).apply())
@@ -121,9 +124,11 @@ namespace DFHack
static DFHack::VMethodInterposeLink<interpose_base,interpose_ptr_##name> interpose_##name; \
rtype interpose_fn_##name args
-#define IMPLEMENT_VMETHOD_INTERPOSE(class,name) \
+#define IMPLEMENT_VMETHOD_INTERPOSE_PRIO(class,name,priority) \
DFHack::VMethodInterposeLink<class::interpose_base,class::interpose_ptr_##name> \
- class::interpose_##name(&class::interpose_base::name, &class::interpose_fn_##name);
+ class::interpose_##name(&class::interpose_base::name, &class::interpose_fn_##name, priority);
+
+#define IMPLEMENT_VMETHOD_INTERPOSE(class,name) IMPLEMENT_VMETHOD_INTERPOSE_PRIO(class,name,0)
#define INTERPOSE_NEXT(name) (this->*interpose_##name.chain)
#define INTERPOSE_HOOK(class, name) (class::interpose_##name)
@@ -140,6 +145,7 @@ namespace DFHack
int vmethod_idx;
void *interpose_method; // Pointer to the code of the interposing method
void *chain_mptr; // Pointer to the chain field below
+ int priority;
bool applied;
void *saved_chain; // Previous pointer to the code
@@ -155,7 +161,7 @@ namespace DFHack
VMethodInterposeLinkBase *get_first_interpose(virtual_identity *id);
void find_child_hosts(virtual_identity *cur, void *vmptr);
public:
- VMethodInterposeLinkBase(virtual_identity *host, int vmethod_idx, void *interpose_method, void *chain_mptr);
+ VMethodInterposeLinkBase(virtual_identity *host, int vmethod_idx, void *interpose_method, void *chain_mptr, int priority);
~VMethodInterposeLinkBase();
bool is_applied() { return applied; }
@@ -171,12 +177,13 @@ namespace DFHack
operator Ptr () { return chain; }
template<class Ptr2>
- VMethodInterposeLink(Ptr target, Ptr2 src)
+ VMethodInterposeLink(Ptr target, Ptr2 src, int priority)
: VMethodInterposeLinkBase(
&Base::_identity,
vmethod_pointer_to_idx(target),
method_pointer_to_addr(src),
- &chain
+ &chain,
+ priority
)
{ src = target; /* check compatibility */ }
};