blob: c09eaabeff71d40e04e2ca3861696bacbc3bc559 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// virtual/v_compiler.c -- a general virtual compiler object
4//
5// $Id: v_compiler.c 9142 2015-02-04 22:17:29Z Zesstra $
6
7// principle:
8// - inherit this object into your own 'virtual_compiler.c'
9// - customize Validate() and CustomizeObject() for you own sake
10//
11// * Validate() checks if a room filename given as argument (without path)
12// is valid and returns this filename with stripped '.c'!!
13// * CustomizeObject() uses the previous_object()->Function() strategy to
14// customize the standard object (for example to set a description)
15//
16// Properties: P_STD_OBJECT, P_COMPILER_PATH
17
18#pragma strict_types
19#pragma save_types
20#pragma range_check
21#pragma no_clone
MG Mud User88f12472016-06-24 23:31:02 +020022
23inherit "/std/thing/properties";
24
25//#define NEED_PROTOTYPES
26
27#include <thing/properties.h>
28#include <defines.h>
29#include <v_compiler.h>
30#include <exploration.h>
31#include <sys_debug.h>
32#include <living/description.h> //fuer P_PARA
33
34// Der VC braucht das 'alte' object_name()-basierte BLUE_NAME, da sonst das
35// Konfigurieren der von einem VC-Objekt geclonten Clones via
36// CustomizeObject() nicht funktioniert (load_name() ermittelt den Namen des
37// VC-Standardobjektes)
38#ifdef BLUE_NAME
39#undef BLUE_NAME
40#endif
41#define BLUE_NAME(ob) (explode(object_name(ob),"#")[0])
42
43private nosave string last_loaded_file;
44private nosave mapping objects;
45
46void create()
47{
48 ::create();
49 seteuid(getuid());
50 SetProp(P_STD_OBJECT, "/std/room");
51 SetProp(P_COMPILER_PATH, sprintf("/%s/",
52 implode(old_explode(object_name(this_object()), "/")[0..<2], "/")));
53 SetProp(P_PARA, ({}) ); // keine Para-VC-Objekte
54 objects = ([]);
55}
56
57// von den erbenen VCs zu ueberschreiben...
58// TODO: aus Standardobjekt entfernen, weil durch P_PARA und QueryValidObject
59// obsolet.
60int NoParaObjects() { return 0; }
61
Zesstra9b4e9332019-07-19 16:31:43 +020062// Standardmaessig nur .c abschneiden und den EPMASTER anstossen.
MG Mud User88f12472016-06-24 23:31:02 +020063string Validate(string file)
64{
65 if(!file) return 0;
66 if(file[<2..] == ".c") file = file[0..<3];
67 EPMASTER->PrepareVCQuery(file);
68 return file;
69}
70
71// Die Funktion bekommt einen Objektnamen uebergeben und muss entscheiden, ob
72// dieser VC dafuer zustaendig ist, das Objekt zu generieren. Jeder Wert != 0
73// zaehlt als 'zustaendig'. Es ist eine Art generalisiertem Validate(). Fuer
74// maximale Nuetzlichkeit muss diese Funktion von den erbenden VCs
75// ueberschrieben werden.
76public int QueryValidObject(string oname) {
77 string fname, path, *pelem;
78 int para;
79 mixed ppara;
80
81 //erstmal Validate fragen
82 pelem=explode(oname,"/");
83 fname=pelem[<1];
84 if (!fname=Validate(fname))
85 return(0); //nicht zustaendig
86 // nicht im richtigen Pfad?
87 path=sprintf("%s/",implode(pelem[0..<2],"/"));
88 if (path!=QueryProp(P_COMPILER_PATH))
89 return(0);
90 // Para-Objekt?
91 if (sscanf(fname,"%s^%d",fname,para) > 1) {
92 if (NoParaObjects())
93 return(0); //direkt zurueck, keine Para-Objekte
94 // bestimmte Para-Dimensionen explizit erlaubt? (Wenn P_PARA nicht
95 // gesetzt ist, sind alle erlaubt!)
96 if (ppara=QueryProp(P_PARA)) {
97 if (pointerp(ppara) && member(ppara,para)!=-1)
98 return(1);
99 else if (intp(para) && ppara==para)
100 return(1);
101 // P_PARA gesetzt, aber gewuenschtes Para nicht enthalten...
102 else return(0);
103 }
104 }
105 return(1); //fall-through, offenbar zustaendig.
106}
107
108mixed CustomizeObject()
109{
110 string file;
Zesstra9b4e9332019-07-19 16:31:43 +0200111 // Wenn !clonep ist es schon ein per VC umbenanntes File und wir koennen den
112 // BLUE_NAME von PO nehmen.
MG Mud User88f12472016-06-24 23:31:02 +0200113 if(!clonep(previous_object()))
114 return Validate(explode(BLUE_NAME(previous_object()), "/")[<1]);
Zesstra9b4e9332019-07-19 16:31:43 +0200115 // Sonst muessen wir gucken, welche File wir zuletzt erzeugt haben - der
116 // Clone dafuer ist erzeugt (der ruft uns gerade), aber es ist noch nicht
117 // vom Driver umbenannt in den endgueltigen Namen. Wenn wir kein
118 // last_loaded_file haben, naja...
119 if(stringp(last_loaded_file))
120 file = last_loaded_file;
121 else
122 file = Validate(explode(BLUE_NAME(previous_object()), "/")[<1]);
MG Mud User88f12472016-06-24 23:31:02 +0200123 if(!file) return 0;
124 last_loaded_file = 0;
Zesstra9b4e9332019-07-19 16:31:43 +0200125 // Das sollte nun das File sein, was wir gerade erzeugen.
MG Mud User88f12472016-06-24 23:31:02 +0200126 return file;
127}
128
129// add a new object to the object list if it compiles
130private mixed AddObject(string file)
131{
132 object ob;
MG Mud User88f12472016-06-24 23:31:02 +0200133
134 // clean up the object list
135 objects = filter_indices(objects, function int (string f) {
136 return (objectp(objects[f])); } );
137
138 last_loaded_file = file;
139 // register new object
140 if(ob = clone_object(QueryProp(P_STD_OBJECT)))
141 objects[file] = ob;
142 return ob;
143}
144
145// try to create an object for the wanted file
146mixed compile_object(string file)
147{
148 // validate if the file name is a correct one
149 if(file = Validate(file))
150 return AddObject(file);
151 return 0;
152}
153
154// return all cloned virtual objects
155mixed QueryObjects()
156{
157 return m_values(objects)-({0});
158}
159
160// clean up rooms that have not been destructed yet
161int remove() {
162
163 if(!mappingp(objects)) return 0;
164
165 //for(ob = QueryObjects(); sizeof(ob); ob = ob[1..])
166 foreach(object ob: QueryObjects()) {
167 ob->remove();
168 if(objectp(ob)) destruct(ob);
169 }
170 return 1;
171}
172