OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
listener.h
1/*
2===========================================================================
3Copyright (C) 2008 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// listener.h: Listener
24
25#pragma once
26
27#include "class.h"
28#include "containerclass.h"
29#include "con_arrayset.h"
30#include "str.h"
31#include "vector.h"
32
33class Entity;
34class Listener;
35class ScriptClass;
36class ScriptThread;
37class ScriptVariable;
38class ScriptVariableList;
39class ScriptVM;
40class SimpleEntity;
41class Archiver;
42class EventQueueNode;
43
44// entity subclass
45#define ECF_ENTITY (1 << 0)
46#define ECF_ANIMATE (1 << 1)
47#define ECF_SENTIENT (1 << 2)
48#define ECF_PLAYER (1 << 3)
49#define ECF_ACTOR (1 << 4)
50#define ECF_ITEM (1 << 5)
51#define ECF_INVENTORYITEM (1 << 6)
52#define ECF_WEAPON (1 << 7)
53#define ECF_PROJECTILE (1 << 8)
54#define ECF_DOOR (1 << 9)
55#define ECF_CAMERA (1 << 10)
56#define ECF_VEHICLE (1 << 11)
57#define ECF_VEHICLETANK (1 << 12)
58#define ECF_VEHICLETURRET (1 << 13)
59#define ECF_TURRET (1 << 14)
60#define ECF_PATHNODE (1 << 15)
61#define ECF_WAYPOINT (1 << 16)
62#define ECF_TEMPWAYPOINT (1 << 17)
63#define ECF_VEHICLEPOINT (1 << 18)
64#define ECF_SPLINEPATH (1 << 19)
65#define ECF_CRATEOBJECT (1 << 20)
66#define ECF_BOT (1 << 21)
67
68// Event flags
69#define EV_CONSOLE (1 << 0) // Allow entry from console
70#define EV_CHEAT (1 << 1) // Only allow entry from console if cheats are enabled
71#define EV_CODEONLY (1 << 2) // Hide from eventlist
72#define EV_CACHE (1 << 3) // This event is used to cache data in
73#define EV_TIKIONLY (1 << 4) // This command only applies to TIKI files
74#define EV_SCRIPTONLY (1 << 5) // This command only applies to SCRIPT files
75#define EV_SERVERCMD (1 << 6) // Client : server command
76#define EV_DEFAULT -1 // default flag
77#define EV_ZERO 0
78
79// Event types
80#define EV_NORMAL 0 // Normal command
81#define EV_RETURN 1 // Return as a function (local.var = local ReturnCommand)
82#define EV_GETTER 2 // Return as a variable (local.var = local.listener.some_getter)
83#define EV_SETTER 3 // Set as a variable (local.listener.some_setter = "value")
84
85// times for posting events
86// Even though negative times technically don't make sense, the effect is to
87// sort events that take place at the start of a map so that they are executed
88// in the proper order. For example, spawnargs must occur before any script
89// commands take place, while unused entities must be removed before the spawnargs
90// are parsed.
91
92#define EV_REMOVE -9.0f // remove any unused entities before spawnargs are parsed
93#define EV_LINKBEAMS -9.0f // for finding out the endpoints of beams
94#define EV_VEHICLE -9.0f
95#define EV_PRIORITY_SPAWNARG -8.0f // for priority spawn args passed in by the bsp file
96#define EV_SETUP_ROPEPIECE -8.0f
97#define EV_SPAWNARG -7.0f // for spawn args passed in by the bsp file
98#define EV_SETUP_ROPEBASE -7.0f
99#define EV_PROCESS_INIT -6.0f
100#define EV_LINKDOORS -6.0f // for finding out which doors are linked together
101#define EV_POSTSPAWN -5.0f // for any processing that must occur after all objects are spawned
102#define EV_SPAWNENTITIES -4.0f
103#define EV_PRIORITY_SPAWNACTOR -3.0f
104#define EV_SPAWNACTOR -2.0f
105
106// Posted Event Flags
107#define EVENT_LEGS_ANIM (1 << 0) // this event is associated with an animation for the legs
108#define EVENT_TORSO_ANIM (1 << 1) // this event is associated with an animation for the torso
109#define EVENT_DIALOG_ANIM (1 << 2) // this event is associated with an animation for dialog lip syncing
110
111typedef enum {
112 IS_STRING,
113 IS_VECTOR,
114 IS_BOOLEAN,
115 IS_INTEGER,
116 IS_FLOAT,
117 IS_ENTITY,
118 IS_LISTENER
119} vartype;
120
121class EventArgDef : public Class
122{
123private:
124 int type;
125 str name;
126 float minRange[3];
127 qboolean minRangeDefault[3];
128 float maxRange[3];
129 qboolean maxRangeDefault[3];
130 qboolean optional;
131
132public:
133 EventArgDef()
134 {
135 type = IS_INTEGER;
136 //name = "undefined";
137 optional = qfalse;
138 };
139
140 void Setup(const char *eventName, const char *argName, const char *argType, const char *argRange);
141 void PrintArgument(FILE *event_file = NULL);
142 void PrintRange(FILE *event_file = NULL);
143 int getType(void);
144 const char *getName(void);
145 qboolean isOptional(void);
146
147 float GetMinRange(int index)
148 {
149 if (index < 3) {
150 return minRange[index];
151 }
152 return 0.0;
153 }
154
155 qboolean GetMinRangeDefault(int index)
156 {
157 if (index < 3) {
158 return minRangeDefault[index];
159 }
160 return qfalse;
161 }
162
163 float GetMaxRange(int index)
164 {
165 if (index < 3) {
166 return maxRange[index];
167 }
168 return 0.0;
169 }
170
171 qboolean GetMaxRangeDefault(int index)
172 {
173 if (index < 3) {
174 return maxRangeDefault[index];
175 }
176 return qfalse;
177 }
178};
179
180inline int EventArgDef::getType(void)
181{
182 return type;
183}
184
185inline const char *EventArgDef::getName(void)
186{
187 return name.c_str();
188}
189
190inline qboolean EventArgDef::isOptional(void)
191{
192 return optional;
193}
194
195class EventDef
196{
197public:
198 str command;
199 int flags;
200 const char *formatspec;
201 const char *argument_names;
202 const char *documentation;
203 uchar type;
204 Container<EventArgDef> *definition;
205
206 EventDef() { definition = NULL; }
207
208 void Error(const char *format, ...);
209
210 void PrintDocumentation(FILE *event_file, bool html);
211 void PrintEventDocumentation(FILE *event_file, bool html);
212
213 void DeleteDocumentation(void);
214 void SetupDocumentation(void);
215};
216
218{
219public:
220 Event *ev;
221 const char *command;
222 int flags;
223 const char *formatspec;
224 const char *argument_names;
225 const char *documentation;
226 int type;
227 DataNode *next;
228};
229
230class command_t
231{
232public:
233 const char *command;
234 int flags;
235 byte type;
236
237public:
238 command_t();
239 command_t(const char *name, byte t);
240
241 friend bool operator==(const char *name, const command_t& command);
242 friend bool operator==(const command_t& cmd1, const command_t& cmd2);
243};
244
245class Event : public Class
246{
247public:
248 qboolean fromScript;
249 short unsigned int eventnum;
250 short unsigned int dataSize;
251 short unsigned int maxDataSize;
252 ScriptVariable *data;
253
254#ifdef _DEBUG
255 // should be used only for debugging purposes
256 const char *name;
257#endif
258
259private:
260 static DataNode *DataNodeList;
261
262public:
263 CLASS_PROTOTYPE(Event);
264
265 static con_map<Event *, EventDef> eventDefList;
266 static con_arrayset<command_t, command_t> commandList;
267
268 static con_map<const_str, unsigned int> normalCommandList;
269 static con_map<const_str, unsigned int> returnCommandList;
270 static con_map<const_str, unsigned int> getterCommandList;
271 static con_map<const_str, unsigned int> setterCommandList;
272
273 static void LoadEvents(void);
274
275 static EventQueueNode EventQueue;
276
277 static int NumEventCommands();
278
279 static void ListCommands(const char *mask = NULL);
280 static void ListDocumentation(const char *mask, qboolean print_to_file = qfalse);
281 static void PendingEvents(const char *mask = NULL);
282
283 static int GetEvent(str name, uchar type = EV_NORMAL);
284 static int GetEventWithFlags(str name, int flags, uchar type = EV_NORMAL);
285
286 static command_t *GetEventInfo(int eventnum);
287 static int GetEventFlags(int eventnum);
288 static const char *GetEventName(int index);
289
290 static int compareEvents(const void *arg1, const void *arg2);
291 static void SortEventList(Container<int> *sortedList);
292
293 virtual void ErrorInternal(Listener *l, str text) const;
294
295 static bool Exists(const char *command);
296 static unsigned int FindEventNum(const char *s);
297 static unsigned int FindNormalEventNum(const_str s);
298 static unsigned int FindNormalEventNum(str s);
299 static unsigned int FindReturnEventNum(const_str s);
300 static unsigned int FindReturnEventNum(str s);
301 static unsigned int FindSetterEventNum(const_str s);
302 static unsigned int FindSetterEventNum(str s);
303 static unsigned int FindGetterEventNum(const_str s);
304 static unsigned int FindGetterEventNum(str s);
305
306 bool operator==(Event ev) { return eventnum == ev.eventnum; }
307
308 bool operator!=(Event ev) { return eventnum != ev.eventnum; }
309
310#ifndef _DEBUG_MEM
311 void *operator new(size_t size);
312 void operator delete(void *ptr);
313#endif
314
315 Event();
316 Event(const Event& ev);
317 Event(const Event& ev, int numArgs);
318 Event(Event&& ev);
319 Event(int index);
320 Event(int index, int numArgs);
321 Event(const char *command);
322 Event(const char *command, int numArgs);
323 Event(
324 const char *command,
325 int flags,
326 const char *
327 formatspec, // Arguments are : 'e' (Entity) 'v' (Vector) 'i' (Integer) 'f' (Float) 's' (String) 'b' (Boolean).
328 // Uppercase arguments means optional.
329 const char *argument_names,
330 const char *documentation,
331 byte type = EV_NORMAL
332 );
333
334 Event& operator=(const Event& ev);
335 Event& operator=(Event&& ev);
336
337 ~Event();
338
339#if defined(ARCHIVE_SUPPORTED)
340 void Archive(Archiver& arc) override;
341#endif
342
343#ifdef _GAME_DLL
344 eventInfo_t *getInfo();
345#else
346 EventDef *getInfo();
347#endif
348
349 const char *getName() const;
350
351 void AddContainer(Container<SafePtr<Listener>> *container);
352 void AddEntity(Entity *ent);
353 void AddFloat(float number);
354 void AddInteger(int number);
355 void AddListener(Listener *listener);
356 void AddNil(void);
357 void AddConstString(const_str string);
358 void AddString(str string);
359 void AddToken(str token);
360 void AddTokens(int argc, const char **argv);
361 void AddValue(const ScriptVariable& value);
362 void AddVector(const Vector& vector);
363 void CopyValues(const ScriptVariable *values, size_t count);
364
365 void Clear(void);
366
367 void CheckPos(int pos) const;
368
369 bool GetBoolean(int pos) const;
370
371 const_str GetConstString(int pos) const;
372
373 Entity *GetEntity(int pos) const;
374
375 float GetFloat(int pos) const;
376 int GetInteger(int pos) const;
377 Listener *GetListener(int pos) const;
378
379 class PathNode *GetPathNode(int pos) const;
380
381#ifdef WITH_SCRIPT_ENGINE
382 SimpleEntity *GetSimpleEntity(int pos) const;
383#endif
384
385 str GetString(int pos) const;
386 str GetToken(int pos) const;
387 ScriptVariable& GetValue(int pos) const;
388 ScriptVariable& GetValue(void);
389 Vector GetVector(int pos) const;
390
391 class Waypoint *GetWaypoint(int pos) const;
392
393 qboolean IsEntityAt(int pos) const;
394 qboolean IsListenerAt(int pos) const;
395 qboolean IsNilAt(int pos) const;
396 qboolean IsNumericAt(int pos) const;
397#ifdef WITH_SCRIPT_ENGINE
398 qboolean IsSimpleEntityAt(int pos) const;
399#endif
400 qboolean IsStringAt(int pos) const;
401 qboolean IsVectorAt(int pos) const;
402
403 qboolean IsFromScript(void) const;
404
405 int NumArgs() const;
406};
407
408#define NODE_CANCEL 1
409#define NODE_FIXED_EVENT 2
410
411class EventQueueNode : public LightClass
412{
413public:
414 Event *event;
415 int inttime;
416 int flags;
417 SafePtr<Listener> m_sourceobject;
418
419 EventQueueNode *prev;
420 EventQueueNode *next;
421
422#ifdef _DEBUG
423 const char *name;
424#endif
425
426 EventQueueNode()
427 {
428 prev = this;
429 next = this;
430
431#ifdef _DEBUG
432 name = NULL;
433#endif
434 }
435
436 Listener *GetSourceObject(void) { return m_sourceobject; }
437
438 void SetSourceObject(Listener *obj) { m_sourceobject = obj; }
439};
440
441template<class Type1, class Type2>
442class con_map;
443
444using ConList = ContainerClass<SafePtr<Listener>>;
445using eventMap = con_map<Event *, EventDef *>;
446
447using ListenerPtr = SafePtr<Listener>;
448
449class Listener : public Class
450{
451public:
452#ifdef WITH_SCRIPT_ENGINE
453 con_set<const_str, ConList> *m_NotifyList;
454 con_set<const_str, ConList> *m_WaitForList;
456 ScriptVariableList *vars;
457#endif
458
459 static bool EventSystemStarted;
460 static bool ProcessingEvents;
461
462private:
463#ifdef WITH_SCRIPT_ENGINE
464 void ExecuteScriptInternal(Event *ev, ScriptVariable& scriptVariable);
465 void ExecuteThreadInternal(Event *ev, ScriptVariable& returnValue);
466 void WaitExecuteScriptInternal(Event *ev, ScriptVariable& returnValue);
467 void WaitExecuteThreadInternal(Event *ev, ScriptVariable& returnValue);
468#endif
469
470 EventQueueNode *PostEventInternal(Event *ev, float delay, int flags);
471
472public:
473 CLASS_PROTOTYPE(Listener);
474
475#ifdef WITH_SCRIPT_ENGINE
476 /* Game functions */
477 virtual ScriptThread *CreateThreadInternal(const ScriptVariable& label);
478 virtual ScriptThread *CreateScriptInternal(const ScriptVariable& label);
479 virtual void StoppedNotify(void);
480 virtual void StartedWaitFor(void);
481 virtual void StoppedWaitFor(const_str name, bool bDeleting);
482#endif
483
484 virtual Listener *GetScriptOwner(void);
485 virtual void SetScriptOwner(Listener *newOwner);
486
487 Listener();
488 virtual ~Listener();
489
490 void Archive(Archiver& arc) override;
491
492 void CancelEventsOfType(Event *ev);
493 void CancelEventsOfType(Event& ev);
494 void CancelFlaggedEvents(int flags);
495 void CancelPendingEvents(void);
496
497 qboolean EventPending(Event& ev);
498
499 void PostEvent(Event *ev, float delay, int flags = 0);
500 void PostEvent(const Event& ev, float delay, int flags = 0);
501
502 qboolean PostponeAllEvents(float time);
503 qboolean PostponeEvent(Event& ev, float time);
504
505 bool ProcessEvent(const Event& ev);
506 bool ProcessEvent(Event *ev);
507 bool ProcessEvent(Event& ev);
508 ScriptVariable& ProcessEventReturn(Event *ev);
509
510 void ProcessContainerEvent(const Container<Event *>& conev);
511
512 qboolean ProcessPendingEvents(void);
513
514 bool ProcessScriptEvent(Event& ev);
515 bool ProcessScriptEvent(Event *ev);
516
517#ifdef WITH_SCRIPT_ENGINE
518
519 void CreateVars(void);
520 void ClearVars(void);
521 ScriptVariableList *Vars(void);
522
523 bool BroadcastEvent(Event& event, ConList *listeners);
524 bool BroadcastEvent(str name, Event& event);
525 bool BroadcastEvent(const_str name, Event& event);
526 void CancelWaiting(str name);
527 void CancelWaiting(const_str name);
528 void CancelWaitingAll(void);
529 void CancelWaitingSources(const_str name, ConList& listeners, ConList& stoppedListeners);
530
531 void ExecuteThread(str scriptName, str label, Event *params = NULL);
532 void ExecuteThread(str scriptName, str label, Event& params);
533
534 void EndOn(str name, Listener *listener);
535 void EndOn(const_str name, Listener *listener);
536 void Notify(const char *name);
537 void Register(str name, Listener *listener);
538 void Register(const_str name, Listener *listener);
539 void RegisterSource(const_str name, Listener *listener);
540 void RegisterTarget(const_str name, Listener *listener);
541 void Unregister(str name);
542 void Unregister(const_str name);
543 void Unregister(str name, Listener *listener);
544 void Unregister(const_str name, Listener *listener);
545 void UnregisterAll(void);
546 bool UnregisterSource(const_str name, Listener *listener);
547 bool UnregisterTarget(const_str name, Listener *listener);
548 void UnregisterTargets(
549 const_str name, ConList& listeners, ConList& stoppedListeners, Container<const_str>& stoppedNames
550 );
551 void AbortRegistration(const_str name, Listener *l);
552
553 int RegisterSize(const_str name) const;
554 int RegisterSize(str name) const;
555 int WaitingSize(const_str name) const;
556 int WaitingSize(str name) const;
557
558 bool WaitTillDisabled(str s);
559 bool WaitTillDisabled(const_str s);
560#endif
561
562 int GetFlags(Event *event) const;
563 qboolean ValidEvent(str name) const;
564
565 //
566 // Scripting functions
567 //
568 void CommandDelay(Event *ev);
569 void Remove(Event *ev);
570 void ScriptRemove(Event *ev);
571 void EventInheritsFrom(Event *ev);
572 void EventIsInheritedBy(Event *ev);
573 void GetClassname(Event *ev);
574
575#ifdef WITH_SCRIPT_ENGINE
576 void CancelFor(Event *ev);
577 void CreateReturnThread(Event *ev);
578 void CreateThread(Event *ev);
579 void ExecuteReturnScript(Event *ev);
580 void ExecuteScript(Event *ev);
581 void EventDelayThrow(Event *ev);
582 void EventEndOn(Event *ev);
583 void EventGetOwner(Event *ev);
584 void EventNotify(Event *ev);
585 void EventThrow(Event *ev);
586 void EventUnregister(Event *ev);
587 void WaitCreateReturnThread(Event *ev);
588 void WaitCreateThread(Event *ev);
589 void WaitExecuteReturnScript(Event *ev);
590 void WaitExecuteScript(Event *ev);
591 void WaitTill(Event *ev);
592 void WaitTillTimeout(Event *ev);
593 void WaitTillAny(Event *ev);
594 void WaitTillAnyTimeout(Event *ev);
595#endif
596};
597
598qboolean IsNumeric(const char *str);
599
600extern Event EV_DelayThrow;
601extern Event EV_Delete;
602extern Event EV_Remove;
603extern Event EV_ScriptRemove;
604extern Event EV_Throw;
605
606extern Event EV_Listener_CreateThread;
607extern Event EV_Listener_CreateReturnThread;
608extern Event EV_Listener_ExecuteReturnScript;
609extern Event EV_Listener_ExecuteScript;
610extern Event EV_Listener_WaitCreateReturnThread;
611
612extern int DisableListenerNotify;
613
614extern cvar_t *g_showevents;
615extern cvar_t *g_eventlimit;
616extern cvar_t *g_timeevents;
617extern cvar_t *g_watch;
618extern cvar_t *g_eventstats;
619
620extern MEM_BlockAlloc<Event> Event_allocator;
621
622#if defined(GAME_DLL)
623//
624// game dll specific defines
625//
626# define EVENT_DebugPrintf gi.DebugPrintf
627# define EVENT_DPrintf gi.DPrintf
628# define EVENT_Printf gi.Printf
629# define EVENT_time level.time
630# define EVENT_msec level.inttime
631# define EVENT_realtime gi.Milliseconds()
632# define EVENT_Error gi.Error
633
634# define EVENT_FILENAME "events.txt"
635
636#elif defined(CGAME_DLL)
637//
638// cgame dll specific defines
639//
640# define EVENT_DebugPrintf cgi.DebugPrintf
641# define EVENT_DPrintf cgi.DPrintf
642# define EVENT_Printf cgi.Printf
643# define EVENT_time (((float)cg.time / 1000.0f))
644# define EVENT_msec cg.time
645# define EVENT_realtime cgi.Milliseconds()
646# define EVENT_Error cgi.Error
647
648# define EVENT_FILENAME "cg_events.txt"
649
650#elif defined(UI_LIB)
651
652# define EVENT_DebugPrintf Com_DebugPrintf
653# define EVENT_DPrintf Com_DPrintf
654# define EVENT_Printf Com_Printf
655# define EVENT_time (((float)cls.realtime / 1000.0f))
656# define EVENT_msec cls.realtime
657# define EVENT_realtime Sys_Milliseconds()
658# define EVENT_Error Com_Error
659
660# define EVENT_FILENAME "ui_events.txt"
661
662#else
663//
664// client specific defines
665//
666# define EVENT_DebugPrintf Com_DebugPrintf
667# define EVENT_DPrintf Com_DPrintf
668# define EVENT_Printf Com_Printf
669# define EVENT_time (((float)cls.realtime / 1000.0f))
670# define EVENT_msec cls.realtime
671# define EVENT_realtime Sys_Milliseconds()
672# define EVENT_Error Com_Error
673
674# define EVENT_FILENAME "cl_events.txt"
675#endif
676
677void L_ClearEventList();
678bool L_EventSystemStarted(void);
679void L_InitEvents(void);
680void L_ProcessPendingEvents();
681void L_ShutdownEvents(void);
682void L_ArchiveEvents(Archiver& arc);
683void L_UnarchiveEvents(Archiver& arc);
Definition archive.h:86
Definition containerclass.h:32
Definition container.h:85
Definition listener.h:218
Definition entity.h:203
Definition listener.h:196
Definition listener.h:412
Definition listener.h:246
Definition lightclass.h:30
Definition listener.h:450
Definition mem_blockalloc.h:172
Definition navigate.h:153
Definition safeptr.h:160
Definition scriptclass.h:35
Definition scriptthread.h:28
Definition scriptvm.h:135
Definition scriptvariable.h:75
Definition simpleentity.h:42
Definition vector.h:61
Definition misc.h:320
Definition listener.h:231
Definition con_arrayset.h:94
Definition con_set.h:547
Definition con_set.h:119
Definition str.h:77