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