33 |
using rpg::quest_event; |
using rpg::quest_event; |
34 |
|
|
35 |
// quest_event manager instance that is initialized when the rpg package is loaded |
// quest_event manager instance that is initialized when the rpg package is loaded |
36 |
// FIXME: breaks loading library |
static quest_event_manager QuestEventManager; |
|
// static quest_event_manager QuestEventManager; |
|
37 |
|
|
38 |
// function returning a new time event |
// function returning a new time event |
39 |
NEW_EVENT (rpg, quest_event) |
NEW_EVENT (rpg, quest_event) |
44 |
// nothing to do here |
// nothing to do here |
45 |
} |
} |
46 |
|
|
47 |
|
// dtor |
48 |
|
quest_event_manager::~quest_event_manager () |
49 |
|
{ |
50 |
|
std::map<std::string, std::vector<listener*> >::iterator i; |
51 |
|
for (i = Events.begin(); i != Events.end(); i++) |
52 |
|
{ |
53 |
|
std::vector<listener*> *li = &(*i).second; |
54 |
|
li->clear(); |
55 |
|
// delete li; // <-- causes double free |
56 |
|
} |
57 |
|
} |
58 |
|
|
59 |
// See whether a matching event is registered and execute the |
// See whether a matching event is registered and execute the |
60 |
// according script(s) |
// according script(s) |
61 |
void quest_event_manager::raise_event (const event * e) |
void quest_event_manager::raise_event (const event *e) |
62 |
|
{ |
63 |
|
std::map<std::string, std::vector<listener*> >::iterator li; |
64 |
|
static std::string paths[] = { "", "*", ">" }; |
65 |
|
quest_event *ev = (quest_event *) e; |
66 |
|
paths[0] = *(ev->begin()); |
67 |
|
|
68 |
|
for (int i = 0; i < 3; i++) |
69 |
|
{ |
70 |
|
if ((li = Events.find (paths[i])) != Events.end ()) |
71 |
|
{ |
72 |
|
raise_event (e, &(*li).second); |
73 |
|
} |
74 |
|
} |
75 |
|
} |
76 |
|
|
77 |
|
// raise all matching events in given list of listeners |
78 |
|
void quest_event_manager::raise_event (const event *e, std::vector<listener*> *listeners) |
79 |
{ |
{ |
80 |
|
s_int32 repeat; |
81 |
|
|
82 |
|
for (std::vector<listener*>::iterator li = listeners->end (); li != listeners->begin(); /* nothing */ ) |
83 |
|
{ |
84 |
|
li--; |
85 |
|
|
86 |
|
// if events equal ... |
87 |
|
if ((*li)->equals (e)) |
88 |
|
{ |
89 |
|
// .. raise event and ... |
90 |
|
repeat = (*li)->raise_event (e); |
91 |
|
// ... remove listener if repeat count reaches zero |
92 |
|
if (repeat == 0) listeners->erase (li); |
93 |
|
} |
94 |
|
} |
95 |
} |
} |
96 |
|
|
97 |
// Unregister a listener |
// Unregister a listener |
98 |
void quest_event_manager::remove (listener *li) |
void quest_event_manager::remove (listener *li) |
99 |
{ |
{ |
100 |
|
quest_event *ev = (quest_event *) li->get_event(); |
101 |
|
std::map<std::string, std::vector<listener*> >::iterator e; |
102 |
|
std::string path = *(ev->begin()); |
103 |
|
|
104 |
|
// try to find vector where listener would be stored |
105 |
|
if ((e = Events.find (path)) != Events.end ()) |
106 |
|
{ |
107 |
|
std::vector<listener*>::iterator i; |
108 |
|
|
109 |
|
// Search for the listener we want to remove |
110 |
|
i = find ((*e).second.begin (), (*e).second.end (), li); |
111 |
|
|
112 |
|
// found? -> get rid of it :) |
113 |
|
if (i != (*e).second.end ()) |
114 |
|
{ |
115 |
|
(*e).second.erase (i); |
116 |
|
return; |
117 |
|
} |
118 |
|
} |
119 |
|
|
120 |
|
// if we end up here, listener wasn't registered or already removed |
121 |
|
fprintf (stderr, "*** quest_event_manager::remove: listener not registered!\n"); |
122 |
} |
} |
123 |
|
|
124 |
// register a listener with the manager |
// register a listener with the manager |
125 |
void quest_event_manager::add (listener *li) |
void quest_event_manager::add (listener *li) |
126 |
{ |
{ |
127 |
|
quest_event *ev = (quest_event *) li->get_event(); |
128 |
|
std::map<std::string, std::vector<listener*> >::iterator e; |
129 |
|
std::string path = *(ev->begin()); |
130 |
|
|
131 |
|
// add listener to those with the same first path element |
132 |
|
if ((e = Events.find (path)) != Events.end ()) |
133 |
|
{ |
134 |
|
(*e).second.push_back (li); |
135 |
|
} |
136 |
|
else |
137 |
|
{ |
138 |
|
std::vector<listener*> *listeners = new std::vector<listener*>(); |
139 |
|
listeners->push_back (li); |
140 |
|
Events[path] = *listeners; |
141 |
|
} |
142 |
} |
} |