scriptobji.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. #include "api.h"
  2. #include <api/script/scriptobji.h>
  3. #include <api/script/objcontroller.h>
  4. #include <api/script/scriptguid.h>
  5. ScriptObjectI::ScriptObjectI(const wchar_t *class_name, ScriptObjectController *object_controller)
  6. {
  7. classname = class_name;
  8. controller = object_controller;
  9. cache_count = -1;
  10. membercachegid = -1;
  11. membercachesid = -1;
  12. ingetinterface = 0;
  13. vcpu_init();
  14. }
  15. ScriptObjectI::~ScriptObjectI()
  16. {
  17. assignedVariables.deleteAll();
  18. memberVariables.deleteAll();
  19. interfaceslist.deleteAll();
  20. WASABI_API_MAKI->vcpu_removeScriptObject(this);
  21. }
  22. void *ScriptObjectI::vcpu_getInterface(GUID g, int *interfacetype)
  23. {
  24. if (g == scriptObjectGuid) return this;
  25. InterfaceEntry *entry = 0;
  26. int n=0;
  27. while (entry = interfaceslist.enumItem(n++))
  28. {
  29. if (entry->getGuid() == g)
  30. {
  31. if (interfacetype != NULL)
  32. *interfacetype = entry->getType();
  33. return entry->getInterface();
  34. }
  35. }
  36. if (ingetinterface) return NULL;
  37. ingetinterface = 1;
  38. void *i = NULL;
  39. ScriptObjectController *c = controller;
  40. //CUT: ScriptObject *no = NULL;
  41. while (i == NULL && c != NULL)
  42. {
  43. i = c->cast(this, g);
  44. if (i != NULL) break;
  45. c = c->getAncestorController();
  46. }
  47. if (interfacetype != NULL)
  48. *interfacetype = INTERFACE_SCRIPTOBJECT;
  49. ingetinterface = 0;
  50. return i;
  51. }
  52. void *ScriptObjectI::vcpu_getInterfaceObject(GUID g, ScriptObject **o)
  53. {
  54. if (g == scriptObjectGuid) return this;
  55. InterfaceEntry *entry = 0;
  56. int n=0;
  57. while (entry = interfaceslist.enumItem(n++))
  58. {
  59. if (entry && entry->getGuid() == g)
  60. {
  61. *o = NULL;
  62. return entry->getInterface();
  63. }
  64. }
  65. if (ingetinterface) return NULL;
  66. ingetinterface = 1;
  67. void *i = NULL;
  68. ScriptObjectController *c = controller;
  69. //CUT: ScriptObject *no = NULL;
  70. while (i == NULL && c != NULL)
  71. {
  72. i = c->cast(this, g);
  73. if (i != NULL)
  74. {
  75. if (o != NULL)
  76. *o = (ScriptObject *)i;
  77. break;
  78. }
  79. c = c->getAncestorController();
  80. }
  81. ingetinterface = 0;
  82. return i;
  83. }
  84. int ScriptObjectI::vcpu_getAssignedVariable(int start, int scriptid, int functionId, int *next, int *globalevententry, int *inheritedevent)
  85. {
  86. if (start < 0) start = 0;
  87. if (start >= assignedVariables.getNumItems()) return -1;
  88. for (int i = start;i < assignedVariables.getNumItems();i++)
  89. {
  90. assvar *v = assignedVariables.enumItem(i);
  91. if (WASABI_API_MAKI->vcpu_getCacheCount() != cache_count)
  92. {
  93. if (!WASABI_API_MAKI->vcpu_isValidScriptId(v->scriptid))
  94. {
  95. vcpu_removeAssignedVariable(v->varid, v->scriptid);
  96. i--;
  97. continue;
  98. }
  99. }
  100. if (scriptid == -1 || v->scriptid == scriptid)
  101. {
  102. int r = getEventForVar(v, functionId, inheritedevent);
  103. if (r == -1) continue;
  104. if (next) *next = i + 1;
  105. if (globalevententry) *globalevententry = r;
  106. return WASABI_API_MAKI->vcpu_mapVarId(v->varid, v->scriptid);
  107. }
  108. }
  109. return -1;
  110. }
  111. void ScriptObjectI::vcpu_removeAssignedVariable(int var, int id)
  112. {
  113. for (int i = 0;i < assignedVariables.getNumItems();i++)
  114. {
  115. assvar *v = assignedVariables.enumItem(i);
  116. if (v->varid == var && v->scriptid == id)
  117. {
  118. delete v;
  119. assignedVariables.removeItem(v);
  120. return ;
  121. }
  122. }
  123. }
  124. void ScriptObjectI::vcpu_addAssignedVariable(int var, int scriptid)
  125. {
  126. do
  127. {
  128. assvar *v = new assvar;
  129. v->scriptid = scriptid;
  130. v->varid = var;
  131. assignedVariables.addItem(v);
  132. computeEventList(v);
  133. var = WASABI_API_MAKI->vcpu_getUserAncestorId(var, scriptid);
  134. }
  135. while (var != -1);
  136. }
  137. const wchar_t *ScriptObjectI::vcpu_getClassName()
  138. {
  139. return classname;
  140. }
  141. ScriptObjectController *ScriptObjectI::vcpu_getController()
  142. {
  143. return controller;
  144. }
  145. int ScriptObjectI::vcpu_getScriptId()
  146. {
  147. return id;
  148. }
  149. void ScriptObjectI::vcpu_setScriptId(int i)
  150. {
  151. id = i;
  152. }
  153. int ScriptObjectI::vcpu_getMember(const wchar_t *id, int scriptid, int rettype)
  154. {
  155. if (membercachesid == scriptid && !WCSICMP(membercacheid, id))
  156. return membercachegid;
  157. membercacheid = id;
  158. membercachesid = scriptid;
  159. for (int i = 0;i < memberVariables.getNumItems();i++)
  160. {
  161. MemberVar *m = memberVariables.enumItem(i);
  162. if (m->getScriptId() == scriptid && !WCSICMP(m->getName(), id))
  163. {
  164. membercachegid = m->getGlobalId();
  165. return membercachegid;
  166. }
  167. }
  168. MemberVar *m = new MemberVar(id, scriptid, rettype);
  169. memberVariables.addItem(m);
  170. membercachegid = m->getGlobalId();
  171. return membercachegid;
  172. }
  173. void ScriptObjectI::vcpu_delMembers(int scriptid)
  174. {
  175. for (int i = 0;i < memberVariables.getNumItems();i++)
  176. if (memberVariables.enumItem(i)->getScriptId() == scriptid)
  177. {
  178. delete memberVariables.enumItem(i);
  179. memberVariables.removeByPos(i--);
  180. }
  181. }
  182. void ScriptObjectI::vcpu_setInterface(GUID g, void *v, int interfacetype)
  183. {
  184. for (int i = 0;i < interfaceslist.getNumItems();i++)
  185. if (interfaceslist.enumItem(i)->getGuid() == g)
  186. {
  187. InterfaceEntry *p = interfaceslist.enumItem(i);
  188. delete p;
  189. interfaceslist.removeByPos(i);
  190. i--;
  191. }
  192. interfaceslist.addItem(new InterfaceEntry(g, v, interfacetype));
  193. }
  194. void ScriptObjectI::vcpu_setClassName(const wchar_t *name)
  195. {
  196. classname = name;
  197. }
  198. void ScriptObjectI::vcpu_setController(ScriptObjectController *c)
  199. {
  200. controller = c;
  201. }
  202. void ScriptObjectI::vcpu_init()
  203. {
  204. WASABI_API_MAKI->vcpu_addScriptObject(this);
  205. }
  206. int ScriptObjectI::getEventForVar(assvar *var, int funcid, int *inheritedevent)
  207. {
  208. if (WASABI_API_MAKI->vcpu_getCacheCount() != cache_count)
  209. {
  210. for (int i = 0;i < assignedVariables.getNumItems();i++)
  211. {
  212. assvar* ass = assignedVariables.enumItem(i);
  213. // Martin> We need to ensure here that a valid script is called
  214. // There are a few circumstances where the script is already deleted from SOM but we want to call it.
  215. // Example: onMouseWheelDown() in a script embedded in a customobject and another script.
  216. // another script can hide the customobject and thus the custom object's embedded script gets unloaded.
  217. // the old scriptID is still cached and wants to be invoked! this will lead to an guru but the guru cannot be thrown
  218. // since the ScriptID isn't valid anymore. this leads to a nullpointer assert crash.
  219. if (!WASABI_API_MAKI->vcpu_isValidScriptId(ass->scriptid))
  220. {
  221. continue;
  222. }
  223. computeEventList(ass);
  224. }
  225. cache_count = WASABI_API_MAKI->vcpu_getCacheCount();
  226. }
  227. TList<int> *list = &var->dlfs;
  228. for (int i = 0;i < list->getNumItems();i += 4)
  229. if (list->enumItem(i) == funcid && list->enumItem(i + 1) == var->varid)
  230. {
  231. *inheritedevent = list->enumItem(i + 3);
  232. return list->enumItem(i + 2);
  233. }
  234. return -1;
  235. }
  236. void ScriptObjectI::computeEventList(assvar *a)
  237. {
  238. a->dlfs.removeAll();
  239. int dlfid;
  240. int scriptid;
  241. int varid;
  242. int var = a->varid;
  243. int inheritedevent = 0;
  244. do
  245. {
  246. for (int i = 0;i < WASABI_API_MAKI->vcpu_getNumEvents();i++)
  247. {
  248. WASABI_API_MAKI->vcpu_getEvent(i, &dlfid, &scriptid, &varid);
  249. if (scriptid == a->scriptid && varid == var)
  250. {
  251. a->dlfs.addItem(dlfid);
  252. a->dlfs.addItem(varid);
  253. a->dlfs.addItem(i);
  254. a->dlfs.addItem(inheritedevent);
  255. }
  256. }
  257. var = WASABI_API_MAKI->vcpu_getUserAncestorId(var, a->scriptid);
  258. inheritedevent = 1;
  259. }
  260. while (var != -1);
  261. }
  262. ScriptObjectI::MemberVar::MemberVar(const wchar_t *_name, int _scriptid, int _rettype)
  263. {
  264. name = _name;
  265. rettype = _rettype;
  266. scriptid = _scriptid;
  267. globalid = WASABI_API_MAKI->maki_createOrphan(rettype);
  268. }
  269. ScriptObjectI::MemberVar::~MemberVar()
  270. {
  271. WASABI_API_MAKI->maki_killOrphan(globalid); // heh :)
  272. }