Lpc Manpages

SYNOPSIS
        object shadow(object obj, int flag)

BESCHREIBUNG
        Wenn <flag> nicht 0 ist, wird das aktuelle Objekt dem Objekt obj
        als Shadow uebergeworfen. Wenn <flag> 0 ist, wird entweder 0 oder
        das geshadowte Objekt zurueck gegeben.

        Das aufrufende Objekt muss vom Master-Objekt die Erlaubnis haben,
        als Shadow zu wirken. Normalerweise kann einem Objekt, das
        query_prevent_shadow() == 1 zurueck liefert, kein Shadow
        uebergeworfen werden. In diesem Fall liefert shadow() 0 zurueck,
        sonst das Objekt, dem der Shadow uebergeworfen wurde.

        shadow() schlaeft fehl, wenn:
          - der Shadow vesucht, eine "nomask" definierte Funktion zu
            ueberlagern,
          - wenn im Praeprozessor #pragma no_shadow gesetzt ist,
          - wenn das aufrufende Objekt bereits ein Shadow ist,
          - wenn das aufrufende Objekt selbst einen Shadow uebergeworfen hat,
          - wenn das aufrufende Objekt ueber ein Environment verfuegt,
          - wenn das Zielobjekt <obj> selbst ein Shadow ist.

        Wenn ein Objekt A einem Objekt B als Shadow uebergeworfen wird,
        werden alle call_other() Aufrufe fuer B an A umgeleitet. Wenn A die
        Funktion, die von call_other() aufgerufen wird, nicht definiert hat,
        wird der Aufruf an B weitergeleitet. Es gibt also nur ein Objekt,
        welches call_other() Aufrufe fuer B machen kann: das Objekt A. Nicht
        einmal das Objekt B kann einen call_other() auf sich selbst machen.
        Hingegen werden alle normalen (internen) Funktionsaufrufe innerhalb
        von B werden wie gewohnt innerhalb von B bearbeitet.

BEISPIELE
        Mit drei Objekten a.c, b.c und c.c:

        --- a.c ---
            void 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); }

        Es wird nun folgender Code aufgerufen:

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

        Das ergibt diesen 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()

            Merke: der erste Aufruf in b::fun2() findet zuerst c::fun3()!
            Der Grund ist, dass fuer Aufrufe aus b fuer a der Treiber
            annimmt, dass alle Shadows vor c schon ihre Chance hatten. Der
            zweite Aufruf hingegen ergeht an b selbst, das der Treiber als
            vom Shadow c ueberlagert erkennt.

GESCHICHTE
        Bis 3.2.1@46 fuehrte die Zerstoerung eines Objekts, dem ein Shadow
            uebergeworfen war, auch zur Zerstoerung aller seiner Shadows.
        Seit 3.2.1@47 ueberleben Shadows die Zerstoerung des Objektes, dem
            sie uebergeworfen sind (ausser, die wird von prepare_destruct()
            manuell erledigt).
        Seit LDMud 3.2.8 koenne sich Objekte dank #pragma no_shadow gezielt
            davor schuetzen, einen Shadow uebergeworfen zu bekommen.

SIEHE AUCH
        query_shadowing(E), unshadow(E), query_allow_shadow(M)