[286] | 1 | // This file is a part of Framsticks SDK. http://www.framsticks.com/ |
---|
| 2 | // Copyright (C) 1999-2015 Maciej Komosinski and Szymon Ulatowski. |
---|
| 3 | // See LICENSE.txt for details. |
---|
[138] | 4 | |
---|
| 5 | #include "mutparamlist.h" |
---|
| 6 | #include <frams/util/extvalue.h> |
---|
| 7 | |
---|
| 8 | struct ParamInfo |
---|
| 9 | { |
---|
[792] | 10 | ParamInterface *pi; |
---|
| 11 | MutableParamInterface *mpi; |
---|
| 12 | CallbackNode *anode, *dnode, *ganode, *gdnode, *cnode, *gcnode, *panode; |
---|
| 13 | int firstprop, firstgroup; |
---|
| 14 | int propcount, groupcount; |
---|
[138] | 15 | }; |
---|
| 16 | |
---|
| 17 | ParamInfo* MutableParamList::getParamInfo(int i) |
---|
| 18 | { |
---|
[792] | 19 | return (ParamInfo*)list(i); |
---|
[138] | 20 | } |
---|
| 21 | |
---|
[792] | 22 | void MutableParamList::addPI(int pos, ParamInfo *pi) |
---|
[138] | 23 | { |
---|
[792] | 24 | int propcount = pi->propcount; |
---|
| 25 | int groupcount = pi->groupcount; |
---|
| 26 | if (pos == 0) |
---|
[138] | 27 | { |
---|
[792] | 28 | pi->firstprop = 0; |
---|
| 29 | pi->firstgroup = 0; |
---|
[138] | 30 | } |
---|
[792] | 31 | else |
---|
[138] | 32 | { |
---|
[792] | 33 | ParamInfo *prev_pi = getParamInfo(pos - 1); |
---|
| 34 | pi->firstprop = prev_pi->firstprop + prev_pi->propcount; |
---|
| 35 | pi->firstgroup = prev_pi->firstgroup + prev_pi->groupcount; |
---|
[138] | 36 | } |
---|
[792] | 37 | list.insert(pos, pi); |
---|
| 38 | pi->propcount = 0; |
---|
| 39 | pi->groupcount = 0; |
---|
| 40 | for (int i = 0; i < groupcount; i++) |
---|
[138] | 41 | { |
---|
[792] | 42 | pi->groupcount = i + 1; |
---|
| 43 | adjustPI(pos + 1, 0, 1); |
---|
| 44 | ongroupadd.action(pi->firstgroup + i); |
---|
[138] | 45 | } |
---|
[792] | 46 | for (int i = 0; i < propcount; i++) |
---|
[138] | 47 | { |
---|
[792] | 48 | pi->propcount = i + 1; |
---|
| 49 | adjustPI(pos + 1, 1, 0); |
---|
| 50 | onadd.action(pi->firstprop + i); |
---|
[138] | 51 | } |
---|
[792] | 52 | if (pi->mpi) |
---|
| 53 | { |
---|
| 54 | pi->anode = pi->mpi->onadd.add(STATRICKCALLBACK(this, &MutableParamList::onPropAdd, pi)); |
---|
| 55 | pi->ganode = pi->mpi->ongroupadd.add(STATRICKCALLBACK(this, &MutableParamList::onGroupAdd, pi)); |
---|
| 56 | pi->dnode = pi->mpi->ondelete.add(STATRICKCALLBACK(this, &MutableParamList::onPropDelete, pi)); |
---|
| 57 | pi->gdnode = pi->mpi->ongroupdelete.add(STATRICKCALLBACK(this, &MutableParamList::onGroupDelete, pi)); |
---|
| 58 | pi->cnode = pi->mpi->onchange.add(STATRICKCALLBACK(this, &MutableParamList::onPropChange, pi)); |
---|
| 59 | pi->gcnode = pi->mpi->ongroupchange.add(STATRICKCALLBACK(this, &MutableParamList::onGroupChange, pi)); |
---|
| 60 | pi->panode = pi->mpi->onactivate.add(STATRICKCALLBACK(this, &MutableParamList::onPropActivate, pi)); |
---|
| 61 | } |
---|
[138] | 62 | } |
---|
| 63 | |
---|
| 64 | int MutableParamList::findPI(ParamInfo *pi) |
---|
| 65 | { |
---|
[792] | 66 | return list.find((void*)pi); |
---|
[138] | 67 | } |
---|
| 68 | |
---|
| 69 | int MutableParamList::findPI(ParamInterface *p) |
---|
| 70 | { |
---|
[792] | 71 | ParamInfo *pi; |
---|
| 72 | for (int i = 0; pi = (ParamInfo*)list(i); i++) |
---|
| 73 | if ((!pi->mpi) && (pi->pi == p)) return i; |
---|
| 74 | return -1; |
---|
[138] | 75 | } |
---|
| 76 | |
---|
| 77 | int MutableParamList::findPI(MutableParamInterface *p) |
---|
| 78 | { |
---|
[792] | 79 | ParamInfo *pi; |
---|
| 80 | for (int i = 0; pi = (ParamInfo*)list(i); i++) |
---|
| 81 | if ((pi->mpi) && (pi->mpi == p)) return i; |
---|
| 82 | return -1; |
---|
[138] | 83 | } |
---|
| 84 | |
---|
[792] | 85 | void MutableParamList::adjustPI(int firstPI, int addprop, int addgroup) |
---|
[138] | 86 | { |
---|
[792] | 87 | ParamInfo *pi; |
---|
| 88 | for (int i = firstPI; pi = getParamInfo(i); i++) |
---|
[138] | 89 | { |
---|
[792] | 90 | pi->firstprop += addprop; |
---|
| 91 | pi->firstgroup += addgroup; |
---|
[138] | 92 | } |
---|
| 93 | } |
---|
| 94 | |
---|
| 95 | void MutableParamList::removePI(int pi_index) |
---|
| 96 | { |
---|
[792] | 97 | if (pi_index < 0) return; |
---|
| 98 | ParamInfo *pi = getParamInfo(pi_index); |
---|
| 99 | for (int i = pi->propcount - 1; i >= 0; i--) |
---|
[138] | 100 | { |
---|
[792] | 101 | pi->propcount = i; |
---|
| 102 | adjustPI(pi_index + 1, -1, 0); |
---|
| 103 | ondelete.action(i); |
---|
[138] | 104 | } |
---|
[792] | 105 | for (int i = pi->groupcount - 1; i >= 0; i--) |
---|
[138] | 106 | { |
---|
[792] | 107 | pi->groupcount = i; |
---|
| 108 | adjustPI(pi_index + 1, 0, -1); |
---|
| 109 | ongroupdelete.action(i); |
---|
[138] | 110 | } |
---|
[792] | 111 | list -= (pi_index); |
---|
| 112 | if (pi->mpi) |
---|
[138] | 113 | { |
---|
[792] | 114 | pi->mpi->onadd.remove(pi->anode); |
---|
| 115 | pi->mpi->ongroupadd.remove(pi->ganode); |
---|
| 116 | pi->mpi->ondelete.remove(pi->dnode); |
---|
| 117 | pi->mpi->ongroupdelete.remove(pi->gdnode); |
---|
| 118 | pi->mpi->onchange.remove(pi->cnode); |
---|
| 119 | pi->mpi->ongroupchange.remove(pi->gcnode); |
---|
| 120 | pi->mpi->onactivate.remove(pi->panode); |
---|
[138] | 121 | } |
---|
[792] | 122 | delete pi; |
---|
[138] | 123 | } |
---|
| 124 | |
---|
| 125 | MutableParamList::~MutableParamList() |
---|
| 126 | { |
---|
[792] | 127 | for (int i = list.size() - 1; i >= 0; i--) |
---|
| 128 | removePI(i); |
---|
[138] | 129 | } |
---|
| 130 | |
---|
[792] | 131 | void MutableParamList::onPropAdd(void* data, intptr_t i) |
---|
[138] | 132 | { |
---|
[792] | 133 | ParamInfo *pi = (ParamInfo*)data; |
---|
| 134 | pi->propcount++; |
---|
| 135 | int j = findPI(pi); |
---|
| 136 | if (j >= 0) |
---|
| 137 | adjustPI(j + 1, 1, 0); |
---|
| 138 | onadd.action(pi->firstprop + i); |
---|
[138] | 139 | } |
---|
| 140 | |
---|
[792] | 141 | void MutableParamList::onPropDelete(void* data, intptr_t i) |
---|
[138] | 142 | { |
---|
[792] | 143 | ParamInfo *pi = (ParamInfo*)data; |
---|
| 144 | pi->propcount--; |
---|
| 145 | int j = findPI(pi); |
---|
| 146 | if (j >= 0) |
---|
| 147 | adjustPI(j + 1, -1, 0); |
---|
| 148 | ondelete.action(pi->firstprop + i); |
---|
[138] | 149 | } |
---|
| 150 | |
---|
[792] | 151 | void MutableParamList::onPropChange(void* data, intptr_t i) |
---|
[138] | 152 | { |
---|
[792] | 153 | ParamInfo *pi = (ParamInfo*)data; |
---|
| 154 | onchange.action(pi->firstprop + i); |
---|
[138] | 155 | } |
---|
| 156 | |
---|
[792] | 157 | void MutableParamList::onPropActivate(void* data, intptr_t i) |
---|
[138] | 158 | { |
---|
[792] | 159 | ParamInfo *pi = (ParamInfo*)data; |
---|
| 160 | onactivate.action(pi->firstprop + i); |
---|
[138] | 161 | } |
---|
| 162 | |
---|
[792] | 163 | void MutableParamList::onGroupAdd(void* data, intptr_t i) |
---|
[138] | 164 | { |
---|
[792] | 165 | ParamInfo *pi = (ParamInfo*)data; |
---|
| 166 | pi->groupcount++; |
---|
| 167 | int j = findPI(pi); |
---|
| 168 | if (j >= 0) |
---|
| 169 | adjustPI(j + 1, 0, 1); |
---|
| 170 | ongroupadd.action(pi->firstgroup + i); |
---|
[138] | 171 | } |
---|
| 172 | |
---|
[792] | 173 | void MutableParamList::onGroupDelete(void* data, intptr_t i) |
---|
[138] | 174 | { |
---|
[792] | 175 | ParamInfo *pi = (ParamInfo*)data; |
---|
| 176 | pi->groupcount--; |
---|
| 177 | int j = findPI(pi); |
---|
| 178 | if (j >= 0) |
---|
| 179 | adjustPI(j + 1, 0, -1); |
---|
| 180 | ongroupdelete.action(pi->firstgroup + i); |
---|
[138] | 181 | } |
---|
| 182 | |
---|
[792] | 183 | void MutableParamList::onGroupChange(void* data, intptr_t i) |
---|
[138] | 184 | { |
---|
[792] | 185 | ParamInfo *pi = (ParamInfo*)data; |
---|
| 186 | ongroupchange.action(pi->firstgroup + i); |
---|
[138] | 187 | } |
---|
| 188 | |
---|
[792] | 189 | void MutableParamList::insert(int pos, MutableParamInterface *p) |
---|
[138] | 190 | { |
---|
[792] | 191 | ParamInfo *pi = new ParamInfo(); |
---|
| 192 | pi->pi = (ParamInterface*)p; |
---|
| 193 | pi->mpi = p; |
---|
| 194 | pi->propcount = p->getPropCount(); |
---|
| 195 | pi->groupcount = p->getGroupCount(); |
---|
| 196 | addPI(pos, pi); |
---|
[138] | 197 | } |
---|
| 198 | |
---|
[792] | 199 | void MutableParamList::insert(int pos, ParamInterface *p) |
---|
[138] | 200 | { |
---|
[792] | 201 | ParamInfo *pi = new ParamInfo(); |
---|
| 202 | pi->pi = p; |
---|
| 203 | pi->mpi = 0; |
---|
| 204 | pi->propcount = p->getPropCount(); |
---|
| 205 | pi->groupcount = p->getGroupCount(); |
---|
| 206 | addPI(pos, pi); |
---|
[138] | 207 | } |
---|
| 208 | |
---|
| 209 | |
---|
| 210 | void MutableParamList::operator+=(ParamInterface *p) |
---|
| 211 | { |
---|
[792] | 212 | insert(list.size(), p); |
---|
[138] | 213 | } |
---|
| 214 | |
---|
| 215 | void MutableParamList::operator+=(MutableParamInterface *p) |
---|
| 216 | { |
---|
[792] | 217 | insert(list.size(), p); |
---|
[138] | 218 | } |
---|
| 219 | |
---|
| 220 | |
---|
| 221 | void MutableParamList::operator-=(ParamInterface *p) |
---|
| 222 | { |
---|
[792] | 223 | int i = findPI(p); |
---|
| 224 | removePI(i); |
---|
[138] | 225 | } |
---|
| 226 | |
---|
| 227 | void MutableParamList::operator-=(MutableParamInterface *p) |
---|
| 228 | { |
---|
[792] | 229 | int i = findPI(p); |
---|
| 230 | removePI(i); |
---|
[138] | 231 | } |
---|
| 232 | |
---|
| 233 | void MutableParamList::operator-=(int i) |
---|
| 234 | { |
---|
[792] | 235 | removePI(i); |
---|
[138] | 236 | } |
---|
| 237 | |
---|
| 238 | int MutableParamList::getGroupCount() |
---|
| 239 | { |
---|
[792] | 240 | int count = 0; |
---|
| 241 | FOREACH(ParamInfo*, pi, list) |
---|
| 242 | count += pi->groupcount; |
---|
| 243 | return count; |
---|
[138] | 244 | } |
---|
| 245 | |
---|
| 246 | int MutableParamList::getPropCount() |
---|
| 247 | { |
---|
[792] | 248 | int count = 0; |
---|
| 249 | FOREACH(ParamInfo*, pi, list) |
---|
| 250 | count += pi->propcount; |
---|
| 251 | return count; |
---|
[138] | 252 | } |
---|
| 253 | |
---|
[792] | 254 | int MutableParamList::getSubParam(int i, ParamInterface **sub_p, int *sub_i) |
---|
[138] | 255 | { |
---|
[792] | 256 | int n; |
---|
| 257 | FOREACH(ParamInfo*, pi, list) |
---|
[138] | 258 | { |
---|
[792] | 259 | if (i < (n = pi->propcount)) |
---|
[138] | 260 | { |
---|
[792] | 261 | *sub_p = pi->pi; |
---|
| 262 | *sub_i = i; |
---|
| 263 | return 1; |
---|
[138] | 264 | } |
---|
[792] | 265 | i -= n; |
---|
[138] | 266 | } |
---|
[792] | 267 | return 0; |
---|
[138] | 268 | } |
---|
| 269 | |
---|
[792] | 270 | int MutableParamList::getSubGroup(int i, ParamInterface **sub_p, int *sub_i) |
---|
[138] | 271 | { |
---|
[792] | 272 | int n; |
---|
| 273 | FOREACH(ParamInfo*, pi, list) |
---|
[138] | 274 | { |
---|
[792] | 275 | if (i < (n = pi->groupcount)) |
---|
[138] | 276 | { |
---|
[792] | 277 | *sub_p = pi->pi; |
---|
| 278 | *sub_i = i; |
---|
| 279 | return 1; |
---|
[138] | 280 | } |
---|
[792] | 281 | i -= n; |
---|
[138] | 282 | } |
---|
[792] | 283 | return 0; |
---|
[138] | 284 | } |
---|
| 285 | |
---|
| 286 | #define FUN(_type_,_name_,_ret_) \ |
---|
| 287 | _type_ MutableParamList:: _name_ (int i) \ |
---|
| 288 | { \ |
---|
| 289 | int j; ParamInterface *pi; \ |
---|
| 290 | if (!getSubParam(i,&pi,&j)) return _ret_; \ |
---|
| 291 | return pi-> _name_ (j); \ |
---|
| 292 | } |
---|
| 293 | |
---|
[792] | 294 | FUN(const char*, id, 0) |
---|
| 295 | FUN(const char*, name, 0) |
---|
| 296 | FUN(const char*, type, 0) |
---|
| 297 | FUN(const char*, help, 0) |
---|
| 298 | FUN(int, flags, 0) |
---|
| 299 | FUN(SString, getString, SString()) |
---|
| 300 | FUN(paInt, getInt, 0) |
---|
| 301 | FUN(double, getDouble, 0) |
---|
| 302 | FUN(ExtValue, getExtValue, ExtValue((paInt)0)) |
---|
| 303 | FUN(ExtObject, getObject, ExtObject()) |
---|
[138] | 304 | |
---|
| 305 | int MutableParamList::group(int i) |
---|
| 306 | { |
---|
[792] | 307 | int n; |
---|
| 308 | int g = 0; |
---|
| 309 | FOREACH(ParamInfo*, pi, list) |
---|
[138] | 310 | { |
---|
[792] | 311 | if (i < (n = pi->propcount)) |
---|
| 312 | return g + pi->pi->group(i); |
---|
| 313 | g += pi->groupcount; |
---|
| 314 | i -= n; |
---|
[138] | 315 | } |
---|
[792] | 316 | return 0; |
---|
[138] | 317 | } |
---|
| 318 | |
---|
| 319 | #define FUN2(_type_,_name_,_argt_) \ |
---|
| 320 | _type_ MutableParamList:: _name_ (int i,_argt_ v) \ |
---|
| 321 | { \ |
---|
| 322 | int j; ParamInterface *pi; \ |
---|
| 323 | if (!getSubParam(i,&pi,&j)) return 0; \ |
---|
| 324 | return pi-> _name_ (j,v); \ |
---|
| 325 | } |
---|
| 326 | |
---|
[792] | 327 | FUN2(int, setInt, paInt) |
---|
| 328 | FUN2(int, setDouble, double) |
---|
| 329 | FUN2(int, setString, const SString &) |
---|
| 330 | FUN2(int, setObject, const ExtObject &) |
---|
| 331 | FUN2(int, setExtValue, const ExtValue &) |
---|
[138] | 332 | |
---|
[792] | 333 | void MutableParamList::call(int i, ExtValue* args, ExtValue *ret) |
---|
[138] | 334 | { |
---|
[792] | 335 | int j; ParamInterface *pi; |
---|
| 336 | if (!getSubParam(i, &pi, &j)) return; |
---|
| 337 | pi->call(j, args, ret); |
---|
[138] | 338 | } |
---|
| 339 | |
---|
| 340 | const char *MutableParamList::grname(int i) |
---|
| 341 | { |
---|
[792] | 342 | int j; ParamInterface *pi; |
---|
| 343 | if (!getSubGroup(i, &pi, &j)) return 0; |
---|
| 344 | return pi->grname(j); |
---|
[138] | 345 | } |
---|
| 346 | |
---|
[792] | 347 | int MutableParamList::grmember(int gi, int i) |
---|
[138] | 348 | { |
---|
[792] | 349 | int n; |
---|
| 350 | int count = 0; |
---|
| 351 | FOREACH(ParamInfo*, pi, list) |
---|
[138] | 352 | { |
---|
[792] | 353 | if (gi < (n = pi->groupcount)) |
---|
[138] | 354 | { |
---|
[792] | 355 | int prop = pi->pi->grmember(gi, i); |
---|
| 356 | if (prop >= pi->propcount) return -9999; |
---|
| 357 | return count + prop; |
---|
[138] | 358 | } |
---|
[792] | 359 | count += pi->propcount; |
---|
| 360 | gi -= n; |
---|
[138] | 361 | } |
---|
[792] | 362 | return -9999; |
---|
[138] | 363 | } |
---|
| 364 | |
---|
| 365 | void MutableParamList::clear() |
---|
| 366 | { |
---|
[792] | 367 | for (int i = list.size() - 1; i >= 0; i--) |
---|
| 368 | operator-=(i); |
---|
[138] | 369 | } |
---|