mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-08-17 17:31:44 +08:00
2397 lines
91 KiB
C++
2397 lines
91 KiB
C++
/***********************************************************************
|
|
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
|
|
DEVELOPER: Zihan Chen(vczh)
|
|
***********************************************************************/
|
|
#include "VlppGlrParser.h"
|
|
#include "VlppReflection.h"
|
|
#include "VlppOS.h"
|
|
#include "Vlpp.h"
|
|
#include "VlppRegex.h"
|
|
|
|
/***********************************************************************
|
|
.\WFLIBRARYPREDEFINED.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::Reflection
|
|
|
|
Interfaces:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_PREDEFINED
|
|
#define VCZH_WORKFLOW_LIBRARY_PREDEFINED
|
|
|
|
#include <math.h>
|
|
|
|
namespace vl
|
|
{
|
|
namespace reflection
|
|
{
|
|
namespace description
|
|
{
|
|
|
|
/***********************************************************************
|
|
Coroutine
|
|
***********************************************************************/
|
|
|
|
/// <summary>Status of a coroutine.</summary>
|
|
enum class CoroutineStatus
|
|
{
|
|
/// <summary>The coroutine is waiting for resuming.</summary>
|
|
Waiting,
|
|
/// <summary>The coroutine is being executed.</summary>
|
|
Executing,
|
|
/// <summary>The coroutine has stopped.</summary>
|
|
Stopped,
|
|
};
|
|
|
|
/// <summary>An object providing input information when resuming a coroutine.</summary>
|
|
class CoroutineResult : public virtual IDescriptable, public Description<CoroutineResult>
|
|
{
|
|
protected:
|
|
Value result;
|
|
Ptr<IValueException> failure;
|
|
|
|
public:
|
|
/// <summary>Get the object provided to the coroutine. This object is the return value for the pending async operation, like $Await.</summary>
|
|
/// <returns>The object provided to the coroutine.</returns>
|
|
Value GetResult();
|
|
|
|
/// <summary>Set the object provided to the coroutine.</summary>
|
|
/// <param name="value">The object provided to the coroutine.</summary>
|
|
void SetResult(const Value& value);
|
|
|
|
/// <summary>Get the error provided to the coroutine. When it is not nullptr, the return value of <see cref="GetResult"/> is ignored.</summary>
|
|
/// <returns>The error provided to the coroutine.</returns>
|
|
Ptr<IValueException> GetFailure();
|
|
|
|
/// <summary>Set the error provided to the coroutine.</summary>
|
|
/// <param name="value">The error provided to the coroutine.</summary>
|
|
void SetFailure(Ptr<IValueException> value);
|
|
};
|
|
|
|
/// <summary>A coroutine. This is typically created by a Workflow script.</summary>
|
|
class ICoroutine : public virtual IDescriptable, public Description<ICoroutine>
|
|
{
|
|
public:
|
|
/// <summary>Resume the coroutine.</summary>
|
|
/// <param name="raiseException">Set to true to raise an exception that the coroutine encountered. The same exception is accessible by <see cref="GetFailure"/>.</param>
|
|
/// <param name="output">Input for the coroutine in this resuming.</param>
|
|
virtual void Resume(bool raiseException, Ptr<CoroutineResult> output) = 0;
|
|
|
|
/// <summary>Returns the current exception.</summary>
|
|
/// <returns>The current exception. It could cause by the Workflow script that creates this coroutine, or by calling <see cref="Resume"/> when this coroutine is in an inappropriate state.</returns>
|
|
virtual Ptr<IValueException> GetFailure() = 0;
|
|
|
|
/// <summary>Returns the status of the coroutine.</summary>
|
|
/// <returns>The status of the coroutine. <see cref="Resume"/> can be called only when this function returns <see cref="CoroutineStatus::Waiting"/>.</returns>
|
|
virtual CoroutineStatus GetStatus() = 0;
|
|
};
|
|
|
|
/***********************************************************************
|
|
Coroutine (Enumerable)
|
|
***********************************************************************/
|
|
|
|
class EnumerableCoroutine : public Object, public Description<EnumerableCoroutine>
|
|
{
|
|
public:
|
|
class IImpl : public virtual IValueEnumerator, public Description<IImpl>
|
|
{
|
|
public:
|
|
virtual void OnYield(const Value& value) = 0;
|
|
virtual void OnJoin(Ptr<IValueEnumerable> value) = 0;
|
|
};
|
|
|
|
typedef Func<Ptr<ICoroutine>(IImpl*)> Creator;
|
|
|
|
static void YieldAndPause(IImpl* impl, const Value& value);
|
|
static void JoinAndPause(IImpl* impl, Ptr<IValueEnumerable> value);
|
|
static void ReturnAndExit(IImpl* impl);
|
|
static Ptr<IValueEnumerable> Create(const Creator& creator);
|
|
};
|
|
|
|
/***********************************************************************
|
|
Coroutine (Async)
|
|
***********************************************************************/
|
|
|
|
/// <summary>Status of am async operation.</summary>
|
|
enum class AsyncStatus
|
|
{
|
|
/// <summary>The async operation is ready to execute.</summary>
|
|
Ready,
|
|
/// <summary>The async operation is being executed.</summary>
|
|
Executing,
|
|
/// <summary>The async operation has stopped.</summary>
|
|
Stopped,
|
|
};
|
|
|
|
/// <summary>A context providing communication between the caller and the async operation.</summary>
|
|
class AsyncContext : public virtual IDescriptable, public Description<AsyncContext>
|
|
{
|
|
protected:
|
|
SpinLock lock;
|
|
bool cancelled = false;
|
|
Value context;
|
|
|
|
public:
|
|
/// <summary>Create a context.</summary>
|
|
/// <param name="_context">Set the initial return value for <see cref="GetContext"/> (optional)..</param>
|
|
AsyncContext(const Value& _context = {});
|
|
~AsyncContext();
|
|
|
|
/// <summary>Test if the current async operation is expected to cancel.</summary>
|
|
/// <returns>Returns true if the current async operation is expected to cancel.</returns>
|
|
/// <remarks>
|
|
/// This function is accessible by "$.IsCancelled" in an $Async coroutine.
|
|
/// A cancelable async operation should check this value when it is able to stop properly, and stop when it is true.
|
|
/// </remarks>
|
|
bool IsCancelled();
|
|
|
|
/// <summary>Set <see cref="IsCancelled"/> to true.</summary>
|
|
/// <returns>Returns true when this operation succeeded.</returns>
|
|
bool Cancel();
|
|
|
|
/// <summary>Returns a value that is accessible in Workflow script by "$.Context" in an $Async coroutine.</summary>
|
|
/// <returns>A value that is accessible in Workflow script by "$.Context" in an $Async coroutine.</returns>
|
|
const description::Value& GetContext();
|
|
|
|
/// <summary>Set a value that is accessible F</summary>
|
|
/// <param name="value">A value that is accessible in Workflow script by "$.Context" in an $Async coroutine.</param>
|
|
void SetContext(const description::Value& value);
|
|
};
|
|
|
|
/// <summary>An async operation.</summary>
|
|
class IAsync : public virtual IDescriptable, public Description<IAsync>
|
|
{
|
|
public:
|
|
/// <summary>Get the status of this async operation.</summary>
|
|
/// <returns>The status of this async operation.</returns>
|
|
virtual AsyncStatus GetStatus() = 0;
|
|
|
|
/// <summary>Run this async operation.</summary>
|
|
/// <returns>Returns true when this operation succeeded. This function cannot be called twice on the same object.</returns>
|
|
/// <param name="callback">A callback to execute when the async operation finished.</param>
|
|
/// <param name="context">A context object that is accessible in Workflow script by "$" in an $Async coroutine (optional).</param>
|
|
virtual bool Execute(const Func<void(Ptr<CoroutineResult>)>& callback, Ptr<AsyncContext> context = nullptr) = 0;
|
|
|
|
/// <summary>Create an async operation that finished after a specified moment of time.</summary>
|
|
/// <returns>Returns the created async operation.</returns>
|
|
/// <param name="milliseconds">The time in milliseconds to wait. It counts from when this function is called, not from when this async operation is executed.</param>
|
|
static Ptr<IAsync> Delay(vint milliseconds);
|
|
};
|
|
|
|
/// <summary>A promise object that controls a <see cref="IFuture"/> object.</summary>
|
|
class IPromise : public virtual IDescriptable, public Description<IPromise>
|
|
{
|
|
public:
|
|
/// <summary>Mark the <see cref="IFuture"/> object as finished by providing a value.</summary>
|
|
/// <returns>Returns true when this operation succeeded. Multiple calls to <see cref="SendResult"/> and <see cref="SendFailure"/> cause a failure.</returns>
|
|
/// <param name="result">The result of the <see cref="IFuture"/> object.</param>
|
|
virtual bool SendResult(const Value& result) = 0;
|
|
|
|
/// <summary>Mark the <see cref="IFuture"/> object as finished by providing an exception.</summary>
|
|
/// <returns>Returns true when this operation succeeded. Multiple calls to <see cref="SendResult"/> and <see cref="SendFailure"/> cause a failure.</returns>
|
|
/// <param name="failure">The exception of the <see cref="IFuture"/> object.</param>
|
|
virtual bool SendFailure(Ptr<IValueException> failure) = 0;
|
|
};
|
|
|
|
/// <summary>An async operation in the future-promise pattern.</summary>
|
|
class IFuture : public virtual IAsync, public Description<IFuture>
|
|
{
|
|
public:
|
|
/// <summary>Get the <see cref="IPromise"/> that controls this future object.</summary>
|
|
/// <returns>The <see cref="IPromise"/> that controls this future object.</returns>
|
|
virtual Ptr<IPromise> GetPromise() = 0;
|
|
|
|
/// <summary>Create a future object.</summary>
|
|
/// <returns>The created future object.</returns>
|
|
static Ptr<IFuture> Create();
|
|
};
|
|
|
|
/// <summary>A scheduler that controls how async operations are executed. It needs to be implemented and attached to threads that run async operations.</summary>
|
|
/// <remarks>See <a href="/workflow/lang/coroutine_async.html">Async Coroutine</a> for more information.</remarks>
|
|
class IAsyncScheduler : public virtual IDescriptable, public Description<IAsyncScheduler>
|
|
{
|
|
public:
|
|
/// <summary>Called when a callback needs to be executed in any thread.</summary>
|
|
/// <param name="callback">The callback to execute.</param>
|
|
/// <remarks>
|
|
/// You can decide which thread to execute.
|
|
/// For GacUI, the scheduler that attached to the UI thread will execute this callback in the UI thread.
|
|
/// </remarks>
|
|
virtual void Execute(const Func<void()>& callback) = 0;
|
|
|
|
/// <summary>Called when a callback needs to be executed in another thread.</summary>
|
|
/// <param name="callback">The callback to execute.</param>
|
|
/// <remarks>
|
|
/// You can decide which thread to execute except the current one.
|
|
/// For GacUI, the scheduler that attached to any thread will execute this callback in a random background thread.
|
|
/// </remarks>
|
|
virtual void ExecuteInBackground(const Func<void()>& callback) = 0;
|
|
|
|
/// <summary>Called when a callback needs to be executed in any thread after a specified moment of time.</summary>
|
|
/// <param name="callback">The callback to execute.</param>
|
|
/// <param name="milliseconds">The time in milliseconds to wait.</param>
|
|
/// <remarks>
|
|
/// You can decide which thread to execute.
|
|
/// For GacUI, the scheduler that attached to the UI thread will execute this callback in the UI thread.
|
|
/// </remarks>
|
|
virtual void DelayExecute(const Func<void()>& callback, vint milliseconds) = 0;
|
|
|
|
/// <summary>Attach a scheduler for all threads.</summary>
|
|
/// <param name="scheduler">The scheduler to attach.</param>
|
|
static void RegisterDefaultScheduler(Ptr<IAsyncScheduler> scheduler);
|
|
|
|
/// <summary>Attach a scheduler for the current thread.</summary>
|
|
/// <param name="scheduler">The scheduler to attach.</param>
|
|
static void RegisterSchedulerForCurrentThread(Ptr<IAsyncScheduler> scheduler);
|
|
|
|
/// <summary>Detach the scheduler for all threads.</summary>
|
|
/// <returns>The previously attached scheduler.</returns>
|
|
static Ptr<IAsyncScheduler> UnregisterDefaultScheduler();
|
|
|
|
/// <summary>Detach the scheduler for the current thread.</summary>
|
|
/// <returns>The previously attached scheduler.</returns>
|
|
static Ptr<IAsyncScheduler> UnregisterSchedulerForCurrentThread();
|
|
|
|
/// <summary>Get the attached scheduler for the current thread.</summary>
|
|
/// <returns>The attached scheduler. If there is no scheduler that is attached to this particular thread, the default scheduler kicks in.</returns>
|
|
static Ptr<IAsyncScheduler> GetSchedulerForCurrentThread();
|
|
};
|
|
|
|
class AsyncCoroutine : public Object, public Description<AsyncCoroutine>
|
|
{
|
|
public:
|
|
class IImpl : public virtual IAsync, public Description<IImpl>
|
|
{
|
|
public:
|
|
virtual Ptr<IAsyncScheduler> GetScheduler() = 0;
|
|
virtual Ptr<AsyncContext> GetContext() = 0;
|
|
virtual void OnContinue(Ptr<CoroutineResult> output) = 0;
|
|
virtual void OnReturn(const Value& value) = 0;
|
|
};
|
|
|
|
typedef Func<Ptr<ICoroutine>(IImpl*)> Creator;
|
|
|
|
static void AwaitAndRead(IImpl* impl, Ptr<IAsync> value);
|
|
static void ReturnAndExit(IImpl* impl, const Value& value);
|
|
static Ptr<AsyncContext> QueryContext(IImpl* impl);
|
|
static Ptr<IAsync> Create(const Creator& creator);
|
|
static void CreateAndRun(const Creator& creator);
|
|
};
|
|
|
|
/***********************************************************************
|
|
Coroutine (State Machine)
|
|
***********************************************************************/
|
|
|
|
class StateMachine : public Object, public AggregatableDescription<StateMachine>
|
|
{
|
|
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
|
|
friend struct CustomTypeDescriptorSelector<StateMachine>;
|
|
#endif
|
|
protected:
|
|
bool stateMachineInitialized = false;
|
|
bool stateMachineStopped = false;
|
|
vint stateMachineInput = -1;
|
|
Ptr<ICoroutine> stateMachineCoroutine;
|
|
|
|
void ResumeStateMachine();
|
|
public:
|
|
StateMachine();
|
|
~StateMachine();
|
|
|
|
CoroutineStatus GetStateMachineStatus();
|
|
};
|
|
|
|
/***********************************************************************
|
|
Libraries
|
|
***********************************************************************/
|
|
|
|
/// <summary>system::Sys includes a lot of utility functions for type conversion, string operations and date time operations for a Workflow script.</summary>
|
|
class Sys : public Description<Sys>
|
|
{
|
|
public:
|
|
static vint Int32ToInt(vint32_t value) { return (vint)value; }
|
|
static vint Int64ToInt(vint64_t value) { return (vint)value; }
|
|
static vint32_t IntToInt32(vint value) { return (vint32_t)value; }
|
|
static vint64_t IntToInt64(vint value) { return (vint64_t)value; }
|
|
|
|
static vuint UInt32ToUInt(vuint32_t value) { return (vuint)value; }
|
|
static vuint UInt64ToUInt(vuint64_t value) { return (vuint)value; }
|
|
static vuint32_t UIntToUInt32(vuint value) { return (vuint32_t)value; }
|
|
static vuint64_t UIntToUInt64(vuint value) { return (vuint64_t)value; }
|
|
|
|
static vint Len(const WString& value) { return value.Length(); }
|
|
static WString Left(const WString& value, vint length) { return value.Left(length); }
|
|
static WString Right(const WString& value, vint length) { return value.Right(length); }
|
|
static WString Mid(const WString& value, vint start, vint length) { return value.Sub(start, length); }
|
|
static vint Find(const WString& value, const WString& substr) { return INVLOC.FindFirst(value, substr, Locale::Normalization::None).key; }
|
|
static WString UCase(const WString& value) { return wupper(value); }
|
|
static WString LCase(const WString& value) { return wlower(value); }
|
|
|
|
static WString LoremIpsumTitle(vint bestLength) { return vl::LoremIpsumTitle(bestLength); }
|
|
static WString LoremIpsumSentence(vint bestLength) { return vl::LoremIpsumSentence(bestLength); }
|
|
static WString LoremIpsumParagraph(vint bestLength) { return vl::LoremIpsumParagraph(bestLength); }
|
|
|
|
#define DEFINE_COMPARE(TYPE) static vint Compare(TYPE a, TYPE b);
|
|
REFLECTION_PREDEFINED_PRIMITIVE_TYPES(DEFINE_COMPARE)
|
|
DEFINE_COMPARE(DateTime)
|
|
#undef DEFINE_COMPARE
|
|
|
|
static DateTime GetLocalTime();
|
|
static DateTime GetUtcTime();
|
|
static DateTime ToLocalTime(DateTime dt);
|
|
static DateTime ToUtcTime(DateTime dt);
|
|
static DateTime Forward(DateTime dt, vuint64_t milliseconds);
|
|
static DateTime Backward(DateTime dt, vuint64_t milliseconds);
|
|
static DateTime CreateDateTime(vint year, vint month, vint day);
|
|
static DateTime CreateDateTime(vint year, vint month, vint day, vint hour, vint minute, vint second, vint milliseconds);
|
|
|
|
static Ptr<IValueEnumerable> ReverseEnumerable(Ptr<IValueEnumerable> value);
|
|
};
|
|
|
|
/// <summary>system::Math includes math functions for a Workflow script.</summary>
|
|
class Math : public Description<Math>
|
|
{
|
|
public:
|
|
static double Pi() { return ASin(1) * 2; }
|
|
|
|
static vint8_t Abs(vint8_t value) { return value > 0 ? value : -value; }
|
|
static vint16_t Abs(vint16_t value) { return value > 0 ? value : -value; }
|
|
static vint32_t Abs(vint32_t value) { return value > 0 ? value : -value; }
|
|
static vint64_t Abs(vint64_t value) { return value > 0 ? value : -value; }
|
|
static float Abs(float value) { return value > 0 ? value : -value; }
|
|
static double Abs(double value) { return value > 0 ? value : -value; }
|
|
|
|
#define DEFINE_MINMAX(TYPE)\
|
|
static TYPE Min(TYPE a, TYPE b);\
|
|
static TYPE Max(TYPE a, TYPE b);\
|
|
|
|
REFLECTION_PREDEFINED_PRIMITIVE_TYPES(DEFINE_MINMAX)
|
|
DEFINE_MINMAX(DateTime)
|
|
#undef DEFINE_MINMAX
|
|
|
|
static double Sin(double value) { return sin(value); }
|
|
static double Cos(double value) { return cos(value); }
|
|
static double Tan(double value) { return tan(value); }
|
|
static double ASin(double value) { return asin(value); }
|
|
static double ACos(double value) { return acos(value); }
|
|
static double ATan(double value) { return atan(value); }
|
|
static double ATan2(double x, double y) { return atan2(y, x); }
|
|
|
|
static double Exp(double value) { return exp(value); }
|
|
static double LogN(double value) { return log(value); }
|
|
static double Log10(double value) { return log10(value); }
|
|
static double Log(double value, double base) { return log(value) / log(base); }
|
|
static double Pow(double value, double power) { return pow(value, power); }
|
|
static double Ceil(double value) { return ceil(value); }
|
|
static double Floor(double value) { return floor(value); }
|
|
static double Round(double value) { return round(value); }
|
|
static double Trunc(double value) { return trunc(value); }
|
|
};
|
|
|
|
/// <summary>system::Math includes localization awared formatting operations for a Workflow script.</summary>
|
|
/// <remarks>
|
|
/// <p>
|
|
/// There are three locales that reflect the configuration of the operating system:
|
|
/// <ul>
|
|
/// <li><b>Invariant</b>: An invariant locale for general languages.</li>
|
|
/// <li><b>System</b>: Locale for the operating system, including the file system.</li>
|
|
/// <li><b>User</b>: Locale for UI of the operating system.</li>
|
|
/// </ul>
|
|
/// </p>
|
|
/// </remarks>
|
|
class Localization : public Description<Localization>
|
|
{
|
|
public:
|
|
static Locale Invariant();
|
|
static Locale System();
|
|
static Locale User();
|
|
static collections::LazyList<Locale> Locales();
|
|
|
|
static collections::LazyList<WString> GetShortDateFormats(Locale locale);
|
|
static collections::LazyList<WString> GetLongDateFormats(Locale locale);
|
|
static collections::LazyList<WString> GetYearMonthDateFormats(Locale locale);
|
|
static collections::LazyList<WString> GetLongTimeFormats(Locale locale);
|
|
static collections::LazyList<WString> GetShortTimeFormats(Locale locale);
|
|
|
|
static WString GetShortDayOfWeekName(Locale locale, vint dayOfWeek);
|
|
static WString GetLongDayOfWeekName(Locale locale, vint dayOfWeek);
|
|
static WString GetShortMonthName(Locale locale, vint month);
|
|
static WString GetLongMonthName(Locale locale, vint month);
|
|
|
|
static WString FormatDate(Locale locale, const WString& format, DateTime date);
|
|
static WString FormatTime(Locale locale, const WString& format, DateTime date);
|
|
static WString FormatNumber(Locale locale, const WString& number);
|
|
static WString FormatCurrency(Locale locale, const WString& number);
|
|
};
|
|
|
|
/***********************************************************************
|
|
MISC
|
|
***********************************************************************/
|
|
|
|
class Versioning : public Object, public Description<Versioning>
|
|
{
|
|
protected:
|
|
vint version = 0;
|
|
|
|
public:
|
|
Versioning();
|
|
~Versioning();
|
|
|
|
vint AllocateVersion();
|
|
vint GetVersion();
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace vl
|
|
{
|
|
namespace __vwsn
|
|
{
|
|
struct att_cpp_File
|
|
{
|
|
WString argument;
|
|
auto operator<=>(const att_cpp_File&) const = default;
|
|
};
|
|
|
|
struct att_cpp_UserImpl
|
|
{
|
|
auto operator<=>(const att_cpp_UserImpl&) const = default;
|
|
};
|
|
|
|
struct att_cpp_Private
|
|
{
|
|
auto operator<=>(const att_cpp_Private&) const = default;
|
|
};
|
|
|
|
struct att_cpp_Protected
|
|
{
|
|
auto operator<=>(const att_cpp_Protected&) const = default;
|
|
};
|
|
|
|
struct att_cpp_Friend
|
|
{
|
|
reflection::description::ITypeDescriptor* argument = nullptr;
|
|
auto operator<=>(const att_cpp_Friend&) const = default;
|
|
};
|
|
|
|
struct att_rpc_Interface
|
|
{
|
|
auto operator<=>(const att_rpc_Interface&) const = default;
|
|
};
|
|
|
|
struct att_rpc_Ctor
|
|
{
|
|
auto operator<=>(const att_rpc_Ctor&) const = default;
|
|
};
|
|
|
|
struct att_rpc_Byval
|
|
{
|
|
auto operator<=>(const att_rpc_Byval&) const = default;
|
|
};
|
|
|
|
struct att_rpc_Byref
|
|
{
|
|
auto operator<=>(const att_rpc_Byref&) const = default;
|
|
};
|
|
|
|
struct att_rpc_Cached
|
|
{
|
|
auto operator<=>(const att_rpc_Cached&) const = default;
|
|
};
|
|
|
|
struct att_rpc_Dynamic
|
|
{
|
|
auto operator<=>(const att_rpc_Dynamic&) const = default;
|
|
};
|
|
|
|
struct att_rpc_IdString
|
|
{
|
|
WString argument;
|
|
auto operator<=>(const att_rpc_IdString&) const = default;
|
|
};
|
|
|
|
struct att_rpc_IdNumber
|
|
{
|
|
vint argument = 0;
|
|
auto operator<=>(const att_rpc_IdNumber&) const = default;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\WFLIBRARYCPPHELPER.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::Reflection
|
|
|
|
Interfaces:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_CPPLIBRARY
|
|
#define VCZH_WORKFLOW_LIBRARY_CPPLIBRARY
|
|
|
|
|
|
namespace vl
|
|
{
|
|
namespace __vwsn
|
|
{
|
|
template<typename T>
|
|
struct RunOnExit
|
|
{
|
|
T* function;
|
|
|
|
RunOnExit(T* _function)
|
|
:function(_function)
|
|
{
|
|
}
|
|
|
|
~RunOnExit()
|
|
{
|
|
function->operator()();
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
T* This(T* thisValue)
|
|
{
|
|
CHECK_ERROR(thisValue != nullptr, L"The this pointer cannot be null.");
|
|
return thisValue;
|
|
}
|
|
|
|
template<typename T>
|
|
T* Ensure(T* pointer)
|
|
{
|
|
CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null.");
|
|
return pointer;
|
|
}
|
|
|
|
template<typename T>
|
|
Ptr<T>& Ensure(Ptr<T>& pointer)
|
|
{
|
|
CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null.");
|
|
return pointer;
|
|
}
|
|
|
|
template<typename T>
|
|
Ptr<T> Ensure(Ptr<T>&& pointer)
|
|
{
|
|
CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null.");
|
|
return std::move(pointer);
|
|
}
|
|
|
|
template<typename T>
|
|
Nullable<T> Ensure(Nullable<T>&& nullable)
|
|
{
|
|
CHECK_ERROR(nullable, L"The pointer cannot be null.");
|
|
return std::move(nullable);
|
|
}
|
|
|
|
template<typename T>
|
|
Nullable<T>& Ensure(Nullable<T>& nullable)
|
|
{
|
|
CHECK_ERROR(nullable, L"The pointer cannot be null.");
|
|
return nullable;
|
|
}
|
|
|
|
template<typename T>
|
|
WString ToString(const T& value)
|
|
{
|
|
WString str;
|
|
CHECK_ERROR(reflection::description::TypedValueSerializerProvider<std::remove_cvref_t<T>>::Serialize(value, str), L"Failed to serialize.");
|
|
return str;
|
|
}
|
|
|
|
template<typename T>
|
|
T Parse(const WString& str)
|
|
{
|
|
T value;
|
|
CHECK_ERROR(reflection::description::TypedValueSerializerProvider<std::remove_cvref_t<T>>::Deserialize(str, value), L"Failed to serialize.");
|
|
return value;
|
|
}
|
|
|
|
template<typename TTo, typename TFrom>
|
|
struct NullableCastHelper
|
|
{
|
|
static Nullable<TTo> Cast(Nullable<TFrom> nullable)
|
|
{
|
|
return Nullable<TTo>(static_cast<TTo>(nullable.Value()));
|
|
}
|
|
};
|
|
|
|
template<typename TFrom>
|
|
struct NullableCastHelper<WString, TFrom>
|
|
{
|
|
static Nullable<WString> Cast(Nullable<TFrom> nullable)
|
|
{
|
|
return Nullable<WString>(ToString(nullable.Value()));
|
|
}
|
|
};
|
|
|
|
template<typename TTo>
|
|
struct NullableCastHelper<TTo, WString>
|
|
{
|
|
static Nullable<TTo> Cast(Nullable<WString> nullable)
|
|
{
|
|
return Nullable<TTo>(Parse<TTo>(nullable.Value()));
|
|
}
|
|
};
|
|
|
|
template<typename TTo, typename TFrom>
|
|
Nullable<TTo> NullableCast(Nullable<TFrom> nullable)
|
|
{
|
|
if (!nullable) return Nullable<TTo>();
|
|
return NullableCastHelper<TTo, TFrom>::Cast(nullable);
|
|
}
|
|
|
|
template<typename TTo, typename TFrom>
|
|
TTo* RawPtrCast(TFrom* pointer)
|
|
{
|
|
if (!pointer) return nullptr;
|
|
if (auto converted = dynamic_cast<TTo*>(pointer)) return converted;
|
|
return pointer->template SafeAggregationCast<TTo>();
|
|
}
|
|
|
|
template<typename TTo, typename TFrom>
|
|
Ptr<TTo> SharedPtrCast(TFrom* pointer)
|
|
{
|
|
if (!pointer) return nullptr;
|
|
if (auto converted = dynamic_cast<TTo*>(pointer)) return Ptr(converted);
|
|
return Ptr(pointer->template SafeAggregationCast<TTo>());
|
|
}
|
|
|
|
template<typename T>
|
|
reflection::description::Value Box(T&& value)
|
|
{
|
|
return reflection::description::BoxParameter(value);
|
|
}
|
|
|
|
template<typename T>
|
|
T Unbox(const reflection::description::Value& value)
|
|
{
|
|
auto unboxed = reflection::description::UnboxParameter<std::remove_cvref_t<T>>(value);
|
|
if (std::is_reference_v<T>)
|
|
{
|
|
CHECK_ERROR(!unboxed.IsOwned(), L"It is impossible to return a reference from a unboxed value, when the unboxing has to call new T(...).");
|
|
}
|
|
return unboxed.Ref();
|
|
}
|
|
|
|
template<typename T>
|
|
struct UnboxWeakHelper
|
|
{
|
|
};
|
|
|
|
template<typename T>
|
|
struct UnboxWeakHelper<T*>
|
|
{
|
|
static T* Unbox(const reflection::description::Value& value)
|
|
{
|
|
if (value.IsNull()) return nullptr;
|
|
auto rawPtr = value.GetRawPtr();
|
|
if (!rawPtr) return nullptr;
|
|
if (auto converted = dynamic_cast<T*>(rawPtr)) return converted;
|
|
try
|
|
{
|
|
return rawPtr->SafeAggregationCast<T>();
|
|
}
|
|
catch (const Exception&)
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct UnboxWeakHelper<Ptr<T>>
|
|
{
|
|
static Ptr<T> Unbox(const reflection::description::Value& value)
|
|
{
|
|
if (value.IsNull()) return nullptr;
|
|
auto rawPtr = value.GetRawPtr();
|
|
if (!rawPtr) return nullptr;
|
|
if (auto converted = dynamic_cast<T*>(rawPtr)) return Ptr(converted);
|
|
try
|
|
{
|
|
return Ptr(rawPtr->SafeAggregationCast<T>());
|
|
}
|
|
catch (const Exception&)
|
|
{
|
|
return nullptr;
|
|
}
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct UnboxWeakHelper<Nullable<T>>
|
|
{
|
|
static Nullable<T> Unbox(const reflection::description::Value& value)
|
|
{
|
|
if (value.IsNull()) return Nullable<T>();
|
|
auto boxed = value.GetBoxedValue().Cast<reflection::description::IValueType::TypedBox<T>>();
|
|
if (!boxed) return Nullable<T>();
|
|
return Nullable<T>(boxed->value);
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
T UnboxWeak(const reflection::description::Value& value)
|
|
{
|
|
return UnboxWeakHelper<std::remove_cvref_t<T>>::Unbox(value);
|
|
}
|
|
|
|
template<typename T>
|
|
collections::LazyList<T> Range(T begin, T end)
|
|
{
|
|
return collections::Range<T>(begin, end - begin);
|
|
}
|
|
|
|
template<typename T>
|
|
bool InSet(const T& value, const collections::LazyList<T>& collection)
|
|
{
|
|
return collection.Any([&](const T& element) {return element == value; });
|
|
}
|
|
|
|
template<typename T>
|
|
bool InSet(const T& value, Ptr<reflection::description::IValueReadonlyList> collection)
|
|
{
|
|
return InSet<T>(value, reflection::description::GetLazyList<T>(collection));
|
|
}
|
|
|
|
template<typename T, typename U>
|
|
Ptr<T> UnboxCollection(U&& value)
|
|
{
|
|
auto boxedValue = reflection::description::BoxParameter(value);
|
|
return reflection::description::UnboxParameter<Ptr<T>>(boxedValue).Ref();
|
|
}
|
|
|
|
template<typename T, typename U>
|
|
Ptr<T> UnboxCollection(const collections::LazyList<U>& value)
|
|
{
|
|
auto boxedValue = reflection::description::BoxParameter(const_cast<collections::LazyList<U>&>(value));
|
|
return reflection::description::UnboxParameter<Ptr<T>>(boxedValue).Ref();
|
|
}
|
|
|
|
struct CreateArray
|
|
{
|
|
using IValueArray = reflection::description::IValueArray;
|
|
|
|
Ptr<IValueArray> list;
|
|
|
|
CreateArray();
|
|
CreateArray(Ptr<IValueArray> _list);
|
|
|
|
CreateArray Resize(vint size)
|
|
{
|
|
list->Resize(size);
|
|
return{ list };
|
|
}
|
|
|
|
template<typename T>
|
|
CreateArray Set(vint index, const T& value)
|
|
{
|
|
list->Set(index, Box(value));
|
|
return{ list };
|
|
}
|
|
};
|
|
|
|
struct CreateList
|
|
{
|
|
using IValueList = reflection::description::IValueList;
|
|
|
|
Ptr<IValueList> list;
|
|
|
|
CreateList();
|
|
CreateList(Ptr<IValueList> _list);
|
|
|
|
template<typename T>
|
|
CreateList Add(const T& value)
|
|
{
|
|
list->Add(Box(value));
|
|
return{ list };
|
|
}
|
|
};
|
|
|
|
struct CreateObservableList
|
|
{
|
|
using IValueObservableList = reflection::description::IValueObservableList;
|
|
|
|
Ptr<IValueObservableList> list;
|
|
|
|
CreateObservableList();
|
|
CreateObservableList(Ptr<IValueObservableList> _list);
|
|
|
|
template<typename T>
|
|
CreateObservableList Add(const T& value)
|
|
{
|
|
list->Add(Box(value));
|
|
return{ list };
|
|
}
|
|
};
|
|
|
|
struct CreateDictionary
|
|
{
|
|
using IValueDictionary = reflection::description::IValueDictionary;
|
|
|
|
Ptr<IValueDictionary> dictionary;
|
|
|
|
CreateDictionary();
|
|
CreateDictionary(Ptr<IValueDictionary> _dictionary);
|
|
|
|
template<typename K, typename V>
|
|
CreateDictionary Add(const K& key, const V& value)
|
|
{
|
|
dictionary->Set(Box(key), Box(value));
|
|
return{ dictionary };
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct EventHelper
|
|
{
|
|
};
|
|
|
|
template<typename T>
|
|
Ptr<reflection::description::IEventHandler> EventAttach(T& e, typename EventHelper<T>::Handler handler)
|
|
{
|
|
return EventHelper<T>::Attach(e, handler);
|
|
}
|
|
|
|
template<typename T>
|
|
bool EventDetach(T& e, Ptr<reflection::description::IEventHandler> handler)
|
|
{
|
|
return EventHelper<T>::Detach(e, handler);
|
|
}
|
|
|
|
template<typename T>
|
|
decltype(auto) EventInvoke(T& e)
|
|
{
|
|
return EventHelper<T>::Invoke(e);
|
|
}
|
|
|
|
template<typename ...TArgs>
|
|
struct EventHelper<Event<void(TArgs...)>>
|
|
{
|
|
using Handler = const Func<void(TArgs...)>&;
|
|
|
|
class EventHandlerImpl : public Object, public reflection::description::IEventHandler
|
|
{
|
|
public:
|
|
Ptr<EventHandler> handler;
|
|
|
|
EventHandlerImpl(Ptr<EventHandler> _handler)
|
|
:handler(_handler)
|
|
{
|
|
}
|
|
|
|
bool IsAttached()override
|
|
{
|
|
return handler->IsAttached();
|
|
}
|
|
};
|
|
|
|
static Ptr<reflection::description::IEventHandler> Attach(Event<void(TArgs...)>& e, Handler handler)
|
|
{
|
|
return Ptr(new EventHandlerImpl(e.Add(handler)));
|
|
}
|
|
|
|
static bool Detach(Event<void(TArgs...)>& e, Ptr<reflection::description::IEventHandler> handler)
|
|
{
|
|
auto impl = handler.Cast<EventHandlerImpl>();
|
|
if (!impl) return false;
|
|
return e.Remove(impl->handler);
|
|
}
|
|
|
|
static Event<void(TArgs...)>& Invoke(Event<void(TArgs...)>& e)
|
|
{
|
|
return e;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPC\WFLIBRARYRPC.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::RPC
|
|
|
|
Interfaces:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC
|
|
|
|
|
|
namespace vl
|
|
{
|
|
namespace rpc_controller
|
|
{
|
|
constexpr vint RpcTypeId_NotFound = -100;
|
|
constexpr vint RpcClientId_Invalid = -1;
|
|
constexpr vint RpcObjectId_Invalid = -1;
|
|
|
|
struct RpcObjectReference
|
|
{
|
|
vint clientId = RpcClientId_Invalid;
|
|
vint objectId = RpcObjectId_Invalid;
|
|
vint typeId = RpcTypeId_NotFound;
|
|
|
|
auto operator<=>(const RpcObjectReference&) const = default;
|
|
};
|
|
|
|
struct RpcException
|
|
{
|
|
WString message;
|
|
|
|
auto operator<=>(const RpcException&) const = default;
|
|
};
|
|
|
|
using RpcEventExceptionMap = Ptr<reflection::description::IValueDictionary>;
|
|
using RpcLocalServiceMap = collections::Dictionary<vint, Ptr<reflection::IDescriptable>>;
|
|
|
|
extern void MergeRpcEventExceptionMap(RpcEventExceptionMap target, RpcEventExceptionMap source);
|
|
|
|
class RpcByvalReturnValue
|
|
: public Object
|
|
, public reflection::Description<RpcByvalReturnValue>
|
|
{
|
|
public:
|
|
reflection::description::Value value;
|
|
vint slot = -1;
|
|
};
|
|
|
|
inline constexpr vint RpcTypeId_IValueEnumerable = -1;
|
|
inline constexpr vint RpcTypeId_IValueEnumerator = -2;
|
|
inline constexpr vint RpcTypeId_IValueArray = -3;
|
|
inline constexpr vint RpcTypeId_IValueList = -4;
|
|
inline constexpr vint RpcTypeId_IValueObservableList = -5;
|
|
inline constexpr vint RpcTypeId_IValueDictionary = -6;
|
|
inline constexpr vint RpcTypeId_IValueReadonlyList = -7;
|
|
|
|
inline constexpr vint RpcMethodId_IValueEnumerable_CreateEnumerator = -1;
|
|
inline constexpr vint RpcMethodId_IValueEnumerator_Next = -2;
|
|
inline constexpr vint RpcMethodId_IValueEnumerator_GetCurrent = -3;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyList_GetCount = -4;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyList_Get = -5;
|
|
inline constexpr vint RpcMethodId_IValueList_Set = -6;
|
|
inline constexpr vint RpcMethodId_IValueList_Add = -7;
|
|
inline constexpr vint RpcMethodId_IValueList_Insert = -8;
|
|
inline constexpr vint RpcMethodId_IValueList_RemoveAt = -9;
|
|
inline constexpr vint RpcMethodId_IValueList_Clear = -10;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyList_Contains = -11;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyList_IndexOf = -12;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyDictionary_GetCount = -13;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyDictionary_Get = -14;
|
|
inline constexpr vint RpcMethodId_IValueDictionary_Set = -15;
|
|
inline constexpr vint RpcMethodId_IValueDictionary_Remove = -16;
|
|
inline constexpr vint RpcMethodId_IValueDictionary_Clear = -17;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyDictionary_ContainsKey = -18;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyDictionary_GetKeys = -19;
|
|
inline constexpr vint RpcMethodId_IValueReadonlyDictionary_GetValues = -20;
|
|
inline constexpr vint RpcMethodId_IValueArray_Resize = -21;
|
|
|
|
inline constexpr vint RpcEventId_IValueObservableList_ItemChanged = -1;
|
|
|
|
/***********************************************************************
|
|
* Interfaces (Serialization)
|
|
***********************************************************************/
|
|
|
|
class IRpcSerializer
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcSerializer>
|
|
{
|
|
public:
|
|
virtual reflection::description::Value Serialize(const reflection::description::Value& value) = 0;
|
|
virtual reflection::description::Value Deserialize(const reflection::description::Value& value) = 0;
|
|
};
|
|
|
|
/***********************************************************************
|
|
* Interfaces (Operations)
|
|
***********************************************************************/
|
|
|
|
class IRpcListOps
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcListOps>
|
|
{
|
|
public:
|
|
virtual RpcObjectReference EnumCreate(RpcObjectReference ref) = 0;
|
|
virtual bool EnumNext(RpcObjectReference enumerator) = 0;
|
|
virtual reflection::description::Value EnumGetCurrent(RpcObjectReference enumerator) = 0;
|
|
|
|
virtual vint ListGetCount(RpcObjectReference ref) = 0;
|
|
virtual reflection::description::Value ListGet(RpcObjectReference ref, vint index) = 0;
|
|
virtual void ListSet(RpcObjectReference ref, vint index, const reflection::description::Value& value) = 0;
|
|
virtual vint ListAdd(RpcObjectReference ref, const reflection::description::Value& value) = 0;
|
|
virtual vint ListInsert(RpcObjectReference ref, vint index, const reflection::description::Value& value) = 0;
|
|
virtual bool ListRemoveAt(RpcObjectReference ref, vint index) = 0;
|
|
virtual void ListClear(RpcObjectReference ref) = 0;
|
|
virtual bool ListContains(RpcObjectReference ref, const reflection::description::Value& value) = 0;
|
|
virtual vint ListIndexOf(RpcObjectReference ref, const reflection::description::Value& value) = 0;
|
|
virtual void ArrayResize(RpcObjectReference ref, vint size) = 0;
|
|
|
|
virtual vint DictGetCount(RpcObjectReference ref) = 0;
|
|
virtual reflection::description::Value DictGet(RpcObjectReference ref, const reflection::description::Value& key) = 0;
|
|
virtual void DictSet(RpcObjectReference ref, const reflection::description::Value& key, const reflection::description::Value& value) = 0;
|
|
virtual bool DictRemove(RpcObjectReference ref, const reflection::description::Value& key) = 0;
|
|
virtual void DictClear(RpcObjectReference ref) = 0;
|
|
virtual bool DictContainsKey(RpcObjectReference ref, const reflection::description::Value& key) = 0;
|
|
virtual RpcObjectReference DictGetKeys(RpcObjectReference ref) = 0;
|
|
virtual RpcObjectReference DictGetValues(RpcObjectReference ref) = 0;
|
|
};
|
|
|
|
class IRpcObjectOps
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcObjectOps>
|
|
{
|
|
public:
|
|
virtual reflection::description::Value InvokeMethod(RpcObjectReference ref, vint methodId, Ptr<reflection::description::IValueArray> arguments) = 0;
|
|
virtual void EndInvokeMethod(vint slot) = 0;
|
|
virtual void ObjectHold(RpcObjectReference ref, vint remoteClientId, bool hold) = 0;
|
|
};
|
|
|
|
class IRpcListEventOps
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcListEventOps>
|
|
{
|
|
public:
|
|
virtual reflection::description::Value OnItemChanged(RpcObjectReference ref, vint index, vint oldCount, vint newCount) = 0;
|
|
};
|
|
|
|
class IRpcObjectEventOps
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcObjectEventOps>
|
|
{
|
|
public:
|
|
virtual reflection::description::Value InvokeEvent(RpcObjectReference ref, vint eventId, Ptr<reflection::description::IValueArray> arguments) = 0;
|
|
};
|
|
|
|
/***********************************************************************
|
|
* Interfaces (Lifecycle)
|
|
***********************************************************************/
|
|
|
|
class IRpcOperations
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcOperations>
|
|
{
|
|
public:
|
|
virtual IRpcObjectOps* GetObjectOps() = 0;
|
|
virtual IRpcObjectEventOps* GetObjectEventOps() = 0;
|
|
};
|
|
|
|
class IRpcDispatcher
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcDispatcher>
|
|
{
|
|
public:
|
|
virtual void Finalize() = 0;
|
|
virtual void Initialize() = 0;
|
|
virtual void DeclareLocalService(RpcObjectReference ref) = 0;
|
|
|
|
virtual IRpcObjectEventOps* BroadcastFromClient_ObjectEventOps(vint selfClientId) = 0;
|
|
virtual IRpcObjectOps* SendToClient_ObjectOps(vint targetClientId) = 0;
|
|
};
|
|
|
|
class IRpcController
|
|
: public virtual IRpcOperations
|
|
, public reflection::Description<IRpcController>
|
|
{
|
|
public:
|
|
virtual void Finalize() = 0;
|
|
virtual void SetEventSuppressedFlag(RpcObjectReference ref, vint eventId, bool suppressed) = 0;
|
|
virtual bool GetEventSuppressedFlag(RpcObjectReference ref, vint eventId) = 0;
|
|
virtual void SetItemChangedSuppressedFlag(RpcObjectReference ref, bool suppressed) = 0;
|
|
virtual bool GetItemChangedSuppressedFlag(RpcObjectReference ref) = 0;
|
|
};
|
|
|
|
/*
|
|
* [Configuration]
|
|
*
|
|
* RunRpcTestCase_JsonRequest configures one RpcJsonDispatcher and one RpcJsonLifecycle for each client.
|
|
* messageDispatcher = shared IRpcJsonMessageDispatcher
|
|
* dispatcher = RpcJsonDispatcher(clientId, messageDispatcher)
|
|
* lifecycle = RpcJsonLifecycle(clientId, dispatcher)
|
|
* serializer = rpcops_IRpcSerializer()
|
|
* getTypeId = [rpcwrapper_GetTypeId(BoxValue<IDescriptable*>(obj))]
|
|
* lifecycle->Register(serializer, rpcops_IRpcObjectOpsJson(lifecycle), rpcops_IRpcObjectEventOpsJson(lifecycle), getTypeId, eventAttacher)
|
|
*
|
|
* Triggering RpcLifecycleBase::AttachLocalObjectEvents
|
|
* call rpclistener_Attach(ref.typeId, this, ref, obj, (cached)rpcops_IOps_CreateJson(this))
|
|
*
|
|
* [Call graph for JSON based RPC]
|
|
*
|
|
* Calling Method of Remote Object:
|
|
* -> IMyInterface::Method (generated Workflow code)
|
|
* -> rpcops_IOps_<Application>::InvokeMethod_IMyInterface_Method (generated Workflow code)
|
|
* {
|
|
* -> IRpcLifecycle->GetDispatcher()->SendToClient_ObjectOps()->InvokeMethod
|
|
* -> RpcJsonObjectOps::InvokeMethod
|
|
* -> IRpcJsonMessageDispatcher::OnJsonRequest
|
|
* ---- NETWORK PROTOCOL (request) ----
|
|
* -> RpcJsonObjectOps::Translate
|
|
* -> IRpcLifecycle->GetController()->GetObjectOps()->InvokeMethod
|
|
* -> RpcCalleeObjectOpsForList::InvokeMethod
|
|
* -> rpcops_IRpcObjectOpsJson()->InvokeMethod (generated Workflow code)
|
|
* -> IMyInterface::Method (actual)
|
|
* ---- NETWORK PROTOCOL (response) ----
|
|
* }
|
|
* { optional EndInvokeMethod when @rpc:Byval on return value }
|
|
*
|
|
* Triggering Event of Remote Object (events are automatically hooked when creating a wrapper for a remote object):
|
|
* -> IMyInterface::SomethingHappened
|
|
* -> rpcops_IOps_<Application>::InvokeMethod_IMyInterface_SomethingHappened (generated Workflow code)
|
|
* {
|
|
* -> IRpcLifecycle->GetDispatcher()->BroadcastFromClient_ObjectEventOps()->InvokeEvent
|
|
* -> RpcJsonEventObjectOps::InvokeEvent
|
|
* -> IRpcJsonMessageDispatcher::OnJsonRequest
|
|
* ---- NETWORK PROTOCOL (broadcast) ----
|
|
* -> RpcJsonEventObjectOps::Translate
|
|
* -> IRpcLifecycle->GetController()->GetObjectOps()->InvokeEvent
|
|
* -> RpcCalleeObjectEventOpsForList::InvokeEvent
|
|
* -> rpcops_IRpcObjectEventOpsJson()->InvokeEvent (generated Workflow code)
|
|
* -> IMyInterface::SomethingHappened
|
|
* ---- NETWORK PROTOCOL (response) ----
|
|
* }
|
|
*
|
|
* Triggering Event of Local Object (when a local object is tracked, RpcLifecycleBase::AttachLocalObjectEvents will be called)
|
|
* The same to remote object.
|
|
*
|
|
* Registering Service:
|
|
* -> IRpcLifecycle->RegisterLocalService
|
|
* {
|
|
* -> IRpcLifecycle->GetDispatcher()->DeclareLocalService(ref)
|
|
* ---- NETWORK PROTOCOL (broadcast) ----
|
|
* -> IRpcLifecycle::DeclareRemoteService(ref)
|
|
* }
|
|
*/
|
|
class IRpcLifecycle
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcLifecycle>
|
|
{
|
|
public:
|
|
virtual void Finalize() = 0;
|
|
virtual void Initialize() = 0;
|
|
virtual vint GetClientId() = 0;
|
|
virtual IRpcDispatcher* GetDispatcher() = 0;
|
|
virtual IRpcController* GetController() = 0;
|
|
virtual IRpcSerializer* GetSerializer() = 0;
|
|
virtual const RpcLocalServiceMap& GetRegisteredLocalServices() = 0;
|
|
virtual Ptr<reflection::IDescriptable> RefToPtr(RpcObjectReference ref) = 0;
|
|
virtual RpcObjectReference PtrToRef(Ptr<reflection::IDescriptable> obj) = 0;
|
|
virtual void LocalObjectHold(RpcObjectReference ref, vint remoteClientId) = 0;
|
|
virtual void LocalObjectUnhold(RpcObjectReference ref, vint remoteClientId) = 0;
|
|
virtual void RegisterLocalService(vint typeId, Ptr<reflection::IDescriptable> service) = 0;
|
|
virtual void DeclareRemoteService(RpcObjectReference ref) = 0;
|
|
virtual vint GetTypeIdFromName(WString typeName) = 0;
|
|
virtual Ptr<reflection::IDescriptable> RequestService(WString typeName) = 0;
|
|
};
|
|
|
|
class IRpcWrapperBase
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcWrapperBase>
|
|
{
|
|
public:
|
|
virtual void DisconnectFromLifecycle() = 0;
|
|
};
|
|
|
|
/***********************************************************************
|
|
* Helpers
|
|
***********************************************************************/
|
|
|
|
extern RpcObjectReference RpcBoxByref(Ptr<reflection::IDescriptable> trivial, IRpcLifecycle* lc);
|
|
extern Ptr<reflection::IDescriptable> RpcUnboxByref(RpcObjectReference serializable, IRpcLifecycle* lc);
|
|
extern reflection::description::Value RpcCopyByval(const reflection::description::Value& trivial, IRpcLifecycle* lc);
|
|
extern reflection::description::Value RpcBoxByval(Ptr<reflection::IDescriptable> trivial, IRpcLifecycle* lc);
|
|
extern reflection::description::Value RpcBoxByval(const reflection::description::Value& trivial, IRpcLifecycle* lc);
|
|
extern Ptr<reflection::IDescriptable> RpcUnboxByval(const reflection::description::Value& serializable, IRpcLifecycle* lc);
|
|
extern void ReadMethodException(const reflection::description::Value& value);
|
|
extern void ReadEventException(RpcEventExceptionMap exceptions);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPC\WFLIBRARYRPCCONTROLLER.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::RPC
|
|
|
|
Interfaces:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_CONTROLLER
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC_CONTROLLER
|
|
|
|
|
|
namespace vl
|
|
{
|
|
namespace rpc_controller
|
|
{
|
|
struct RpcEventSuppressionKey
|
|
{
|
|
RpcObjectReference ref;
|
|
vint eventId = 0;
|
|
|
|
auto operator<=>(const RpcEventSuppressionKey&) const = default;
|
|
};
|
|
|
|
class RpcControllerDefault : public Object, public IRpcController
|
|
{
|
|
protected:
|
|
Ptr<IRpcObjectOps> objectCallback;
|
|
Ptr<IRpcObjectEventOps> eventCallback;
|
|
collections::Dictionary<RpcEventSuppressionKey, vint> eventSuppressedFlags;
|
|
collections::Dictionary<RpcObjectReference, vint> itemChangedSuppressedFlags;
|
|
|
|
template<typename TKey>
|
|
static void SetSuppressedFlag(collections::Dictionary<TKey, vint>& flags, const TKey& key, bool suppressed);
|
|
|
|
template<typename TKey>
|
|
static bool GetSuppressedFlag(const collections::Dictionary<TKey, vint>& flags, const TKey& key);
|
|
|
|
public:
|
|
|
|
RpcControllerDefault();
|
|
~RpcControllerDefault();
|
|
|
|
void Register(Ptr<IRpcObjectOps> objectCallback, Ptr<IRpcObjectEventOps> eventCallback);
|
|
|
|
// IRpcController
|
|
|
|
IRpcObjectOps* GetObjectOps()override;
|
|
IRpcObjectEventOps* GetObjectEventOps()override;
|
|
|
|
void Finalize()override;
|
|
void SetEventSuppressedFlag(RpcObjectReference ref, vint eventId, bool suppressed)override;
|
|
bool GetEventSuppressedFlag(RpcObjectReference ref, vint eventId)override;
|
|
void SetItemChangedSuppressedFlag(RpcObjectReference ref, bool suppressed)override;
|
|
bool GetItemChangedSuppressedFlag(RpcObjectReference ref)override;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPC\WFLIBRARYRPCLIFECYCLE.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::RPC
|
|
|
|
Lifecycle:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_LIFECYCLE
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC_LIFECYCLE
|
|
|
|
|
|
namespace vl
|
|
{
|
|
namespace rpc_controller
|
|
{
|
|
class IRpcSerializer;
|
|
class RpcLifecycleBase;
|
|
|
|
class RpcLocalObjectTracker : public Object
|
|
{
|
|
friend class RpcLifecycleBase;
|
|
private:
|
|
RpcLifecycleBase* lifecycle = nullptr;
|
|
RpcObjectReference ref;
|
|
public:
|
|
RpcLocalObjectTracker(RpcLifecycleBase* lc, RpcObjectReference r);
|
|
~RpcLocalObjectTracker();
|
|
void Attach(RpcLifecycleBase* lc, RpcObjectReference r);
|
|
void Detach();
|
|
RpcObjectReference GetRef() const { return ref; }
|
|
vint GetClientId() const { return ref.clientId; }
|
|
RpcLifecycleBase* GetLifecycle() const { return lifecycle; }
|
|
bool IsTracked() const { return lifecycle != nullptr; }
|
|
};
|
|
|
|
class RpcWrapperTracker : public Object
|
|
{
|
|
friend class RpcLifecycleBase;
|
|
private:
|
|
RpcLifecycleBase* lifecycle = nullptr;
|
|
RpcObjectReference ref;
|
|
public:
|
|
RpcWrapperTracker(RpcLifecycleBase* lc, RpcObjectReference r);
|
|
~RpcWrapperTracker();
|
|
void Detach();
|
|
RpcObjectReference GetRef() const { return ref; }
|
|
RpcLifecycleBase* GetLifecycle() const { return lifecycle; }
|
|
};
|
|
|
|
struct RpcLocalObjectProperties : public Object
|
|
{
|
|
RpcObjectReference ref;
|
|
collections::SortedList<vint> interestedClients;
|
|
reflection::IDescriptable* rawPtr = nullptr;
|
|
Ptr<reflection::IDescriptable> ownedPtr;
|
|
Ptr<EventHandler> eventHandler;
|
|
};
|
|
|
|
class RpcLifecycleBase : public Object, public IRpcLifecycle
|
|
{
|
|
friend class RpcLocalObjectTracker;
|
|
friend class RpcWrapperTracker;
|
|
public:
|
|
using UniversalWrapperFactory = Func<Ptr<IRpcWrapperBase>(RpcObjectReference, IRpcLifecycle*)>;
|
|
private:
|
|
struct RpcWrapperProperties
|
|
{
|
|
reflection::DescriptableObject* root = nullptr;
|
|
IRpcWrapperBase* proxy = nullptr;
|
|
};
|
|
using LocalProperties = collections::Dictionary<vint, Ptr<RpcLocalObjectProperties>>;
|
|
using WrapperProperties = collections::Dictionary<RpcObjectReference, RpcWrapperProperties>;
|
|
private:
|
|
RpcControllerDefault controller;
|
|
vint clientId = RpcClientId_Invalid;
|
|
vint nextObjectId = RpcObjectId_Invalid;
|
|
bool initialized = false;
|
|
LocalProperties localObjectProperties;
|
|
RpcLocalServiceMap registeredLocalServices;
|
|
collections::Dictionary<vint, RpcObjectReference> registeredRemoteServices;
|
|
static WString InternalProperty_LocalObjectTracker;
|
|
static WString InternalProperty_WrapperTracker;
|
|
UniversalWrapperFactory universalWrapperFactory;
|
|
WrapperProperties wrapperProperties;
|
|
|
|
void TrackWrapper(reflection::DescriptableObject* root, IRpcWrapperBase* proxy, RpcObjectReference ref);
|
|
void UntrackWrapper(RpcObjectReference ref);
|
|
bool TryGetTrackedWrapperRef(reflection::DescriptableObject* obj, RpcObjectReference& ref)const;
|
|
IRpcWrapperBase* GetTrackedWrapper(RpcObjectReference ref)const;
|
|
void TrackLocalObject(RpcObjectReference ref, reflection::IDescriptable* obj);
|
|
RpcObjectReference CreateLocalObject(Ptr<reflection::IDescriptable> obj, RpcObjectReference ref);
|
|
void UntrackLocalObject(RpcObjectReference ref, bool clearInternalProperty);
|
|
void RemoveLocalObject(RpcObjectReference ref, bool clearInternalProperty);
|
|
bool IsTracked(vint objectId)const;
|
|
Ptr<reflection::IDescriptable> CreateCallerProxy(RpcObjectReference ref, IRpcSerializer* serializer);
|
|
void DisconnectWrappersForFinalize();
|
|
protected:
|
|
collections::Dictionary<WString, vint> idMap;
|
|
Ptr<IRpcSerializer> serializer;
|
|
|
|
virtual vint DecideTypeId(reflection::IDescriptable* obj)const;
|
|
virtual void AttachLocalObjectEvents(RpcObjectReference ref, reflection::IDescriptable* obj) = 0;
|
|
public:
|
|
RpcLifecycleBase(vint _clientId);
|
|
~RpcLifecycleBase();
|
|
|
|
void SetIdMap(const collections::Dictionary<WString, vint>& _idMap);
|
|
void RegisterWrapperFactory(UniversalWrapperFactory factory);
|
|
void SetSerializer(Ptr<IRpcSerializer> _serializer);
|
|
IRpcSerializer* GetSerializer() override;
|
|
|
|
// IRpcLifecycle
|
|
|
|
void Finalize()override;
|
|
void Initialize()override;
|
|
vint GetClientId()override;
|
|
RpcControllerDefault* GetController()override;
|
|
const RpcLocalServiceMap& GetRegisteredLocalServices()override;
|
|
void LocalObjectHold(RpcObjectReference ref, vint remoteClientId)override;
|
|
void LocalObjectUnhold(RpcObjectReference ref, vint remoteClientId)override;
|
|
void RegisterLocalService(vint typeId, Ptr<reflection::IDescriptable> service)override;
|
|
void DeclareRemoteService(RpcObjectReference ref)override;
|
|
vint GetTypeIdFromName(WString typeName)override;
|
|
Ptr<reflection::IDescriptable> RequestService(WString typeName)override;
|
|
Ptr<reflection::IDescriptable> RefToPtr(RpcObjectReference ref)override;
|
|
Ptr<reflection::IDescriptable> RefToPtr(RpcObjectReference ref, IRpcSerializer* serializer);
|
|
RpcObjectReference PtrToRef(Ptr<reflection::IDescriptable> obj)override;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPC\WFLIBRARYRPCWRAPPERS.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::RPC
|
|
|
|
Collection Wrappers:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_WRAPPERS
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC_WRAPPERS
|
|
|
|
|
|
namespace vl
|
|
{
|
|
namespace rpc_controller
|
|
{
|
|
|
|
/***********************************************************************
|
|
* Collection Caller Wrappers
|
|
***********************************************************************/
|
|
|
|
class RpcByrefEnumerator : public Object, public reflection::Description<RpcByrefEnumerator>, public reflection::description::IValueEnumerator, public virtual IRpcWrapperBase
|
|
{
|
|
private:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
RpcObjectReference ref;
|
|
vint index = -1;
|
|
public:
|
|
RpcByrefEnumerator(IRpcLifecycle* lc, RpcObjectReference enumeratorRef, IRpcSerializer* _serializer);
|
|
~RpcByrefEnumerator();
|
|
|
|
void DisconnectFromLifecycle()override;
|
|
reflection::description::Value GetCurrent()override;
|
|
vint GetIndex()override;
|
|
bool Next()override;
|
|
};
|
|
|
|
class RpcByrefEnumerable : public Object, public reflection::Description<RpcByrefEnumerable>, public reflection::description::IValueEnumerable, public virtual IRpcWrapperBase
|
|
{
|
|
private:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
RpcObjectReference ref;
|
|
public:
|
|
RpcByrefEnumerable(IRpcLifecycle* lc, RpcObjectReference enumerableRef, IRpcSerializer* _serializer);
|
|
~RpcByrefEnumerable();
|
|
|
|
void DisconnectFromLifecycle()override;
|
|
Ptr<reflection::description::IValueEnumerator> CreateEnumerator()override;
|
|
};
|
|
|
|
class RpcByrefReadonlyList : public Object, public reflection::Description<RpcByrefReadonlyList>, public virtual reflection::description::IValueReadonlyList, public virtual IRpcWrapperBase
|
|
{
|
|
protected:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
RpcObjectReference ref;
|
|
public:
|
|
RpcByrefReadonlyList(IRpcLifecycle* lc, RpcObjectReference listRef, IRpcSerializer* _serializer);
|
|
~RpcByrefReadonlyList();
|
|
|
|
void DisconnectFromLifecycle()override;
|
|
Ptr<reflection::description::IValueEnumerator> CreateEnumerator()override;
|
|
vint GetCount()override;
|
|
reflection::description::Value Get(vint index)override;
|
|
bool Contains(const reflection::description::Value& value)override;
|
|
vint IndexOf(const reflection::description::Value& value)override;
|
|
};
|
|
|
|
class RpcByrefList : public RpcByrefReadonlyList, public reflection::Description<RpcByrefList>, public virtual reflection::description::IValueList
|
|
{
|
|
public:
|
|
RpcByrefList(IRpcLifecycle* lc, RpcObjectReference listRef, IRpcSerializer* _serializer);
|
|
~RpcByrefList()override;
|
|
|
|
Ptr<reflection::description::IValueEnumerator> CreateEnumerator()override;
|
|
vint GetCount()override;
|
|
reflection::description::Value Get(vint index)override;
|
|
bool Contains(const reflection::description::Value& value)override;
|
|
vint IndexOf(const reflection::description::Value& value)override;
|
|
void Set(vint index, const reflection::description::Value& value)override;
|
|
vint Add(const reflection::description::Value& value)override;
|
|
vint Insert(vint index, const reflection::description::Value& value)override;
|
|
bool Remove(const reflection::description::Value& value)override;
|
|
bool RemoveAt(vint index)override;
|
|
void Clear()override;
|
|
};
|
|
|
|
class RpcByrefArray : public Object, public reflection::Description<RpcByrefArray>, public reflection::description::IValueArray, public virtual IRpcWrapperBase
|
|
{
|
|
private:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
RpcObjectReference ref;
|
|
public:
|
|
RpcByrefArray(IRpcLifecycle* lc, RpcObjectReference arrayRef, IRpcSerializer* _serializer);
|
|
~RpcByrefArray();
|
|
|
|
void DisconnectFromLifecycle()override;
|
|
Ptr<reflection::description::IValueEnumerator> CreateEnumerator()override;
|
|
vint GetCount()override;
|
|
reflection::description::Value Get(vint index)override;
|
|
bool Contains(const reflection::description::Value& value)override;
|
|
vint IndexOf(const reflection::description::Value& value)override;
|
|
void Set(vint index, const reflection::description::Value& value)override;
|
|
void Resize(vint size)override;
|
|
};
|
|
|
|
class RpcByrefObservableList : public Object, public reflection::Description<RpcByrefObservableList>, public reflection::description::IValueObservableList, public virtual IRpcWrapperBase
|
|
{
|
|
private:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
RpcObjectReference ref;
|
|
public:
|
|
RpcByrefObservableList(IRpcLifecycle* lc, RpcObjectReference listRef, IRpcSerializer* _serializer);
|
|
~RpcByrefObservableList();
|
|
|
|
void DisconnectFromLifecycle()override;
|
|
Ptr<reflection::description::IValueEnumerator> CreateEnumerator()override;
|
|
vint GetCount()override;
|
|
reflection::description::Value Get(vint index)override;
|
|
bool Contains(const reflection::description::Value& value)override;
|
|
vint IndexOf(const reflection::description::Value& value)override;
|
|
void Set(vint index, const reflection::description::Value& value)override;
|
|
vint Add(const reflection::description::Value& value)override;
|
|
vint Insert(vint index, const reflection::description::Value& value)override;
|
|
bool Remove(const reflection::description::Value& value)override;
|
|
bool RemoveAt(vint index)override;
|
|
void Clear()override;
|
|
};
|
|
|
|
class RpcByrefDictionary : public Object, public reflection::Description<RpcByrefDictionary>, public reflection::description::IValueDictionary, public virtual IRpcWrapperBase
|
|
{
|
|
private:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
RpcObjectReference ref;
|
|
public:
|
|
RpcByrefDictionary(IRpcLifecycle* lc, RpcObjectReference dictRef, IRpcSerializer* _serializer);
|
|
~RpcByrefDictionary();
|
|
|
|
void DisconnectFromLifecycle()override;
|
|
Ptr<reflection::description::IValueReadonlyList> GetKeys()override;
|
|
Ptr<reflection::description::IValueReadonlyList> GetValues()override;
|
|
vint GetCount()override;
|
|
reflection::description::Value Get(const reflection::description::Value& key)override;
|
|
void Set(const reflection::description::Value& key, const reflection::description::Value& value)override;
|
|
bool Remove(const reflection::description::Value& key)override;
|
|
void Clear()override;
|
|
};
|
|
|
|
/***********************************************************************
|
|
* Collection Callee Wrappers
|
|
***********************************************************************/
|
|
|
|
class RpcCalleeListOps : public Object, public IRpcListOps
|
|
{
|
|
private:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
|
|
public:
|
|
RpcCalleeListOps(IRpcLifecycle* lc, IRpcSerializer* _serializer);
|
|
|
|
RpcObjectReference EnumCreate(RpcObjectReference ref)override;
|
|
bool EnumNext(RpcObjectReference enumerator)override;
|
|
reflection::description::Value EnumGetCurrent(RpcObjectReference enumerator)override;
|
|
|
|
vint ListGetCount(RpcObjectReference ref)override;
|
|
reflection::description::Value ListGet(RpcObjectReference ref, vint index)override;
|
|
void ListSet(RpcObjectReference ref, vint index, const reflection::description::Value& value)override;
|
|
vint ListAdd(RpcObjectReference ref, const reflection::description::Value& value)override;
|
|
vint ListInsert(RpcObjectReference ref, vint index, const reflection::description::Value& value)override;
|
|
bool ListRemoveAt(RpcObjectReference ref, vint index)override;
|
|
void ListClear(RpcObjectReference ref)override;
|
|
bool ListContains(RpcObjectReference ref, const reflection::description::Value& value)override;
|
|
vint ListIndexOf(RpcObjectReference ref, const reflection::description::Value& value)override;
|
|
void ArrayResize(RpcObjectReference ref, vint size)override;
|
|
|
|
vint DictGetCount(RpcObjectReference ref)override;
|
|
reflection::description::Value DictGet(RpcObjectReference ref, const reflection::description::Value& key)override;
|
|
void DictSet(RpcObjectReference ref, const reflection::description::Value& key, const reflection::description::Value& value)override;
|
|
bool DictRemove(RpcObjectReference ref, const reflection::description::Value& key)override;
|
|
void DictClear(RpcObjectReference ref)override;
|
|
bool DictContainsKey(RpcObjectReference ref, const reflection::description::Value& key)override;
|
|
RpcObjectReference DictGetKeys(RpcObjectReference ref)override;
|
|
RpcObjectReference DictGetValues(RpcObjectReference ref)override;
|
|
};
|
|
|
|
class RpcCalleeListEventOps : public Object, public IRpcListEventOps
|
|
{
|
|
private:
|
|
IRpcLifecycle* lifecycle = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
|
|
public:
|
|
RpcCalleeListEventOps(IRpcLifecycle* lc, IRpcSerializer* _serializer);
|
|
|
|
reflection::description::Value OnItemChanged(RpcObjectReference ref, vint index, vint oldCount, vint newCount)override;
|
|
};
|
|
|
|
class RpcCalleeObjectOpsForList : public Object, public IRpcObjectOps
|
|
{
|
|
private:
|
|
Ptr<RpcCalleeListOps> listOps;
|
|
Ptr<IRpcObjectOps> objectOps;
|
|
IRpcSerializer* serializer = nullptr;
|
|
|
|
public:
|
|
RpcCalleeObjectOpsForList(Ptr<RpcCalleeListOps> _listOps, Ptr<IRpcObjectOps> _objectOps, IRpcSerializer* _serializer);
|
|
|
|
reflection::description::Value InvokeMethod(RpcObjectReference ref, vint methodId, Ptr<reflection::description::IValueArray> arguments)override;
|
|
void EndInvokeMethod(vint slot)override;
|
|
void ObjectHold(RpcObjectReference ref, vint remoteClientId, bool hold)override;
|
|
};
|
|
|
|
class RpcCalleeObjectEventOpsForList : public Object, public IRpcObjectEventOps
|
|
{
|
|
private:
|
|
Ptr<RpcCalleeListEventOps> listEventOps;
|
|
Ptr<IRpcObjectEventOps> objectEventOps;
|
|
IRpcSerializer* serializer = nullptr;
|
|
|
|
public:
|
|
RpcCalleeObjectEventOpsForList(Ptr<RpcCalleeListEventOps> _listEventOps, Ptr<IRpcObjectEventOps> _objectEventOps, IRpcSerializer* _serializer);
|
|
|
|
reflection::description::Value InvokeEvent(RpcObjectReference ref, vint eventId, Ptr<reflection::description::IValueArray> arguments)override;
|
|
};
|
|
|
|
class RpcCallerListOps : public Object, public IRpcListOps
|
|
{
|
|
private:
|
|
IRpcObjectOps* objectOps = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
|
|
public:
|
|
RpcCallerListOps(IRpcObjectOps* _objectOps, IRpcSerializer* _serializer);
|
|
|
|
RpcObjectReference EnumCreate(RpcObjectReference ref)override;
|
|
bool EnumNext(RpcObjectReference enumerator)override;
|
|
reflection::description::Value EnumGetCurrent(RpcObjectReference enumerator)override;
|
|
|
|
vint ListGetCount(RpcObjectReference ref)override;
|
|
reflection::description::Value ListGet(RpcObjectReference ref, vint index)override;
|
|
void ListSet(RpcObjectReference ref, vint index, const reflection::description::Value& value)override;
|
|
vint ListAdd(RpcObjectReference ref, const reflection::description::Value& value)override;
|
|
vint ListInsert(RpcObjectReference ref, vint index, const reflection::description::Value& value)override;
|
|
bool ListRemoveAt(RpcObjectReference ref, vint index)override;
|
|
void ListClear(RpcObjectReference ref)override;
|
|
bool ListContains(RpcObjectReference ref, const reflection::description::Value& value)override;
|
|
vint ListIndexOf(RpcObjectReference ref, const reflection::description::Value& value)override;
|
|
void ArrayResize(RpcObjectReference ref, vint size)override;
|
|
|
|
vint DictGetCount(RpcObjectReference ref)override;
|
|
reflection::description::Value DictGet(RpcObjectReference ref, const reflection::description::Value& key)override;
|
|
void DictSet(RpcObjectReference ref, const reflection::description::Value& key, const reflection::description::Value& value)override;
|
|
bool DictRemove(RpcObjectReference ref, const reflection::description::Value& key)override;
|
|
void DictClear(RpcObjectReference ref)override;
|
|
bool DictContainsKey(RpcObjectReference ref, const reflection::description::Value& key)override;
|
|
RpcObjectReference DictGetKeys(RpcObjectReference ref)override;
|
|
RpcObjectReference DictGetValues(RpcObjectReference ref)override;
|
|
};
|
|
|
|
class RpcCallerListEventOps : public Object, public IRpcListEventOps
|
|
{
|
|
private:
|
|
IRpcObjectEventOps* objectEventOps = nullptr;
|
|
IRpcSerializer* serializer = nullptr;
|
|
|
|
public:
|
|
RpcCallerListEventOps(IRpcObjectEventOps* _objectEventOps, IRpcSerializer* _serializer);
|
|
|
|
reflection::description::Value OnItemChanged(RpcObjectReference ref, vint index, vint oldCount, vint newCount)override;
|
|
};
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPCJSON\WFLIBRARYRPCJSON.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::RPC
|
|
|
|
JSON Helpers:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_JSON
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC_JSON
|
|
|
|
|
|
namespace vl
|
|
{
|
|
namespace rpc_controller
|
|
{
|
|
class RpcCalleeListOps;
|
|
class RpcCalleeListEventOps;
|
|
class RpcCalleeObjectOpsForList;
|
|
class RpcCalleeObjectEventOpsForList;
|
|
|
|
using RpcJsonSerializeCallback = Func<Ptr<glr::json::JsonNode>(const reflection::description::Value&)>;
|
|
using RpcJsonDeserializeCallback = Func<reflection::description::Value(Ptr<glr::json::JsonNode>)>;
|
|
|
|
extern Ptr<glr::json::JsonNode> JsonSerializePredefinedTypes(const reflection::description::Value& value, const RpcJsonSerializeCallback& rpcjson_Serialize);
|
|
extern reflection::description::Value JsonDeserializePredefinedTypes(const reflection::description::Value& value, const RpcJsonDeserializeCallback& rpcjson_Deserialize);
|
|
|
|
class IRpcJsonMessageDispatcher
|
|
: public virtual reflection::IDescriptable
|
|
, public reflection::Description<IRpcJsonMessageDispatcher>
|
|
{
|
|
public:
|
|
enum class RequestType
|
|
{
|
|
Direct,
|
|
Broadcast,
|
|
BroadcastAndDrop,
|
|
};
|
|
|
|
virtual vint AllocateRequestId() = 0;
|
|
virtual Ptr<glr::json::JsonNode> OnJsonRequest(Ptr<glr::json::JsonNode> message, RequestType requestType) = 0;
|
|
|
|
static Ptr<glr::json::JsonNode> DefaultTranslate(
|
|
Ptr<glr::json::JsonNode> message,
|
|
RequestType requestType,
|
|
IRpcObjectOps* objectOps,
|
|
IRpcObjectEventOps* objectEventOps,
|
|
IRpcDispatcher* dispatcher,
|
|
IRpcLifecycle* lifecycle
|
|
);
|
|
};
|
|
|
|
class RpcJsonObjectOps : public Object, public IRpcObjectOps
|
|
{
|
|
private:
|
|
vint sourceClientId = RpcClientId_Invalid;
|
|
vint targetClientId = RpcClientId_Invalid;
|
|
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
|
|
|
public:
|
|
RpcJsonObjectOps(IRpcJsonMessageDispatcher* _dispatcher);
|
|
RpcJsonObjectOps(vint _sourceClientId, vint _targetClientId, IRpcJsonMessageDispatcher* _dispatcher);
|
|
~RpcJsonObjectOps();
|
|
|
|
reflection::description::Value InvokeMethod(RpcObjectReference ref, vint methodId, Ptr<reflection::description::IValueArray> arguments)override;
|
|
void EndInvokeMethod(vint slot)override;
|
|
void ObjectHold(RpcObjectReference ref, vint remoteClientId, bool hold)override;
|
|
|
|
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcObjectOps* ops, IRpcLifecycle* lifecycle = nullptr);
|
|
};
|
|
|
|
class RpcJsonObjectEventOps : public Object, public IRpcObjectEventOps
|
|
{
|
|
private:
|
|
vint sourceClientId = RpcClientId_Invalid;
|
|
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
|
|
|
public:
|
|
RpcJsonObjectEventOps(IRpcJsonMessageDispatcher* _dispatcher);
|
|
RpcJsonObjectEventOps(vint _sourceClientId, IRpcJsonMessageDispatcher* _dispatcher);
|
|
~RpcJsonObjectEventOps();
|
|
|
|
reflection::description::Value InvokeEvent(RpcObjectReference ref, vint eventId, Ptr<reflection::description::IValueArray> arguments)override;
|
|
|
|
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcObjectEventOps* ops, IRpcLifecycle* lifecycle = nullptr);
|
|
};
|
|
|
|
class RpcJsonDispatcher : public Object, public IRpcDispatcher
|
|
{
|
|
private:
|
|
vint sourceClientId = RpcClientId_Invalid;
|
|
IRpcJsonMessageDispatcher* dispatcher = nullptr;
|
|
Ptr<RpcJsonObjectEventOps> objectEventOps;
|
|
collections::Dictionary<vint, Ptr<RpcJsonObjectOps>> objectOps;
|
|
|
|
public:
|
|
RpcJsonDispatcher(vint _sourceClientId, IRpcJsonMessageDispatcher* _dispatcher);
|
|
|
|
void Finalize()override;
|
|
void Initialize()override;
|
|
void DeclareLocalService(RpcObjectReference ref)override;
|
|
IRpcObjectEventOps* BroadcastFromClient_ObjectEventOps(vint selfClientId)override;
|
|
IRpcObjectOps* SendToClient_ObjectOps(vint targetClientId)override;
|
|
|
|
static Ptr<glr::json::JsonNode> Translate(Ptr<glr::json::JsonNode> message, IRpcDispatcher* dispatcher, IRpcLifecycle* lifecycle);
|
|
};
|
|
|
|
class RpcJsonLifecycle : public RpcLifecycleBase
|
|
{
|
|
private:
|
|
RpcJsonDispatcher* dispatcher = nullptr;
|
|
Func<vint(reflection::IDescriptable*)> getTypeId;
|
|
Func<void(RpcObjectReference, reflection::IDescriptable*)> eventAttacher;
|
|
Ptr<RpcCalleeListOps> listOps;
|
|
Ptr<RpcCalleeListEventOps> listEventOps;
|
|
Ptr<RpcCalleeObjectOpsForList> objectOpsForList;
|
|
Ptr<RpcCalleeObjectEventOpsForList> objectEventOpsForList;
|
|
|
|
protected:
|
|
vint DecideTypeId(reflection::IDescriptable* obj)const override;
|
|
void AttachLocalObjectEvents(RpcObjectReference ref, reflection::IDescriptable* obj)override;
|
|
|
|
public:
|
|
RpcJsonLifecycle(vint _clientId, RpcJsonDispatcher* _dispatcher);
|
|
|
|
void Register(
|
|
Ptr<IRpcSerializer> _serializer,
|
|
Ptr<IRpcObjectOps> _objectOps,
|
|
Ptr<IRpcObjectEventOps> _objectEventOps,
|
|
Func<vint(reflection::IDescriptable*)> _getTypeId,
|
|
Func<void(RpcObjectReference, reflection::IDescriptable*)> _eventAttacher
|
|
);
|
|
IRpcSerializer* GetSerializer()override;
|
|
IRpcDispatcher* GetDispatcher()override;
|
|
};
|
|
|
|
extern vint ReadRequestId(Ptr<glr::json::JsonNode> message);
|
|
extern void WriteRequestId(Ptr<glr::json::JsonNode> message, vint requestId);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\WFLIBRARYREFLECTION.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
Framework::Reflection
|
|
|
|
Interfaces:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_REFLECTION
|
|
#define VCZH_WORKFLOW_LIBRARY_REFLECTION
|
|
|
|
|
|
namespace vl
|
|
{
|
|
namespace reflection
|
|
{
|
|
namespace description
|
|
{
|
|
|
|
/***********************************************************************
|
|
Predefined Types
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_DEBUG_NO_REFLECTION
|
|
|
|
#define WORKFLOW_LIBRARY_ATTRIBUTE_TYPES(F)\
|
|
F(vl::__vwsn::att_cpp_File)\
|
|
F(vl::__vwsn::att_cpp_UserImpl)\
|
|
F(vl::__vwsn::att_cpp_Private)\
|
|
F(vl::__vwsn::att_cpp_Protected)\
|
|
F(vl::__vwsn::att_cpp_Friend)\
|
|
F(vl::__vwsn::att_rpc_Interface)\
|
|
F(vl::__vwsn::att_rpc_Ctor)\
|
|
F(vl::__vwsn::att_rpc_Byval)\
|
|
F(vl::__vwsn::att_rpc_Byref)\
|
|
F(vl::__vwsn::att_rpc_Cached)\
|
|
F(vl::__vwsn::att_rpc_Dynamic)\
|
|
F(vl::__vwsn::att_rpc_IdString)\
|
|
F(vl::__vwsn::att_rpc_IdNumber)\
|
|
|
|
#define WORKFLOW_LIBRARY_TYPES(F)\
|
|
F(Sys) \
|
|
F(Math) \
|
|
F(Localization) \
|
|
F(CoroutineStatus) \
|
|
F(CoroutineResult) \
|
|
F(ICoroutine) \
|
|
F(EnumerableCoroutine::IImpl) \
|
|
F(EnumerableCoroutine) \
|
|
F(AsyncStatus) \
|
|
F(AsyncContext) \
|
|
F(IAsync) \
|
|
F(IPromise) \
|
|
F(IFuture) \
|
|
F(IAsyncScheduler) \
|
|
F(AsyncCoroutine::IImpl) \
|
|
F(AsyncCoroutine) \
|
|
F(StateMachine) \
|
|
F(Versioning) \
|
|
F(vl::rpc_controller::RpcObjectReference)\
|
|
F(vl::rpc_controller::RpcException)\
|
|
F(vl::rpc_controller::RpcByvalReturnValue)\
|
|
F(vl::rpc_controller::IRpcSerializer)\
|
|
F(vl::rpc_controller::IRpcJsonMessageDispatcher::RequestType)\
|
|
F(vl::rpc_controller::IRpcJsonMessageDispatcher)\
|
|
F(vl::rpc_controller::IRpcListOps)\
|
|
F(vl::rpc_controller::IRpcListEventOps)\
|
|
F(vl::rpc_controller::IRpcObjectOps)\
|
|
F(vl::rpc_controller::IRpcObjectEventOps)\
|
|
F(vl::rpc_controller::IRpcOperations)\
|
|
F(vl::rpc_controller::IRpcDispatcher)\
|
|
F(vl::rpc_controller::IRpcController)\
|
|
F(vl::rpc_controller::IRpcLifecycle)\
|
|
F(vl::rpc_controller::IRpcWrapperBase)\
|
|
F(vl::rpc_controller::RpcByrefEnumerator)\
|
|
F(vl::rpc_controller::RpcByrefEnumerable)\
|
|
F(vl::rpc_controller::RpcByrefReadonlyList)\
|
|
F(vl::rpc_controller::RpcByrefList)\
|
|
F(vl::rpc_controller::RpcByrefArray)\
|
|
F(vl::rpc_controller::RpcByrefObservableList)\
|
|
F(vl::rpc_controller::RpcByrefDictionary)\
|
|
WORKFLOW_LIBRARY_ATTRIBUTE_TYPES(F)\
|
|
|
|
WORKFLOW_LIBRARY_TYPES(DECL_TYPE_INFO)
|
|
|
|
#endif
|
|
|
|
/***********************************************************************
|
|
Interface Implementation Proxy (Implement)
|
|
***********************************************************************/
|
|
|
|
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4250)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcSerializer)
|
|
vl::reflection::description::Value Serialize(const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(Serialize, value);
|
|
}
|
|
|
|
vl::reflection::description::Value Deserialize(const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(Deserialize, value);
|
|
}
|
|
END_INTERFACE_PROXY(vl::rpc_controller::IRpcSerializer)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcJsonMessageDispatcher)
|
|
vl::vint AllocateRequestId()override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY_NOPARAMS(AllocateRequestId);
|
|
}
|
|
|
|
vl::Ptr<vl::glr::json::JsonNode> OnJsonRequest(vl::Ptr<vl::glr::json::JsonNode> message, vl::rpc_controller::IRpcJsonMessageDispatcher::RequestType requestType)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(OnJsonRequest, message, requestType);
|
|
}
|
|
END_INTERFACE_PROXY(vl::rpc_controller::IRpcJsonMessageDispatcher)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcListOps)
|
|
vl::rpc_controller::RpcObjectReference EnumCreate(vl::rpc_controller::RpcObjectReference ref)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(EnumCreate, ref);
|
|
}
|
|
|
|
bool EnumNext(vl::rpc_controller::RpcObjectReference enumerator)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(EnumNext, enumerator);
|
|
}
|
|
|
|
vl::reflection::description::Value EnumGetCurrent(vl::rpc_controller::RpcObjectReference enumerator)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(EnumGetCurrent, enumerator);
|
|
}
|
|
|
|
vl::vint ListGetCount(vl::rpc_controller::RpcObjectReference ref)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(ListGetCount, ref);
|
|
}
|
|
|
|
vl::reflection::description::Value ListGet(vl::rpc_controller::RpcObjectReference ref, vl::vint index)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(ListGet, ref, index);
|
|
}
|
|
|
|
void ListSet(vl::rpc_controller::RpcObjectReference ref, vl::vint index, const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(ListSet, ref, index, value);
|
|
}
|
|
|
|
vl::vint ListAdd(vl::rpc_controller::RpcObjectReference ref, const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(ListAdd, ref, value);
|
|
}
|
|
|
|
vl::vint ListInsert(vl::rpc_controller::RpcObjectReference ref, vl::vint index, const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(ListInsert, ref, index, value);
|
|
}
|
|
|
|
bool ListRemoveAt(vl::rpc_controller::RpcObjectReference ref, vl::vint index)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(ListRemoveAt, ref, index);
|
|
}
|
|
|
|
void ListClear(vl::rpc_controller::RpcObjectReference ref)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(ListClear, ref);
|
|
}
|
|
|
|
bool ListContains(vl::rpc_controller::RpcObjectReference ref, const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(ListContains, ref, value);
|
|
}
|
|
|
|
vl::vint ListIndexOf(vl::rpc_controller::RpcObjectReference ref, const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(ListIndexOf, ref, value);
|
|
}
|
|
|
|
void ArrayResize(vl::rpc_controller::RpcObjectReference ref, vl::vint size)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(ArrayResize, ref, size);
|
|
}
|
|
|
|
vl::vint DictGetCount(vl::rpc_controller::RpcObjectReference ref)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(DictGetCount, ref);
|
|
}
|
|
|
|
vl::reflection::description::Value DictGet(vl::rpc_controller::RpcObjectReference ref, const vl::reflection::description::Value& key)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(DictGet, ref, key);
|
|
}
|
|
|
|
void DictSet(vl::rpc_controller::RpcObjectReference ref, const vl::reflection::description::Value& key, const vl::reflection::description::Value& value)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(DictSet, ref, key, value);
|
|
}
|
|
|
|
bool DictRemove(vl::rpc_controller::RpcObjectReference ref, const vl::reflection::description::Value& key)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(DictRemove, ref, key);
|
|
}
|
|
|
|
void DictClear(vl::rpc_controller::RpcObjectReference ref)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(DictClear, ref);
|
|
}
|
|
|
|
bool DictContainsKey(vl::rpc_controller::RpcObjectReference ref, const vl::reflection::description::Value& key)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(DictContainsKey, ref, key);
|
|
}
|
|
|
|
vl::rpc_controller::RpcObjectReference DictGetKeys(vl::rpc_controller::RpcObjectReference ref)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(DictGetKeys, ref);
|
|
}
|
|
|
|
vl::rpc_controller::RpcObjectReference DictGetValues(vl::rpc_controller::RpcObjectReference ref)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(DictGetValues, ref);
|
|
}
|
|
END_INTERFACE_PROXY(vl::rpc_controller::IRpcListOps)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcObjectOps)
|
|
vl::reflection::description::Value InvokeMethod(vl::rpc_controller::RpcObjectReference ref, vl::vint methodId, vl::Ptr<vl::reflection::description::IValueArray> arguments)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(InvokeMethod, ref, methodId, arguments);
|
|
}
|
|
|
|
void EndInvokeMethod(vl::vint slot)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(EndInvokeMethod, slot);
|
|
}
|
|
|
|
void ObjectHold(vl::rpc_controller::RpcObjectReference ref, vl::vint remoteClientId, bool hold)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(ObjectHold, ref, remoteClientId, hold);
|
|
}
|
|
|
|
END_INTERFACE_PROXY(vl::rpc_controller::IRpcObjectOps)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcListEventOps)
|
|
vl::reflection::description::Value OnItemChanged(vl::rpc_controller::RpcObjectReference ref, vl::vint index, vl::vint oldCount, vl::vint newCount)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(OnItemChanged, ref, index, oldCount, newCount);
|
|
}
|
|
END_INTERFACE_PROXY(vl::rpc_controller::IRpcListEventOps)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcObjectEventOps)
|
|
vl::reflection::description::Value InvokeEvent(vl::rpc_controller::RpcObjectReference ref, vl::vint eventId, vl::Ptr<vl::reflection::description::IValueArray> arguments)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(InvokeEvent, ref, eventId, arguments);
|
|
}
|
|
END_INTERFACE_PROXY(vl::rpc_controller::IRpcObjectEventOps)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(vl::rpc_controller::IRpcWrapperBase)
|
|
void DisconnectFromLifecycle()override
|
|
{
|
|
INVOKE_INTERFACE_PROXY_NOPARAMS(DisconnectFromLifecycle);
|
|
}
|
|
END_INTERFACE_PROXY(vl::rpc_controller::IRpcWrapperBase)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(ICoroutine)
|
|
|
|
void Resume(bool raiseException, Ptr<CoroutineResult> output)override
|
|
{
|
|
INVOKE_INTERFACE_PROXY(Resume, raiseException, output);
|
|
}
|
|
|
|
Ptr<IValueException> GetFailure()override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY_NOPARAMS(GetFailure);
|
|
}
|
|
|
|
CoroutineStatus GetStatus()override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY_NOPARAMS(GetStatus);
|
|
}
|
|
END_INTERFACE_PROXY(ICoroutine)
|
|
|
|
BEGIN_INTERFACE_PROXY_NOPARENT_SHAREDPTR(IAsync)
|
|
|
|
AsyncStatus GetStatus()override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY_NOPARAMS(GetStatus);
|
|
}
|
|
|
|
bool Execute(const Func<void(Ptr<CoroutineResult>)>& callback, Ptr<AsyncContext> context)override
|
|
{
|
|
INVOKEGET_INTERFACE_PROXY(Execute, callback, context);
|
|
}
|
|
END_INTERFACE_PROXY(IAsync)
|
|
|
|
#pragma warning(pop)
|
|
|
|
#endif
|
|
|
|
/***********************************************************************
|
|
LoadPredefinedTypes
|
|
***********************************************************************/
|
|
|
|
extern bool WfLoadLibraryTypes();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPCJSON\WFLIBRARYRPCJSONDISPATCHERSHARED.H
|
|
***********************************************************************/
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_JSON_DISPATCHER_SHARED
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC_JSON_DISPATCHER_SHARED
|
|
|
|
|
|
namespace vl::rpc_controller::channeling
|
|
{
|
|
using JsonPackage = vl::Ptr<vl::glr::json::JsonNode>;
|
|
using JsonChannel = vl::inter_process::IChannel<JsonPackage>;
|
|
using JsonChannelClient = vl::inter_process::IChannelClient<JsonPackage>;
|
|
using JsonChannelServer = vl::inter_process::IChannelServer<JsonPackage>;
|
|
using JsonNetworkChannelClient = vl::inter_process::NetworkProtocolChannelClient<JsonPackage, vl::glr::json::JsonNodeListSerializer>;
|
|
using JsonLocalChannelClient = vl::inter_process::NetworkProtocolLocalChannelClient<JsonPackage, vl::glr::json::JsonNodeListSerializer>;
|
|
template<typename TServerBase>
|
|
using JsonNetworkChannelServer = vl::inter_process::NetworkProtocolChannelServer<JsonPackage, vl::glr::json::JsonNodeListSerializer, TServerBase>;
|
|
using TaskQueue = vl::TaskQueue;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPCJSON\WFLIBRARYRPCJSONDISPATCHERCLIENT.H
|
|
***********************************************************************/
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_JSON_DISPATCHER_CLIENT
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC_JSON_DISPATCHER_CLIENT
|
|
|
|
|
|
namespace vl::rpc_controller::channeling
|
|
{
|
|
/// <summary>
|
|
/// A IChannelReader for hosting and connecting RPC services
|
|
/// </summary>
|
|
class RpcJsonDispatcherClient
|
|
: public vl::Object
|
|
, public virtual vl::rpc_controller::IRpcJsonMessageDispatcher
|
|
, public virtual vl::inter_process::IChannelReader<JsonPackage>
|
|
{
|
|
protected:
|
|
using RequestType = vl::rpc_controller::IRpcJsonMessageDispatcher::RequestType;
|
|
|
|
private:
|
|
struct ReceivedJsonMessage
|
|
{
|
|
vl::vint senderClientId = -1;
|
|
JsonPackage message;
|
|
};
|
|
|
|
JsonChannel* rpcChannel = nullptr;
|
|
vl::atomic_vint nextRequestId = 0;
|
|
vl::atomic_vint activeJsonRequests = 0;
|
|
vl::atomic_vint initialized = 0;
|
|
vl::atomic_vint serverLocalClientId = -1;
|
|
vl::Ptr<vl::rpc_controller::RpcJsonDispatcher> rpcDispatcher;
|
|
vl::Ptr<vl::rpc_controller::RpcJsonLifecycle> lifecycle;
|
|
|
|
// covers messages and bufferedResponses
|
|
vl::SpinLock lockMessages;
|
|
vl::Semaphore semaphoreMessages;
|
|
vl::collections::List<ReceivedJsonMessage> messages;
|
|
vl::collections::List<ReceivedJsonMessage> bufferedResponses;
|
|
|
|
// covers cachedIncomingServiceDeclarations and cachedOutgoingServiceDeclarations
|
|
vl::SpinLock lockServiceDeclarations;
|
|
vl::collections::List<JsonPackage> cachedIncomingServiceDeclarations;
|
|
vl::collections::List<JsonPackage> cachedOutgoingServiceDeclarations;
|
|
|
|
// covers waitingForServices
|
|
vl::SpinLock lockWaitingForServices;
|
|
vl::collections::List<vl::WString> waitingForServices;
|
|
vl::EventObject eventWaitingForServices;
|
|
bool eventWaitingForServicesCreated = false;
|
|
vl::EventObject eventServerLocalClientId;
|
|
|
|
void PrepareConnection(JsonChannel* channel, const vl::collections::List<vl::WString>& _waitingForServices);
|
|
void ProcessCachedIncomingServiceDeclarations();
|
|
void SendCachedOutgoingServiceDeclarations();
|
|
void ProcessIncomingServiceDeclaration(JsonPackage request);
|
|
void UpdateWaitingForServices(JsonPackage request);
|
|
void WaitForServerClientId();
|
|
void WaitForExpectedServices();
|
|
void SendJsonRequest(JsonPackage message, RequestType requestType);
|
|
void PushReceivedMessage(vl::vint senderClientId, JsonPackage message);
|
|
ReceivedJsonMessage PopReceivedMessage();
|
|
bool TryPopBufferedResponse(vl::vint requestId, ReceivedJsonMessage& message);
|
|
void PushBufferedResponse(ReceivedJsonMessage message);
|
|
void SendJsonResponse(vl::vint receiverClientId, JsonPackage response);
|
|
void FlushChannel();
|
|
void ProcessRequestAndSendResponse(vl::vint senderClientId, JsonPackage request);
|
|
JsonPackage TranslateRequest(JsonPackage request);
|
|
|
|
protected:
|
|
virtual void ScheduleTask(vl::Func<void()> task) = 0;
|
|
void SetRpcObjects(vl::Ptr<vl::rpc_controller::RpcJsonDispatcher> _rpcDispatcher, vl::Ptr<vl::rpc_controller::RpcJsonLifecycle> _lifecycle);
|
|
vl::rpc_controller::RpcJsonLifecycle* GetRpcJsonLifecycle();
|
|
|
|
public:
|
|
RpcJsonDispatcherClient();
|
|
|
|
void WaitForServer(JsonChannelClient* channelClient, JsonChannel* channel, const vl::collections::List<vl::WString>& _waitingForServices);
|
|
vl::vint ConnectLocalServer(JsonChannelServer* channelServer, vl::Ptr<JsonChannelClient> localClient, JsonChannel* channel, const vl::collections::List<vl::WString>& _waitingForServices);
|
|
void Initialize();
|
|
vl::rpc_controller::IRpcLifecycle* GetRpcLifecycle();
|
|
vl::rpc_controller::IRpcDispatcher* GetRpcDispatcher();
|
|
void SetServerLocalClientId(vl::vint clientId);
|
|
void NotifyServerClientDisconnected();
|
|
|
|
vl::vint AllocateRequestId() override;
|
|
JsonPackage OnJsonRequest(JsonPackage message, RequestType requestType) override;
|
|
void OnRead(vl::vint senderClientId, const JsonPackage& package) override;
|
|
|
|
virtual void FinalizeRpc();
|
|
};
|
|
|
|
class RpcJsonDispatcherClientForTaskQueue : public RpcJsonDispatcherClient
|
|
{
|
|
private:
|
|
vl::Ptr<TaskQueue> taskQueue;
|
|
|
|
protected:
|
|
void ScheduleTask(vl::Func<void()> task) override;
|
|
|
|
public:
|
|
RpcJsonDispatcherClientForTaskQueue(vl::Ptr<TaskQueue> _taskQueue);
|
|
};
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\RPCJSON\WFLIBRARYRPCJSONDISPATCHERSERVER.H
|
|
***********************************************************************/
|
|
#ifndef VCZH_WORKFLOW_LIBRARY_RPC_JSON_DISPATCHER_SERVER
|
|
#define VCZH_WORKFLOW_LIBRARY_RPC_JSON_DISPATCHER_SERVER
|
|
|
|
|
|
namespace vl::rpc_controller::channeling
|
|
{
|
|
/// <summary>
|
|
/// A IChannelReader for RPC service delivering and request broadcasting
|
|
/// </summary>
|
|
class RpcJsonDispatcherServer
|
|
: public vl::Object
|
|
, public virtual vl::inter_process::IChannelReader<JsonPackage>
|
|
{
|
|
public:
|
|
struct PendingBroadcast : public vl::Object
|
|
{
|
|
vl::vint originalClientId = -1;
|
|
vl::vint originalRequestId = -1;
|
|
vl::vint redirectedRequestId = -1;
|
|
bool hasNonNullResponse = false;
|
|
vl::collections::List<vl::vint> expectedClientIds;
|
|
vl::collections::Dictionary<vl::vint, JsonPackage> responses;
|
|
};
|
|
|
|
struct CompletedBroadcast
|
|
{
|
|
vl::vint originalClientId = -1;
|
|
JsonPackage response;
|
|
};
|
|
|
|
private:
|
|
JsonChannel* rpcChannel = nullptr;
|
|
JsonChannelClient* serverClient = nullptr;
|
|
vl::atomic_vint nextRequestId = 0;
|
|
|
|
// covers connectedClientIds, pendingBroadcasts, redirectedBroadcasts and cachedServiceDeclarations
|
|
vl::SpinLock lockBroadcasts;
|
|
vl::collections::SortedList<vl::vint> connectedClientIds;
|
|
vl::collections::Dictionary<vl::WString, vl::Ptr<PendingBroadcast>> pendingBroadcasts;
|
|
vl::collections::Dictionary<vl::vint, vl::WString> redirectedBroadcasts;
|
|
vl::collections::List<JsonPackage> cachedServiceDeclarations;
|
|
|
|
vl::vint AllocateRequestId();
|
|
vl::WString MakeBroadcastKey(vl::vint clientId, vl::vint requestId);
|
|
JsonPackage CreateBroadcastResponse(vl::vint sourceClientId, vl::vint targetClientId, vl::vint requestId, vl::Ptr<PendingBroadcast> pending);
|
|
CompletedBroadcast CompleteBroadcastLocked(const vl::WString& key);
|
|
void DeliverCompletedBroadcast(const CompletedBroadcast& completed);
|
|
JsonPackage StartBroadcast(vl::vint originalClientId, vl::vint originalRequestId, JsonPackage message);
|
|
void StartBroadcastAndDrop(vl::vint originalClientId, JsonPackage message);
|
|
bool TryHandleBroadcastResponse(vl::vint senderClientId, JsonPackage response);
|
|
void HandleServiceDeclaration(vl::vint senderClientId, JsonPackage request);
|
|
void SendLoginMessages(vl::vint clientId);
|
|
void SendJsonResponse(vl::vint receiverClientId, JsonPackage response);
|
|
void FlushChannel();
|
|
|
|
protected:
|
|
virtual void ScheduleTask(vl::Func<void()> task) = 0;
|
|
|
|
public:
|
|
RpcJsonDispatcherServer(JsonChannelClient* _serverClient, JsonChannel* channel);
|
|
|
|
bool HasServerClientId();
|
|
void RegisterClient(vl::vint clientId);
|
|
void DisconnectClient(vl::vint clientId);
|
|
vl::vint GetServerClientId();
|
|
void OnRead(vl::vint senderClientId, const JsonPackage& package) override;
|
|
};
|
|
|
|
class RpcJsonDispatcherServerForTaskQueue : public RpcJsonDispatcherServer
|
|
{
|
|
private:
|
|
vl::Ptr<TaskQueue> taskQueue;
|
|
|
|
protected:
|
|
void ScheduleTask(vl::Func<void()> task) override;
|
|
|
|
public:
|
|
RpcJsonDispatcherServerForTaskQueue(JsonChannelClient* _serverClient, JsonChannel* channel, vl::Ptr<TaskQueue> _taskQueue);
|
|
};
|
|
}
|
|
|
|
#endif
|
|
|