Initial release
This commit is contained in:
+218
@@ -0,0 +1,218 @@
|
||||
// This file is part of VSTGUI. It is subject to the license terms
|
||||
// in the LICENSE file found in the top-level directory of this
|
||||
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../tiny-js/TinyJS.h"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
namespace VSTGUI {
|
||||
namespace ScriptingInternal {
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct ScriptAddChildScoped
|
||||
{
|
||||
using CScriptVar = TJS::CScriptVar;
|
||||
using CScriptVarLink = TJS::CScriptVarLink;
|
||||
|
||||
ScriptAddChildScoped (CScriptVar& var, std::string_view name, CScriptVar* obj) : var (var)
|
||||
{
|
||||
if ((link = var.findChild (name)))
|
||||
{
|
||||
oldVar = TJS::owning (link->getVar ());
|
||||
link->setVar (obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
link = var.addChild (name, obj);
|
||||
}
|
||||
}
|
||||
~ScriptAddChildScoped () noexcept
|
||||
{
|
||||
if (oldVar && link)
|
||||
{
|
||||
link->setVar (oldVar);
|
||||
oldVar->release ();
|
||||
}
|
||||
else if (link)
|
||||
{
|
||||
var.removeLink (link);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CScriptVar& var;
|
||||
CScriptVarLink* link {nullptr};
|
||||
CScriptVar* oldVar {nullptr};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline TJS::CScriptVar* createJSFunction (TJS::JSCallback&& proc)
|
||||
{
|
||||
auto funcVar = new TJS::CScriptVar (TJS::TINYJS_BLANK_DATA,
|
||||
TJS::SCRIPTVAR_FUNCTION | TJS::SCRIPTVAR_NATIVE);
|
||||
funcVar->setCallback (std::move (proc));
|
||||
return funcVar;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline TJS::CScriptVar* createJSFunction (TJS::JSCallback&& proc,
|
||||
const std::initializer_list<std::string_view>& argNames)
|
||||
{
|
||||
auto f = createJSFunction (std::move (proc));
|
||||
for (auto name : argNames)
|
||||
f->addChildNoDup (name);
|
||||
return f;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline TJS::CScriptVar* getArgument (TJS::CScriptVar* var, std::string_view argName,
|
||||
std::string_view funcSignature)
|
||||
{
|
||||
auto child = var->findChild (argName);
|
||||
auto result = child ? child->getVar () : nullptr;
|
||||
if (!result || result->isUndefined ())
|
||||
{
|
||||
TJS::string s ("Missing `");
|
||||
s.append (argName);
|
||||
s.append ("` argument in ");
|
||||
s.append (funcSignature);
|
||||
throw TJS::CScriptException (std::move (s));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
inline TJS::CScriptVar* getOptionalArgument (TJS::CScriptVar* var, std::string_view argName)
|
||||
{
|
||||
if (auto child = var->findChild (argName))
|
||||
return child->getVar ();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct ScriptObject
|
||||
{
|
||||
using CScriptVar = TJS::CScriptVar;
|
||||
|
||||
ScriptObject () { scriptVar = TJS::owning (new CScriptVar ()); }
|
||||
ScriptObject (CScriptVar* var) : scriptVar (TJS::owning (var)) {}
|
||||
ScriptObject (ScriptObject&& o) { *this = std::move (o); }
|
||||
ScriptObject& operator= (ScriptObject&& o)
|
||||
{
|
||||
if (scriptVar)
|
||||
scriptVar->release ();
|
||||
scriptVar = nullptr;
|
||||
std::swap (scriptVar, o.scriptVar);
|
||||
return *this;
|
||||
}
|
||||
virtual ~ScriptObject () noexcept
|
||||
{
|
||||
if (scriptVar)
|
||||
{
|
||||
scriptVar->release ();
|
||||
}
|
||||
}
|
||||
|
||||
operator CScriptVar* () const
|
||||
{
|
||||
validate ();
|
||||
return scriptVar;
|
||||
}
|
||||
CScriptVar* operator->() const
|
||||
{
|
||||
validate ();
|
||||
return scriptVar;
|
||||
}
|
||||
|
||||
CScriptVar* getVar () const
|
||||
{
|
||||
validate ();
|
||||
return scriptVar;
|
||||
}
|
||||
CScriptVar* take ()
|
||||
{
|
||||
auto v = scriptVar;
|
||||
scriptVar = nullptr;
|
||||
return v;
|
||||
}
|
||||
void addChild (std::string_view name, ScriptObject&& obj)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->addChild (name, obj);
|
||||
}
|
||||
void addChild (std::string_view name, double d)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->addChild (name, new CScriptVar (d));
|
||||
}
|
||||
void addChild (std::string_view name, int64_t i)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->addChild (name, new CScriptVar (i));
|
||||
}
|
||||
void addChild (std::string_view name, int32_t i)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->addChild (name, new CScriptVar (static_cast<int64_t> (i)));
|
||||
}
|
||||
void addChild (std::string_view name, std::string_view value)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->addChild (name, new CScriptVar (TJS::string {value.data (), value.size ()}));
|
||||
}
|
||||
void addFunc (std::string_view name, std::function<void (CScriptVar*)>&& func)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->addChild (name, createJSFunction (std::move (func)));
|
||||
}
|
||||
void addFunc (std::string_view name, std::function<void (CScriptVar*)>&& func,
|
||||
const std::initializer_list<std::string_view>& argNames)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->addChild (name, createJSFunction (std::move (func), argNames));
|
||||
}
|
||||
void addFunc (std::string_view name, std::string_view code)
|
||||
{
|
||||
validate ();
|
||||
auto funcVar = new TJS::CScriptVar (TJS::TINYJS_BLANK_DATA, TJS::SCRIPTVAR_FUNCTION);
|
||||
funcVar->setFunctionScript (code);
|
||||
scriptVar->addChild (name, funcVar);
|
||||
}
|
||||
|
||||
using OnDestroyFunc = std::function<void (CScriptVar*)>;
|
||||
void setOnDestroy (OnDestroyFunc&& f)
|
||||
{
|
||||
validate ();
|
||||
scriptVar->setLifeTimeObserver (OnDestroy::make (std::move (f)));
|
||||
}
|
||||
|
||||
protected:
|
||||
struct OnDestroy : TJS::IScriptVarLifeTimeObserver
|
||||
{
|
||||
static OnDestroy* make (OnDestroyFunc f) { return new OnDestroy (std::move (f)); }
|
||||
|
||||
private:
|
||||
OnDestroy (OnDestroyFunc f) : func (std::move (f)) {}
|
||||
|
||||
void onDestroy (CScriptVar* var)
|
||||
{
|
||||
func (var);
|
||||
delete this;
|
||||
}
|
||||
OnDestroyFunc func;
|
||||
};
|
||||
|
||||
void validate () const
|
||||
{
|
||||
if (scriptVar == nullptr)
|
||||
scriptVar = TJS::owning (new CScriptVar ());
|
||||
}
|
||||
|
||||
mutable CScriptVar* scriptVar {nullptr};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
} // ScriptingInternal
|
||||
} // VSTGUI
|
||||
Reference in New Issue
Block a user