CONCEPT
std_rooms - spezielle Standardraeume fuer (begrenzte) Gebiete
IDEA
Moechte man eine ganze Menge von Raeumen mit etwas gleichem aus-
ruesten, sei es Details, sei es Befehle oder Funktionen, so kann man
sich fuer diese einen speziellen Standardraum anlegen, der genau das
bereitstellt.
Anstelle von "/std/room" erbt man dann von diesem Raum und hat so
standardmaessig schon einige Details oder Befehle oder Funktionen
in dem Raum.
Dies hat unter anderem den Vorteil, dass man die Details/den Code
an einer zentralen Stelle fuer alle diese Raeume pflegen kann.
Dieses Verfahren wird oft verwendet und ebenso oft werden dabei
kapitale Fehler begangen, die dem Magier so beim Testen erstmal
nicht auffallen. Diese Hilfeseite soll nun etwas Licht darauf
werfen, was man tun und was lassen sollte, um eine stabile
Umsetzung zu erreichen.
DESCRIPTION
Im Wesentlichen werden zwei Dinge oftmals nicht beachtet, auch weil
sie nicht richtig dokumentiert sind *g*. Dies ist einmal die
Programm-Verdraengung im (eigenen) Standardraum, die ggf. auftreten
kann. Weiterhin ist es das Loeschen bereits gesetzter Eigenschaften.
Programm-Verdraengung wird in Raeumen angewendet, um Speicherplatz
zu sparen. Hat ein Raum nur eine Funktion create(), so wirft er
nach dem create() sein Programm weg (s.a. replace_program(E) und
_create(L)). Wuerde jetzt create() in dem Objekt aufgerufen, so
gelangt dies sofort an ::create(), da das Objekt den Code einfach
nicht mehr hat.
Fuer normale Raeume ist dies ok, da sie ein paar Properties setzen
und dann ist create() ja auch ueberfluessig. Bei (eigenen)
Standardraeume kann dies jedoch zu Problemen fuehren:
Nehmen wir an, wir machen einen Standardraum, in dem einige zur
Region gehoerige Details gesetzt werden, die halt immer wieder
auftreten. Zusaetzlich wollen wir eine einheitliche Nachtbeschreibung.
Wir machen also einen Standardraum fuer diese Region. Sie beinhaltet
nur create() wo diese Werte halt gesetzt werden.
Jetzt machen wir ein paar Raeume, die von diesem Raum erben. Wir
laden die Raeume und alles scheint wunderbar zu funktionieren.
Irgendwann spaeter stolpert Fiona ueber unseren Code und schreit
entgeistert rum. Wieso nur?
Ganz einfach. Nehmen wir an, irgendein Magier hat Langeweile. Er
behebt einen Typo in unserem Standardraum. Um zu sehen ob es geht,
laedt er ihn dann auch. Auch jetzt scheint noch alles problemlos.
Aber was passiert genau? Wenn wir den Standardraum explizit laden,
wird natuerlich auch sein create() ausgefuehrt. Im create() bemerkt
er, dass er Speicher sparen kann, wenn er sein Programm wegwirft.
Wenn nun ein Raum von dem Standardraum erbt, so ist da kein
spezielles create() vorhanden (es wurde ja weggeworfen), also fehlen
alle unsere schoenen Details und so weiter.
(Implizites Laden eines Objektes durch Ererbung loest _nicht_ das
create() im Objekt aus, was als Ererbungsquelle dient.)
Wie beheben wir das? Irgendeine (leere) Funktion in den Standardraum
einbauen. Eine Zeile der Art void blah() {} genuegt. Wenn wir
mehrere verschiedene Standardraeume anlegen wollen, empfliehlt es
sich, diese einfach alle in ein File zu legen. Wir machen eine
Funktion der Art:
void my_create(string typus) {
switch (typus) {
case "wald" : [...]
case "lichtung" : [...]
case "pilze_vorhanden": [...]
[...]
}
}
Damit haben wir erstmal eine Funktion neben create(), es kann also
keine Programmverdraengung mehr auftreten. Zweitens sparen wir
die ganzen Blueplans fuer zig verschiedene Standardraeume - wir
haben fuer alle einen gemeinsamen.
Und bequem ist es auch, man erbt (nur) von diesem Standardraum,
im create() ruft man dann auf:
void create() {
::create();
filter(({"wald","pilze_vorhanden"}), "my_create");
[...]
}
Das zweite Problem - loeschen bereits gesetzter Eigenschaften - ist
eher leicht einzusehen. Nichtsdestrotrotz kommen hier auch immer
mal Schwierigkeiten vor. Jedoch kann dieses Problem nur dann
auftreten, wenn man sich nicht an eine weitere Forderung Fionas
haelt: Der Vererbungsbaum soll moeglichst flach und geradlinig
gehalten werden. Also unser Standardraum erbt von /std/room,
die einzelnen Raeume nur von unserem Standardraum usw. Nur auf
diese Art kann der Speicherspar-Mechanismus der oben beschrieben
wurde auch fuer alle unsere Raeume in der Region benutzt werden.
Sollte man sich, aus welchen Gruenden auch immer, _nicht_ an diese
Regel halten, so kommt manchmal solch ein Code heraus:
inherit "/std/room"; // Negativbeispiel
inherit "..../my_std_room";
create() {
my_std_room::create();
room::create();
[...]
}
Das Aufrufen von create() aus dem /std/room loescht (!) jedoch
viele bereits gesetzte Properties, weil diese halt initialisiert
werden.
Wie gesagt, solche eine Vererbung ist sowieso zu vermeiden! Also
sollte das Problem auch nicht auftreten.
SEE ALSO
replace_program(E), create(A), _create(L)
|