| 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) |