shadow()
========

FUNKTION
--------
::

     object shadow(object ob, int flag)

ARGUMENTE
---------
::

     object ob		- das vom shadow betroffene Objekt
     int flag		- 0 fuer eine Shadow-Existenzabfrage
                      1 fuer Shadow durch previous_object()

BESCHREIBUNG
------------
::

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

     Wenn ein Objekt A ein Objekt B beschattet, werden alle call_other() fuer
     B auf A umgeleitet. Wenn die an B gerufene Funktion in A existiert, so
     wird sie in A gerufen, bei Nichtexistenz in B.
     A ist das einzige Objekt, welche die beschatteten Funktionen mit 
     call_other() in B aufrufen kann, selbst B kann nicht per call_other() 
     diese Funktion rufen.
     Alle intern verwendeten Funktionen arbeiten jedoch weiterhin normal.

     Das aufrufende Objekt muss vom Master-Objekt die Erlaubnis haben,
     als Shadow zu wirken.

     Es gibt folgende Kriterien fuer eine erfolgreiche Beschattung:
     - das zu beschattende Objekt ob:
       - ist weder ein access_rights-Objekt noch ein ROOT-Objekt
       - gibt beim Aufruf von query_prevent_shadow(beschatter) eine 0
         zurueck
       - beschattet selbst niemanden
       - hat kein '#pragma no_shadow' gesetzt
     - der Beschatter:
       - wird nicht selbst (direkt) beschattet
       - beschattet noch niemanden (sonst folgt direkter Abbruch)
       - hat kein environment()
       - definiert/beschattet keine Methode, die im beschatteten Objekt ob 
         als nomask definiert ist

     Beschattet man ein Objekt A mit einem Objekt B und dann das Objekt A
     zusaetzlich mit einem Objekt C, so wird eine Beschattungshierarchie
     erstellt:

     B macht shadow(A, 1)
     B->A
     C macht shadow(A, 1)
     C->B->A

BEISPIELE
---------
::

     // wenn: B beschattet A, dann
     shadow(find_object(A), 0) == B


     // 3 Objekte beschatten in Hierarchie (liegt auch im Pfad)
     --- aa.c ---
     void fun() {
         printf("%O [a] fun()\n", this_object());
     }

     void fun3() {
         printf("%O [a] fun3()\n", this_object());
     }

     --- bb.c ---
     int fun() {
         printf("%O [b] fun()\n", this_object());
         find_object("/doc/beispiele/shadow/aa")->fun();
     }

     void fun2() {
         printf("%O [b] fun2()\n", this_object());
         find_object("/doc/beispiele/shadow/aa")->fun3();
         this_object()->fun3();
     }

     void do_shadow(object target) { shadow(target, 1); }

     --- cc.c ---
     int fun() {
         printf("%O [c] fun()\n", this_object());
         find_object("/doc/beispiele/shadow/aa")->fun();
     }

     void fun3() {
         printf("%O [c] fun3()\n", this_object());
     }

     void do_shadow(object target) { shadow(target, 1); }

     // darauf arbeitender Code

     object a, b, c;

     destruct("/doc/beispiele/shadow/aa");
     a = load_object("/doc/beispiele/shadow/aa");
     destruct("/doc/beispiele/shadow/bb");
     b = load_object("/doc/beispiele/shadow/bb");
     destruct("/doc/beispiele/shadow/cc");
     c = load_object("/doc/beispiele/shadow/cc");

     b->do_shadow(a);
     c->do_shadow(a);
     printf("--- a->fun() ---\n");
     a->fun();
     printf("--- b->fun() ---\n");
     b->fun();
     printf("--- c->fun() ---\n");
     c->fun();
     printf("--- b->fun2() ---\n");
     b->fun2();

     // ... und seine Ausgabe:

     --- a->fun() ---
     /doc/beispiele/shadow/cc [c] fun()
     /doc/beispiele/shadow/bb [b] fun()
     /doc/beispiele/shadow/aa [a] fun()
     --- b->fun() ---
     /doc/beispiele/shadow/cc [c] fun()
     /doc/beispiele/shadow/bb [b] fun()
     /doc/beispiele/shadow/aa [a] fun()
     --- c->fun() ---
     /doc/beispiele/shadow/cc [c] fun()
     /doc/beispiele/shadow/bb [b] fun()
     /doc/beispiele/shadow/aa [a] fun()
     --- b->fun2() ---
     /doc/beispiele/shadow/bb [b] fun2()
     /doc/beispiele/shadow/aa [a] fun3()
     /doc/beispiele/shadow/cc [c] fun3()

     // Der erste Aufruf von b::fun2() in a findet sofort a::fun3()! Der
     // Driver nimmt an, dass alle Shadows ab c bei Rufen von b nach a
     // schon ihre Chance hatten.
     // Der zweite Aufruf allerdings ist auf b und wird beim Durchgeben
     // an a von c uebernommen.

SIEHE AUCH
----------
::

     Generell:	     shadow(E)
     Rechte:	     query_allow_shadow(M), query_prevent_shadow(L)
     Informationen:  query_shadowing(E)

8.Aug 2007 Gloinson