aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/script/scriptobji.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/script/scriptobji.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Wasabi/api/script/scriptobji.cpp')
-rw-r--r--Src/Wasabi/api/script/scriptobji.cpp305
1 files changed, 305 insertions, 0 deletions
diff --git a/Src/Wasabi/api/script/scriptobji.cpp b/Src/Wasabi/api/script/scriptobji.cpp
new file mode 100644
index 00000000..f9cbef46
--- /dev/null
+++ b/Src/Wasabi/api/script/scriptobji.cpp
@@ -0,0 +1,305 @@
+#include "api.h"
+#include <api/script/scriptobji.h>
+#include <api/script/objcontroller.h>
+#include <api/script/scriptguid.h>
+
+ScriptObjectI::ScriptObjectI(const wchar_t *class_name, ScriptObjectController *object_controller)
+{
+ classname = class_name;
+ controller = object_controller;
+ cache_count = -1;
+ membercachegid = -1;
+ membercachesid = -1;
+ ingetinterface = 0;
+ vcpu_init();
+}
+
+ScriptObjectI::~ScriptObjectI()
+{
+ assignedVariables.deleteAll();
+ memberVariables.deleteAll();
+ interfaceslist.deleteAll();
+ WASABI_API_MAKI->vcpu_removeScriptObject(this);
+}
+
+void *ScriptObjectI::vcpu_getInterface(GUID g, int *interfacetype)
+{
+ if (g == scriptObjectGuid) return this;
+ InterfaceEntry *entry = 0;
+ int n=0;
+ while (entry = interfaceslist.enumItem(n++))
+ {
+ if (entry->getGuid() == g)
+ {
+ if (interfacetype != NULL)
+ *interfacetype = entry->getType();
+ return entry->getInterface();
+ }
+ }
+
+ if (ingetinterface) return NULL;
+ ingetinterface = 1;
+
+ void *i = NULL;
+ ScriptObjectController *c = controller;
+ //CUT: ScriptObject *no = NULL;
+ while (i == NULL && c != NULL)
+ {
+ i = c->cast(this, g);
+ if (i != NULL) break;
+ c = c->getAncestorController();
+ }
+
+ if (interfacetype != NULL)
+ *interfacetype = INTERFACE_SCRIPTOBJECT;
+ ingetinterface = 0;
+ return i;
+}
+
+void *ScriptObjectI::vcpu_getInterfaceObject(GUID g, ScriptObject **o)
+{
+ if (g == scriptObjectGuid) return this;
+ InterfaceEntry *entry = 0;
+ int n=0;
+ while (entry = interfaceslist.enumItem(n++))
+ {
+ if (entry && entry->getGuid() == g)
+ {
+ *o = NULL;
+ return entry->getInterface();
+ }
+ }
+ if (ingetinterface) return NULL;
+ ingetinterface = 1;
+
+ void *i = NULL;
+ ScriptObjectController *c = controller;
+ //CUT: ScriptObject *no = NULL;
+ while (i == NULL && c != NULL)
+ {
+ i = c->cast(this, g);
+ if (i != NULL)
+ {
+ if (o != NULL)
+ *o = (ScriptObject *)i;
+ break;
+ }
+ c = c->getAncestorController();
+ }
+
+ ingetinterface = 0;
+ return i;
+}
+
+int ScriptObjectI::vcpu_getAssignedVariable(int start, int scriptid, int functionId, int *next, int *globalevententry, int *inheritedevent)
+{
+ if (start < 0) start = 0;
+ if (start >= assignedVariables.getNumItems()) return -1;
+ for (int i = start;i < assignedVariables.getNumItems();i++)
+ {
+ assvar *v = assignedVariables.enumItem(i);
+ if (WASABI_API_MAKI->vcpu_getCacheCount() != cache_count)
+ {
+ if (!WASABI_API_MAKI->vcpu_isValidScriptId(v->scriptid))
+ {
+ vcpu_removeAssignedVariable(v->varid, v->scriptid);
+ i--;
+ continue;
+ }
+ }
+ if (scriptid == -1 || v->scriptid == scriptid)
+ {
+ int r = getEventForVar(v, functionId, inheritedevent);
+ if (r == -1) continue;
+ if (next) *next = i + 1;
+ if (globalevententry) *globalevententry = r;
+ return WASABI_API_MAKI->vcpu_mapVarId(v->varid, v->scriptid);
+ }
+ }
+ return -1;
+}
+
+void ScriptObjectI::vcpu_removeAssignedVariable(int var, int id)
+{
+ for (int i = 0;i < assignedVariables.getNumItems();i++)
+ {
+ assvar *v = assignedVariables.enumItem(i);
+ if (v->varid == var && v->scriptid == id)
+ {
+ delete v;
+ assignedVariables.removeItem(v);
+ return ;
+ }
+ }
+}
+
+void ScriptObjectI::vcpu_addAssignedVariable(int var, int scriptid)
+{
+ do
+ {
+ assvar *v = new assvar;
+ v->scriptid = scriptid;
+ v->varid = var;
+ assignedVariables.addItem(v);
+ computeEventList(v);
+ var = WASABI_API_MAKI->vcpu_getUserAncestorId(var, scriptid);
+ }
+ while (var != -1);
+}
+
+const wchar_t *ScriptObjectI::vcpu_getClassName()
+{
+ return classname;
+}
+
+ScriptObjectController *ScriptObjectI::vcpu_getController()
+{
+ return controller;
+}
+
+int ScriptObjectI::vcpu_getScriptId()
+{
+ return id;
+}
+
+void ScriptObjectI::vcpu_setScriptId(int i)
+{
+ id = i;
+}
+
+int ScriptObjectI::vcpu_getMember(const wchar_t *id, int scriptid, int rettype)
+{
+ if (membercachesid == scriptid && !WCSICMP(membercacheid, id))
+ return membercachegid;
+ membercacheid = id;
+ membercachesid = scriptid;
+ for (int i = 0;i < memberVariables.getNumItems();i++)
+ {
+ MemberVar *m = memberVariables.enumItem(i);
+ if (m->getScriptId() == scriptid && !WCSICMP(m->getName(), id))
+ {
+ membercachegid = m->getGlobalId();
+ return membercachegid;
+ }
+ }
+ MemberVar *m = new MemberVar(id, scriptid, rettype);
+ memberVariables.addItem(m);
+ membercachegid = m->getGlobalId();
+ return membercachegid;
+}
+
+void ScriptObjectI::vcpu_delMembers(int scriptid)
+{
+ for (int i = 0;i < memberVariables.getNumItems();i++)
+ if (memberVariables.enumItem(i)->getScriptId() == scriptid)
+ {
+ delete memberVariables.enumItem(i);
+ memberVariables.removeByPos(i--);
+ }
+}
+
+void ScriptObjectI::vcpu_setInterface(GUID g, void *v, int interfacetype)
+{
+ for (int i = 0;i < interfaceslist.getNumItems();i++)
+ if (interfaceslist.enumItem(i)->getGuid() == g)
+ {
+ InterfaceEntry *p = interfaceslist.enumItem(i);
+ delete p;
+ interfaceslist.removeByPos(i);
+ i--;
+ }
+ interfaceslist.addItem(new InterfaceEntry(g, v, interfacetype));
+}
+
+void ScriptObjectI::vcpu_setClassName(const wchar_t *name)
+{
+ classname = name;
+}
+
+void ScriptObjectI::vcpu_setController(ScriptObjectController *c)
+{
+ controller = c;
+}
+
+void ScriptObjectI::vcpu_init()
+{
+ WASABI_API_MAKI->vcpu_addScriptObject(this);
+}
+
+int ScriptObjectI::getEventForVar(assvar *var, int funcid, int *inheritedevent)
+{
+ if (WASABI_API_MAKI->vcpu_getCacheCount() != cache_count)
+ {
+ for (int i = 0;i < assignedVariables.getNumItems();i++)
+ {
+ assvar* ass = assignedVariables.enumItem(i);
+ // Martin> We need to ensure here that a valid script is called
+ // There are a few circumstances where the script is already deleted from SOM but we want to call it.
+ // Example: onMouseWheelDown() in a script embedded in a customobject and another script.
+ // another script can hide the customobject and thus the custom object's embedded script gets unloaded.
+ // the old scriptID is still cached and wants to be invoked! this will lead to an guru but the guru cannot be thrown
+ // since the ScriptID isn't valid anymore. this leads to a nullpointer assert crash.
+ if (!WASABI_API_MAKI->vcpu_isValidScriptId(ass->scriptid))
+ {
+ continue;
+ }
+ computeEventList(ass);
+ }
+ cache_count = WASABI_API_MAKI->vcpu_getCacheCount();
+ }
+ TList<int> *list = &var->dlfs;
+ for (int i = 0;i < list->getNumItems();i += 4)
+ if (list->enumItem(i) == funcid && list->enumItem(i + 1) == var->varid)
+ {
+ *inheritedevent = list->enumItem(i + 3);
+ return list->enumItem(i + 2);
+ }
+
+ return -1;
+}
+
+void ScriptObjectI::computeEventList(assvar *a)
+{
+ a->dlfs.removeAll();
+
+ int dlfid;
+ int scriptid;
+ int varid;
+
+ int var = a->varid;
+ int inheritedevent = 0;
+
+ do
+ {
+ for (int i = 0;i < WASABI_API_MAKI->vcpu_getNumEvents();i++)
+ {
+ WASABI_API_MAKI->vcpu_getEvent(i, &dlfid, &scriptid, &varid);
+ if (scriptid == a->scriptid && varid == var)
+ {
+ a->dlfs.addItem(dlfid);
+ a->dlfs.addItem(varid);
+ a->dlfs.addItem(i);
+ a->dlfs.addItem(inheritedevent);
+ }
+ }
+ var = WASABI_API_MAKI->vcpu_getUserAncestorId(var, a->scriptid);
+ inheritedevent = 1;
+ }
+ while (var != -1);
+}
+
+
+
+ScriptObjectI::MemberVar::MemberVar(const wchar_t *_name, int _scriptid, int _rettype)
+{
+ name = _name;
+ rettype = _rettype;
+ scriptid = _scriptid;
+ globalid = WASABI_API_MAKI->maki_createOrphan(rettype);
+}
+
+ScriptObjectI::MemberVar::~MemberVar()
+{
+ WASABI_API_MAKI->maki_killOrphan(globalid); // heh :)
+}
+