SYNOPSIS
int shadow(object ob)
DESCRIPTION
The current object will become a shadow of ob. This efun
returns 1 on success, 0 otherwise.
The calling object must be permitted by the master object to
do the shadowing. In most installations, an object that
defines the function query_prevent_shadow() to return 1
can't be shadowed, and the shadow() function will return 0
instead of ob.
shadow() also fails if the calling object tries to shadow
a function that was defined as ``nomask'', if the program was
compiled with the #pragma no_shadow, or if the calling
object is already shadowing, is being shadowed, or has an
environment. Also the target ob must not be shadowing
something else.
If an object A shadows an object B then all call_other() to B
will be redirected to A. If object A has not defined the
function, then the call will be passed to B. There is only on
object that can call functions in B with call_other(), and
that is A. Not even object B can call_other() itself. All
normal (internal) function calls inside B will however remain
internal to B.
EXAMPLES
With the three objects a.c, b.c and c.c
--- a.c ---
int fun() {
debug_message(sprintf("%O [a] fun()\n", this_object()));
}
void fun3() {
debug_message(sprintf("%O [a] fun3()\n", this_object()));
}
--- b.c ---
int fun() {
debug_message(sprintf("%O [b] fun()\n", this_object()));
find_object("a")->fun();
}
void fun2() {
debug_message(sprintf("%O [b] fun2()\n", this_object()));
find_object("a")->fun3();
this_object()->fun3();
}
void do_shadow(object target) { shadow(target, 1); }
--- c.c ---
int fun() {
debug_message(sprintf("%O [c] fun()\n", this_object()));
find_object("a")->fun();
}
void fun3() {
debug_message(sprintf("%O [c] fun3()\n", this_object()));
}
void do_shadow(object target) { shadow(target, 1); }
code like the following
object a, b, c;
a = load_object("a");
b = load_object("b");
c = load_object("c");
b->do_shadow(a);
c->do_shadow(a);
debug_message("--- a->fun() ---\n");
a->fun();
debug_message("--- b->fun() ---\n");
b->fun();
debug_message("--- c->fun() ---\n");
c->fun();
debug_message("--- b->fun2() ---\n");
b->fun2();
produces this output:
--- a->fun() ---
/c [c] fun()
/b [b] fun()
/a [a] fun()
--- b->fun() ---
/c [c] fun()
/b [b] fun()
/a [a] fun()
--- c->fun() ---
/c [c] fun()
/b [b] fun()
/a [a] fun()
--- b->fun2() ---
/b [b] fun2()
/a [a] fun3()
/c [c] fun3()
Note that the first call in b::fun2() find c::fun3()! Reason is that
for calls originating from b to a the driver assumes that all
shadows beyond c already had their chance. The second call however
was to b itself, which the gamedriver recognized as being shadowed
by c.
HISTORY
Up to 3.2.1@46, destructing a shadowed object also destructs
all shadows. Since 3.2.1@47, shadows may survive the
destruction of the shadowee (unless the prepare_destruct() in
the master object destructs them manually).
Since LDMud 3.2.8, programs may protect themselves from being
shadowed with the #pragma no_shadow.
SEE ALSO
query_shadowing(E), unshadow(E), query_allow_shadow(M)
|