8 entity CallbackChain_New(string name)
11 e.classname = "callbackchain";
16 bool CallbackChain_Add(entity cb, bool() func, int order)
18 if (order & CBC_ORDER_FIRST) {
19 if (order & CBC_ORDER_LAST)
20 if (cb.cbc_order & CBC_ORDER_ANY)
22 if (cb.cbc_order & CBC_ORDER_FIRST)
24 } else if (order & CBC_ORDER_LAST) {
25 if (cb.cbc_order & CBC_ORDER_LAST)
28 entity thiscb = spawn();
29 thiscb.classname = "callback";
30 thiscb.cbc_func = func;
31 thiscb.cbc_order = order;
32 if (order & CBC_ORDER_FIRST) {
33 thiscb.cbc_next = cb.cbc_next;
35 } else if (order & CBC_ORDER_LAST) {
37 while (e.cbc_next) e = e.cbc_next;
40 // by default we execute last, but before a possible CBC_ORDER_LAST callback
42 // we must make sure that we insert BEFORE an CBC_ORDER_LAST mutator!
43 while (e.cbc_next && !(e.cbc_next.cbc_order & CBC_ORDER_LAST)) e = e.cbc_next;
44 thiscb.cbc_next = e.cbc_next;
47 cb.cbc_order |= (order | CBC_ORDER_ANY);
51 int CallbackChain_Remove(entity cb, bool() func)
54 for (entity e = cb; e.cbc_next; e = e.cbc_next) {
55 while (e.cbc_next.cbc_func == func) {
56 // remove e.cbc_next from the chain
57 entity e2 = e.cbc_next.cbc_next;
62 // e.cbc_next is now something we want to keep
63 order |= (e.cbc_next.cbc_order & CBC_ORDER_ANY);
69 bool CallbackChain_Call(entity cb)
72 for (entity e = cb; e.cbc_next; e = e.cbc_next) {
73 CallbackChain_ReturnValue = r;
74 r |= e.cbc_next.cbc_func();
76 return r; // callbacks return an error status, so 0 is default return value
79 const int MAX_MUTATORS = 15;
80 string loaded_mutators[MAX_MUTATORS];
81 bool Mutator_Add(mutatorfunc_t func, string name)
84 for (int i = 0; i < MAX_MUTATORS; ++i) {
85 if (name == loaded_mutators[i])
86 return true; // already added
87 if (!(loaded_mutators[i]))
91 backtrace("WARNING: too many mutators, cannot add any more\n");
94 loaded_mutators[j] = name;
96 if (!func(MUTATOR_ADDING)) {
101 backtrace("WARNING: when adding mutator: adding failed, rolling back\n");
103 if (func(MUTATOR_ROLLING_BACK)) {
105 error("WARNING: when adding mutator: rolling back failed");
109 void Mutator_Remove(mutatorfunc_t func, string name)
112 for (i = 0; i < MAX_MUTATORS; ++i)
113 if (name == loaded_mutators[i])
115 if (i >= MAX_MUTATORS) {
116 backtrace("WARNING: removing not-added mutator\n");
119 loaded_mutators[i] = string_null;
121 if (func(MUTATOR_REMOVING) != 0) {
123 error("Mutator_Remove: removing mutator failed");