8 entity CallbackChain_New(string name)
12 e.classname = "callbackchain";
17 float CallbackChain_Add(entity cb, float() func, float order)
20 if(order & CBC_ORDER_FIRST)
22 if(order & CBC_ORDER_LAST)
23 if(cb.cbc_order & CBC_ORDER_ANY)
25 if(cb.cbc_order & CBC_ORDER_FIRST)
28 else if(order & CBC_ORDER_LAST)
30 if(cb.cbc_order & CBC_ORDER_LAST)
35 thiscb.classname = "callback";
36 thiscb.cbc_func = func;
37 thiscb.cbc_order = order;
38 if(order & CBC_ORDER_FIRST)
40 thiscb.cbc_next = cb.cbc_next;
43 else if(order & CBC_ORDER_LAST)
45 for(e = cb; e.cbc_next; e = e.cbc_next);
50 // by default we execute last, but before a possible CBC_ORDER_LAST callback
51 for(e = cb; e.cbc_next && !(e.cbc_next.cbc_order & CBC_ORDER_LAST); e = e.cbc_next); // we must make sure that we insert BEFORE an CBC_ORDER_LAST mutator!
52 thiscb.cbc_next = e.cbc_next;
55 cb.cbc_order |= (order | CBC_ORDER_ANY);
59 float CallbackChain_Remove(entity cb, float() func)
66 for(e = cb; e.cbc_next; e = e.cbc_next)
68 while(e.cbc_next.cbc_func == func)
70 // remove e.cbc_next from the chain
72 e2 = e.cbc_next.cbc_next;
77 // e.cbc_next is now something we want to keep
78 order |= (e.cbc_next.cbc_order & CBC_ORDER_ANY);
84 float CallbackChain_Call(entity cb)
89 for(e = cb; e.cbc_next; e = e.cbc_next)
91 CallbackChain_ReturnValue = r;
92 r |= e.cbc_next.cbc_func();
94 return r; // callbacks return an error status, so 0 is default return value
97 const float MAX_MUTATORS = 15;
98 string loaded_mutators[MAX_MUTATORS];
99 float Mutator_Add(mutatorfunc_t func, string name)
103 for(i = 0; i < MAX_MUTATORS; ++i)
105 if(name == loaded_mutators[i])
106 return 1; // already added
107 if (!(loaded_mutators[i]))
112 backtrace("WARNING: too many mutators, cannot add any more\n");
115 loaded_mutators[j] = name;
117 if(func(MUTATOR_ADDING) == 0)
123 backtrace("WARNING: when adding mutator: adding failed, rolling back\n");
125 if(func(MUTATOR_ROLLING_BACK) != 0)
128 error("WARNING: when adding mutator: rolling back failed");
132 void Mutator_Remove(float(float) func, string name)
135 for(i = 0; i < MAX_MUTATORS; ++i)
136 if(name == loaded_mutators[i])
138 if(i >= MAX_MUTATORS)
140 backtrace("WARNING: removing not-added mutator\n");
143 loaded_mutators[i] = string_null;
145 if(func(MUTATOR_REMOVING) != 0)
148 error("Mutator_Remove: removing mutator failed");