Files
hot-step-cpp-ROCm/engine/vendor/vst3sdk/vstgui4/vstgui/uidescription-scripting/detail/scriptobject.h
T
2026-08-16 18:24:52 +07:00

219 lines
5.4 KiB
C++

// 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