Objekt Tests bei call_out()


Hallo,

Bei der Durchsicht von fremden Code ist mir aufgefallen, dass oftmals vergessen wird abzufragen, ob ein Objekt überhaupt noch existiert oder es sich noch im Raum befindet, bevor damit irgend etwas angestellt wird. Besonders wenn Zeit vergangen ist (z.B. durch call_out()), kann dies zu Bugs führen. Das scheint ein beliebter Anfängerfehler zu sein.

Hier ein Beispiel, wie man es nicht machen sollte:


#pragma strong_types

#include <properties.h>
#include <language.h>

inherit "/std/room";

protected void create()
{
  ::create();

  SetProp(P_INT_SHORT, "Ein Raum");
  SetProp(P_INT_LONG,  "Ein Raum.");
  SerProp(P_INT_LONG_EXT,"Ein Baum.\n");
  SetProp(P_LIGHT,1);

  AddCmd(({"lach","lache"}),"lachen_act")
}

static void message(object pl)
{
  // Medlung an Spieler
  tell_object(pl,"Der Baum schaut Dich verwundert an.\n");
}

static int lachen_act(string str)
{
  if(find_call_out("message") == -1)     // call_out() läuft noch nicht
    call_out("message",2,this_player()); // Meldung per call_out() starten

  return 0;
}

In der Funktion message(), die per call_out() aufgerufen wird, wird hier dem Spieler eine Nachricht per tell_object() gesendet. Das Problem hierbei ist aber, dass bis zum Aufruf von message() Zeit vergeht. In dieser Zeit kann der Spieler das Mud (der Objekt-Pointer ist dann weg) oder den Raum verlassen haben. Im ersten Fall gibt es einen Fehler, im zweiten Fall bekommt der Spieler die Nachricht, obwohl er gar nicht mehr im diesem Raum steht.

Hier mal eine bessere Funktion fuer message()

static void message(object pl)
{
  if(objectp(pl)) // existiert das Spielerobjekt überhaupt noch...
    if(present(pl,this_object())) // steht der Spieler noch in diesem Raum
      // Medlung an Spieler
      tell_object(pl,"Der Baum schaut Dich verwundert an.\n");
}

Das gilt natürlich nicht nur für Spieler und Räume, sondern immer dann, wenn mit Objekten über call_out() etwas angestellt werden soll.

Gruß,

– It –