mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-02-05 19:40:03 +08:00
1250 lines
34 KiB
C++
1250 lines
34 KiB
C++
/***********************************************************************
|
|
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
|
|
DEVELOPER: Zihan Chen(vczh)
|
|
***********************************************************************/
|
|
#include "VlppWorkflowLibrary.h"
|
|
|
|
/***********************************************************************
|
|
.\WFLIBRARYCPPHELPER.CPP
|
|
***********************************************************************/
|
|
|
|
namespace vl
|
|
{
|
|
namespace __vwsn
|
|
{
|
|
|
|
/***********************************************************************
|
|
CreateArray
|
|
***********************************************************************/
|
|
|
|
CreateArray::CreateArray()
|
|
:list(IValueArray::Create())
|
|
{
|
|
}
|
|
|
|
CreateArray::CreateArray(Ptr<IValueArray> _list)
|
|
:list(_list)
|
|
{
|
|
}
|
|
|
|
/***********************************************************************
|
|
CreateList
|
|
***********************************************************************/
|
|
|
|
CreateList::CreateList()
|
|
:list(IValueList::Create())
|
|
{
|
|
}
|
|
|
|
CreateList::CreateList(Ptr<IValueList> _list)
|
|
:list(_list)
|
|
{
|
|
}
|
|
|
|
/***********************************************************************
|
|
CreateObservableList
|
|
***********************************************************************/
|
|
|
|
CreateObservableList::CreateObservableList()
|
|
:list(IValueObservableList::Create())
|
|
{
|
|
}
|
|
|
|
CreateObservableList::CreateObservableList(Ptr<IValueObservableList> _list)
|
|
:list(_list)
|
|
{
|
|
}
|
|
|
|
/***********************************************************************
|
|
CreateDictionary
|
|
***********************************************************************/
|
|
|
|
CreateDictionary::CreateDictionary()
|
|
:dictionary(IValueDictionary::Create())
|
|
{
|
|
}
|
|
|
|
CreateDictionary::CreateDictionary(Ptr<IValueDictionary> _dictionary)
|
|
:dictionary(_dictionary)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
.\WFLIBRARYPREDEFINED.CPP
|
|
***********************************************************************/
|
|
|
|
namespace vl
|
|
{
|
|
using namespace collections;
|
|
|
|
namespace reflection
|
|
{
|
|
namespace description
|
|
{
|
|
|
|
/***********************************************************************
|
|
CoroutineResult
|
|
***********************************************************************/
|
|
|
|
Value CoroutineResult::GetResult()
|
|
{
|
|
return result;
|
|
}
|
|
|
|
void CoroutineResult::SetResult(const Value& value)
|
|
{
|
|
result = value;
|
|
}
|
|
|
|
Ptr<IValueException> CoroutineResult::GetFailure()
|
|
{
|
|
return failure;
|
|
}
|
|
|
|
void CoroutineResult::SetFailure(Ptr<IValueException> value)
|
|
{
|
|
failure = value;
|
|
}
|
|
|
|
/***********************************************************************
|
|
EnumerableCoroutine
|
|
***********************************************************************/
|
|
|
|
class CoroutineEnumerator : public Object, public virtual EnumerableCoroutine::IImpl, public Description<CoroutineEnumerator>
|
|
{
|
|
protected:
|
|
EnumerableCoroutine::Creator creator;
|
|
Ptr<ICoroutine> coroutine;
|
|
Value current;
|
|
vint index = -1;
|
|
Ptr<IValueEnumerator> joining;
|
|
|
|
public:
|
|
CoroutineEnumerator(const EnumerableCoroutine::Creator& _creator)
|
|
:creator(_creator)
|
|
{
|
|
}
|
|
|
|
Value GetCurrent()override
|
|
{
|
|
return current;
|
|
}
|
|
|
|
vint GetIndex()override
|
|
{
|
|
return index;
|
|
}
|
|
|
|
bool Next()override
|
|
{
|
|
if (!coroutine)
|
|
{
|
|
coroutine = creator(this);
|
|
}
|
|
|
|
while (coroutine->GetStatus() == CoroutineStatus::Waiting)
|
|
{
|
|
if (joining)
|
|
{
|
|
if (joining->Next())
|
|
{
|
|
current = joining->GetCurrent();
|
|
index++;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
joining = nullptr;
|
|
}
|
|
}
|
|
|
|
coroutine->Resume(true, nullptr);
|
|
if (coroutine->GetStatus() != CoroutineStatus::Waiting)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (!joining)
|
|
{
|
|
index++;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void OnYield(const Value& value)override
|
|
{
|
|
current = value;
|
|
joining = nullptr;
|
|
}
|
|
|
|
void OnJoin(Ptr<IValueEnumerable> value)override
|
|
{
|
|
if (!value)
|
|
{
|
|
throw Exception(L"Cannot join a null collection.");
|
|
}
|
|
current = Value();
|
|
joining = value->CreateEnumerator();
|
|
}
|
|
};
|
|
|
|
class CoroutineEnumerable : public Object, public virtual IValueEnumerable, public Description<CoroutineEnumerable>
|
|
{
|
|
protected:
|
|
EnumerableCoroutine::Creator creator;
|
|
|
|
public:
|
|
CoroutineEnumerable(const EnumerableCoroutine::Creator& _creator)
|
|
:creator(_creator)
|
|
{
|
|
}
|
|
|
|
Ptr<IValueEnumerator> CreateEnumerator()override
|
|
{
|
|
return Ptr(new CoroutineEnumerator(creator));
|
|
}
|
|
};
|
|
|
|
void EnumerableCoroutine::YieldAndPause(IImpl* impl, const Value& value)
|
|
{
|
|
impl->OnYield(value);
|
|
}
|
|
|
|
void EnumerableCoroutine::JoinAndPause(IImpl* impl, Ptr<IValueEnumerable> value)
|
|
{
|
|
impl->OnJoin(value);
|
|
}
|
|
|
|
void EnumerableCoroutine::ReturnAndExit(IImpl* impl)
|
|
{
|
|
}
|
|
|
|
Ptr<IValueEnumerable> EnumerableCoroutine::Create(const Creator& creator)
|
|
{
|
|
return Ptr(new CoroutineEnumerable(creator));
|
|
}
|
|
|
|
/***********************************************************************
|
|
AsyncContext
|
|
***********************************************************************/
|
|
|
|
AsyncContext::AsyncContext(const Value& _context)
|
|
:context(_context)
|
|
{
|
|
}
|
|
|
|
AsyncContext::~AsyncContext()
|
|
{
|
|
}
|
|
|
|
bool AsyncContext::IsCancelled()
|
|
{
|
|
SPIN_LOCK(lock)
|
|
{
|
|
return cancelled;
|
|
}
|
|
CHECK_FAIL(L"Not reachable");
|
|
}
|
|
|
|
bool AsyncContext::Cancel()
|
|
{
|
|
SPIN_LOCK(lock)
|
|
{
|
|
if (cancelled) return false;
|
|
cancelled = true;
|
|
return true;
|
|
}
|
|
CHECK_FAIL(L"Not reachable");
|
|
}
|
|
|
|
const description::Value& AsyncContext::GetContext()
|
|
{
|
|
SPIN_LOCK(lock)
|
|
{
|
|
return context;
|
|
}
|
|
CHECK_FAIL(L"Not reachable");
|
|
}
|
|
|
|
void AsyncContext::SetContext(const description::Value& value)
|
|
{
|
|
SPIN_LOCK(lock)
|
|
{
|
|
context = value;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
DelayAsync
|
|
***********************************************************************/
|
|
|
|
class DelayAsync : public Object, public virtual IAsync, public Description<DelayAsync>
|
|
{
|
|
protected:
|
|
SpinLock lock;
|
|
vint milliseconds;
|
|
AsyncStatus status = AsyncStatus::Ready;
|
|
|
|
public:
|
|
DelayAsync(vint _milliseconds)
|
|
:milliseconds(_milliseconds)
|
|
{
|
|
}
|
|
|
|
AsyncStatus GetStatus()override
|
|
{
|
|
return status;
|
|
}
|
|
|
|
bool Execute(const Func<void(Ptr<CoroutineResult>)>& _callback, Ptr<AsyncContext> context)override
|
|
{
|
|
SPIN_LOCK(lock)
|
|
{
|
|
if (status != AsyncStatus::Ready) return false;
|
|
status = AsyncStatus::Executing;
|
|
IAsyncScheduler::GetSchedulerForCurrentThread()->DelayExecute([async = Ptr<DelayAsync>(this), callback = _callback]()
|
|
{
|
|
if (callback)
|
|
{
|
|
callback(nullptr);
|
|
}
|
|
}, milliseconds);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
Ptr<IAsync> IAsync::Delay(vint milliseconds)
|
|
{
|
|
return Ptr(new DelayAsync(milliseconds));
|
|
}
|
|
|
|
/***********************************************************************
|
|
FutureAndPromiseAsync
|
|
***********************************************************************/
|
|
|
|
class FutureAndPromiseAsync : public virtual IFuture, public virtual IPromise, public Description<FutureAndPromiseAsync>
|
|
{
|
|
public:
|
|
SpinLock lock;
|
|
AsyncStatus status = AsyncStatus::Ready;
|
|
Ptr<CoroutineResult> cr;
|
|
Func<void(Ptr<CoroutineResult>)> callback;
|
|
|
|
void ExecuteCallbackAndClear()
|
|
{
|
|
status = AsyncStatus::Stopped;
|
|
if (callback)
|
|
{
|
|
callback(cr);
|
|
}
|
|
cr = nullptr;
|
|
callback = {};
|
|
}
|
|
|
|
template<typename F>
|
|
bool Send(F f)
|
|
{
|
|
SPIN_LOCK(lock)
|
|
{
|
|
if (status == AsyncStatus::Stopped || cr) return false;
|
|
cr = Ptr(new CoroutineResult);
|
|
f();
|
|
if (status == AsyncStatus::Executing)
|
|
{
|
|
ExecuteCallbackAndClear();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
AsyncStatus GetStatus()override
|
|
{
|
|
return status;
|
|
}
|
|
|
|
bool Execute(const Func<void(Ptr<CoroutineResult>)>& _callback, Ptr<AsyncContext> context)override
|
|
{
|
|
SPIN_LOCK(lock)
|
|
{
|
|
if (status != AsyncStatus::Ready) return false;
|
|
callback = _callback;
|
|
if (cr)
|
|
{
|
|
ExecuteCallbackAndClear();
|
|
}
|
|
else
|
|
{
|
|
status = AsyncStatus::Executing;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Ptr<IPromise> GetPromise()override
|
|
{
|
|
return Ptr(this);
|
|
}
|
|
|
|
bool SendResult(const Value& result)override
|
|
{
|
|
return Send([=, this]()
|
|
{
|
|
cr->SetResult(result);
|
|
});
|
|
}
|
|
|
|
bool SendFailure(Ptr<IValueException> failure)override
|
|
{
|
|
return Send([=, this]()
|
|
{
|
|
cr->SetFailure(failure);
|
|
});
|
|
}
|
|
};
|
|
|
|
Ptr<IFuture> IFuture::Create()
|
|
{
|
|
return Ptr(new FutureAndPromiseAsync);
|
|
}
|
|
|
|
/***********************************************************************
|
|
IAsyncScheduler
|
|
***********************************************************************/
|
|
|
|
class AsyncSchedulerMap
|
|
{
|
|
public:
|
|
Dictionary<vint, Ptr<IAsyncScheduler>> schedulers;
|
|
Ptr<IAsyncScheduler> defaultScheduler;
|
|
};
|
|
|
|
AsyncSchedulerMap* asyncSchedulerMap = nullptr;
|
|
SpinLock asyncSchedulerLock;
|
|
|
|
#define ENSURE_ASYNC_SCHEDULER_MAP\
|
|
if (!asyncSchedulerMap) asyncSchedulerMap = new AsyncSchedulerMap;
|
|
|
|
#define DISPOSE_ASYNC_SCHEDULER_MAP_IF_NECESSARY\
|
|
if (asyncSchedulerMap->schedulers.Count() == 0 && !asyncSchedulerMap->defaultScheduler)\
|
|
{\
|
|
delete asyncSchedulerMap;\
|
|
asyncSchedulerMap = nullptr;\
|
|
}\
|
|
|
|
void IAsyncScheduler::RegisterDefaultScheduler(Ptr<IAsyncScheduler> scheduler)
|
|
{
|
|
SPIN_LOCK(asyncSchedulerLock)
|
|
{
|
|
ENSURE_ASYNC_SCHEDULER_MAP
|
|
CHECK_ERROR(!asyncSchedulerMap->defaultScheduler, L"IAsyncScheduler::RegisterDefaultScheduler()#A default scheduler has already been registered.");
|
|
asyncSchedulerMap->defaultScheduler = scheduler;
|
|
}
|
|
}
|
|
|
|
void IAsyncScheduler::RegisterSchedulerForCurrentThread(Ptr<IAsyncScheduler> scheduler)
|
|
{
|
|
SPIN_LOCK(asyncSchedulerLock)
|
|
{
|
|
ENSURE_ASYNC_SCHEDULER_MAP
|
|
CHECK_ERROR(!asyncSchedulerMap->schedulers.Keys().Contains(Thread::GetCurrentThreadId()), L"IAsyncScheduler::RegisterDefaultScheduler()#A scheduler for this thread has already been registered.");
|
|
asyncSchedulerMap->schedulers.Add(Thread::GetCurrentThreadId(), scheduler);
|
|
}
|
|
}
|
|
|
|
Ptr<IAsyncScheduler> IAsyncScheduler::UnregisterDefaultScheduler()
|
|
{
|
|
Ptr<IAsyncScheduler> scheduler;
|
|
SPIN_LOCK(asyncSchedulerLock)
|
|
{
|
|
if (asyncSchedulerMap)
|
|
{
|
|
scheduler = asyncSchedulerMap->defaultScheduler;
|
|
asyncSchedulerMap->defaultScheduler = nullptr;
|
|
DISPOSE_ASYNC_SCHEDULER_MAP_IF_NECESSARY
|
|
}
|
|
}
|
|
return scheduler;
|
|
}
|
|
|
|
Ptr<IAsyncScheduler> IAsyncScheduler::UnregisterSchedulerForCurrentThread()
|
|
{
|
|
Ptr<IAsyncScheduler> scheduler;
|
|
SPIN_LOCK(asyncSchedulerLock)
|
|
{
|
|
if (asyncSchedulerMap)
|
|
{
|
|
vint index = asyncSchedulerMap->schedulers.Keys().IndexOf(Thread::GetCurrentThreadId());
|
|
if (index != -1)
|
|
{
|
|
scheduler = asyncSchedulerMap->schedulers.Values()[index];
|
|
asyncSchedulerMap->schedulers.Remove(Thread::GetCurrentThreadId());
|
|
}
|
|
DISPOSE_ASYNC_SCHEDULER_MAP_IF_NECESSARY
|
|
}
|
|
}
|
|
return scheduler;
|
|
}
|
|
|
|
#undef ENSURE_ASYNC_SCHEDULER_MAP
|
|
#undef DISPOSE_ASYNC_SCHEDULER_MAP_IF_NECESSARY
|
|
|
|
Ptr<IAsyncScheduler> IAsyncScheduler::GetSchedulerForCurrentThread()
|
|
{
|
|
Ptr<IAsyncScheduler> scheduler;
|
|
SPIN_LOCK(asyncSchedulerLock)
|
|
{
|
|
CHECK_ERROR(asyncSchedulerMap != nullptr, L"IAsyncScheduler::GetSchedulerForCurrentThread()#There is no scheduler registered for the current thread.");
|
|
vint index = asyncSchedulerMap->schedulers.Keys().IndexOf(Thread::GetCurrentThreadId());
|
|
if (index != -1)
|
|
{
|
|
scheduler = asyncSchedulerMap->schedulers.Values()[index];
|
|
}
|
|
else if (asyncSchedulerMap->defaultScheduler)
|
|
{
|
|
scheduler = asyncSchedulerMap->defaultScheduler;
|
|
}
|
|
else
|
|
{
|
|
CHECK_FAIL(L"IAsyncScheduler::GetSchedulerForCurrentThread()#There is no scheduler registered for the current thread.");
|
|
}
|
|
}
|
|
return scheduler;
|
|
}
|
|
|
|
/***********************************************************************
|
|
AsyncCoroutine
|
|
***********************************************************************/
|
|
|
|
class CoroutineAsync : public Object, public virtual AsyncCoroutine::IImpl, public Description<CoroutineAsync>
|
|
{
|
|
protected:
|
|
Ptr<ICoroutine> coroutine;
|
|
AsyncCoroutine::Creator creator;
|
|
Ptr<IAsyncScheduler> scheduler;
|
|
Func<void(Ptr<CoroutineResult>)> callback;
|
|
Ptr<AsyncContext> context;
|
|
Value result;
|
|
|
|
public:
|
|
CoroutineAsync(AsyncCoroutine::Creator _creator)
|
|
:creator(_creator)
|
|
{
|
|
}
|
|
|
|
AsyncStatus GetStatus()override
|
|
{
|
|
if (!coroutine)
|
|
{
|
|
return AsyncStatus::Ready;
|
|
}
|
|
else if (coroutine->GetStatus() != CoroutineStatus::Stopped)
|
|
{
|
|
return AsyncStatus::Executing;
|
|
}
|
|
else
|
|
{
|
|
return AsyncStatus::Stopped;
|
|
}
|
|
}
|
|
|
|
bool Execute(const Func<void(Ptr<CoroutineResult>)>& _callback, Ptr<AsyncContext> _context)override
|
|
{
|
|
if (coroutine) return false;
|
|
scheduler = IAsyncScheduler::GetSchedulerForCurrentThread();
|
|
callback = _callback;
|
|
context = _context;
|
|
coroutine = creator(this);
|
|
OnContinue(nullptr);
|
|
return true;
|
|
}
|
|
|
|
Ptr<IAsyncScheduler> GetScheduler()override
|
|
{
|
|
return scheduler;
|
|
}
|
|
|
|
Ptr<AsyncContext> GetContext()override
|
|
{
|
|
if (!context)
|
|
{
|
|
context = Ptr(new AsyncContext);
|
|
}
|
|
return context;
|
|
}
|
|
|
|
void OnContinue(Ptr<CoroutineResult> output)override
|
|
{
|
|
scheduler->Execute([async = Ptr<CoroutineAsync>(this), output]()
|
|
{
|
|
async->coroutine->Resume(false, output);
|
|
if (async->coroutine->GetStatus() == CoroutineStatus::Stopped && async->callback)
|
|
{
|
|
auto result = Ptr(new CoroutineResult);
|
|
if (async->coroutine->GetFailure())
|
|
{
|
|
result->SetFailure(async->coroutine->GetFailure());
|
|
}
|
|
else
|
|
{
|
|
result->SetResult(async->result);
|
|
}
|
|
async->callback(result);
|
|
}
|
|
});
|
|
}
|
|
|
|
void OnReturn(const Value& value)override
|
|
{
|
|
result = value;
|
|
}
|
|
};
|
|
|
|
void AsyncCoroutine::AwaitAndRead(IImpl* impl, Ptr<IAsync> value)
|
|
{
|
|
value->Execute([async = Ptr<IImpl>(impl)](auto output)
|
|
{
|
|
async->OnContinue(output);
|
|
}, impl->GetContext());
|
|
}
|
|
|
|
void AsyncCoroutine::ReturnAndExit(IImpl* impl, const Value& value)
|
|
{
|
|
impl->OnReturn(value);
|
|
}
|
|
|
|
Ptr<AsyncContext> AsyncCoroutine::QueryContext(IImpl* impl)
|
|
{
|
|
return impl->GetContext();
|
|
}
|
|
|
|
Ptr<IAsync> AsyncCoroutine::Create(const Creator& creator)
|
|
{
|
|
return Ptr(new CoroutineAsync(creator));
|
|
}
|
|
void AsyncCoroutine::CreateAndRun(const Creator& creator)
|
|
{
|
|
Ptr(new CoroutineAsync(creator))->Execute(
|
|
[](Ptr<CoroutineResult> cr)
|
|
{
|
|
if (cr->GetFailure())
|
|
{
|
|
#pragma push_macro("GetMessage")
|
|
#if defined GetMessage
|
|
#undef GetMessage
|
|
#endif
|
|
throw Exception(cr->GetFailure()->GetMessage());
|
|
#pragma pop_macro("GetMessage")
|
|
}
|
|
}, nullptr);
|
|
}
|
|
|
|
/***********************************************************************
|
|
StateMachine
|
|
***********************************************************************/
|
|
|
|
void StateMachine::ResumeStateMachine()
|
|
{
|
|
Ptr<CoroutineResult> previousResult;
|
|
while (true)
|
|
{
|
|
if (stateMachineCoroutine == nullptr)
|
|
{
|
|
if (!stateMachineInitialized)
|
|
{
|
|
throw Exception(L"The state machine has not been initialized.");
|
|
}
|
|
if (stateMachineStopped)
|
|
{
|
|
throw Exception(L"The state machine has been stopped.");
|
|
}
|
|
stateMachineStopped = true;
|
|
|
|
if (previousResult)
|
|
{
|
|
if (auto failure = previousResult->GetFailure())
|
|
{
|
|
throw Exception(failure->GetMessage());
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
else if (stateMachineCoroutine->GetStatus() != CoroutineStatus::Stopped)
|
|
{
|
|
auto currentCoroutine = stateMachineCoroutine;
|
|
currentCoroutine->Resume(false, previousResult);
|
|
if (stateMachineCoroutine == currentCoroutine)
|
|
{
|
|
// wait for input
|
|
break;
|
|
}
|
|
else if (currentCoroutine->GetStatus() == CoroutineStatus::Stopped)
|
|
{
|
|
// leave a state machine
|
|
previousResult = Ptr(new CoroutineResult);
|
|
if (auto failure = currentCoroutine->GetFailure())
|
|
{
|
|
previousResult->SetFailure(failure);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// enter a state machine
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
StateMachine::StateMachine()
|
|
{
|
|
}
|
|
|
|
StateMachine::~StateMachine()
|
|
{
|
|
FinalizeAggregation();
|
|
}
|
|
|
|
CoroutineStatus StateMachine::GetStateMachineStatus()
|
|
{
|
|
if (stateMachineStopped)
|
|
{
|
|
return CoroutineStatus::Stopped;
|
|
}
|
|
else if (stateMachineCoroutine)
|
|
{
|
|
if (stateMachineCoroutine->GetStatus() == CoroutineStatus::Waiting)
|
|
{
|
|
return CoroutineStatus::Waiting;
|
|
}
|
|
else
|
|
{
|
|
return CoroutineStatus::Executing;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return CoroutineStatus::Waiting;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
Sys
|
|
***********************************************************************/
|
|
|
|
namespace system_sys
|
|
{
|
|
class ReverseEnumerable : public Object, public IValueEnumerable
|
|
{
|
|
protected:
|
|
Ptr<IValueReadonlyList> list;
|
|
|
|
class Enumerator : public Object, public IValueEnumerator
|
|
{
|
|
protected:
|
|
Ptr<IValueReadonlyList> list;
|
|
vint index;
|
|
|
|
public:
|
|
Enumerator(Ptr<IValueReadonlyList> _list)
|
|
:list(_list), index(_list->GetCount())
|
|
{
|
|
}
|
|
|
|
Value GetCurrent()
|
|
{
|
|
return list->Get(index);
|
|
}
|
|
|
|
vint GetIndex()
|
|
{
|
|
return list->GetCount() - 1 - index;
|
|
}
|
|
|
|
bool Next()
|
|
{
|
|
if (index <= 0) return false;
|
|
index--;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
public:
|
|
ReverseEnumerable(Ptr<IValueReadonlyList> _list)
|
|
:list(_list)
|
|
{
|
|
}
|
|
|
|
Ptr<IValueEnumerator> CreateEnumerator()override
|
|
{
|
|
return Ptr(new Enumerator(list));
|
|
}
|
|
};
|
|
}
|
|
|
|
DateTime Sys::GetLocalTime()
|
|
{
|
|
return DateTime::LocalTime();
|
|
}
|
|
|
|
DateTime Sys::GetUtcTime()
|
|
{
|
|
return DateTime::UtcTime();
|
|
}
|
|
|
|
DateTime Sys::ToLocalTime(DateTime dt)
|
|
{
|
|
return dt.ToLocalTime();
|
|
}
|
|
|
|
DateTime Sys::ToUtcTime(DateTime dt)
|
|
{
|
|
return dt.ToUtcTime();
|
|
}
|
|
|
|
DateTime Sys::Forward(DateTime dt, vuint64_t milliseconds)
|
|
{
|
|
return dt.Forward(milliseconds);
|
|
}
|
|
|
|
DateTime Sys::Backward(DateTime dt, vuint64_t milliseconds)
|
|
{
|
|
return dt.Backward(milliseconds);
|
|
}
|
|
|
|
DateTime Sys::CreateDateTime(vint year, vint month, vint day)
|
|
{
|
|
return DateTime::FromDateTime(year, month, day);
|
|
}
|
|
|
|
DateTime Sys::CreateDateTime(vint year, vint month, vint day, vint hour, vint minute, vint second, vint milliseconds)
|
|
{
|
|
return DateTime::FromDateTime(year, month, day, hour, minute, second, milliseconds);
|
|
}
|
|
|
|
Ptr<IValueEnumerable> Sys::ReverseEnumerable(Ptr<IValueEnumerable> value)
|
|
{
|
|
auto list = value.Cast<IValueReadonlyList>();
|
|
if (!list)
|
|
{
|
|
list = IValueList::Create(GetLazyList<Value>(value));
|
|
}
|
|
return Ptr(new system_sys::ReverseEnumerable(list));
|
|
}
|
|
|
|
#define DEFINE_COMPARE(TYPE)\
|
|
vint Sys::Compare(TYPE a, TYPE b)\
|
|
{\
|
|
auto result = a <=> b;\
|
|
if (result < 0) return -1;\
|
|
if (result > 0) return 1;\
|
|
return 0;\
|
|
}\
|
|
|
|
REFLECTION_PREDEFINED_PRIMITIVE_TYPES(DEFINE_COMPARE)
|
|
DEFINE_COMPARE(DateTime)
|
|
#undef DEFINE_COMPARE
|
|
|
|
/***********************************************************************
|
|
Math
|
|
***********************************************************************/
|
|
|
|
#define DEFINE_MINMAX(TYPE)\
|
|
TYPE Math::Min(TYPE a, TYPE b)\
|
|
{\
|
|
return Sys::Compare(a, b) < 0 ? a : b;\
|
|
}\
|
|
TYPE Math::Max(TYPE a, TYPE b)\
|
|
{\
|
|
return Sys::Compare(a, b) > 0 ? a : b;\
|
|
}\
|
|
|
|
REFLECTION_PREDEFINED_PRIMITIVE_TYPES(DEFINE_MINMAX)
|
|
DEFINE_MINMAX(DateTime)
|
|
#undef DEFINE_MINMAX
|
|
|
|
/***********************************************************************
|
|
Localization
|
|
***********************************************************************/
|
|
|
|
Locale Localization::Invariant()
|
|
{
|
|
return Locale::Invariant();
|
|
}
|
|
|
|
Locale Localization::System()
|
|
{
|
|
return Locale::SystemDefault();
|
|
}
|
|
|
|
Locale Localization::User()
|
|
{
|
|
return Locale::UserDefault();
|
|
}
|
|
|
|
collections::LazyList<Locale> Localization::Locales()
|
|
{
|
|
auto result = Ptr(new List<Locale>);
|
|
Locale::Enumerate(*result.Obj());
|
|
return result;
|
|
}
|
|
|
|
collections::LazyList<WString> Localization::GetShortDateFormats(Locale locale)
|
|
{
|
|
auto result = Ptr(new List<WString>);
|
|
locale.GetShortDateFormats(*result.Obj());
|
|
return result;
|
|
}
|
|
|
|
collections::LazyList<WString> Localization::GetLongDateFormats(Locale locale)
|
|
{
|
|
auto result = Ptr(new List<WString>);
|
|
locale.GetLongDateFormats(*result.Obj());
|
|
return result;
|
|
}
|
|
|
|
collections::LazyList<WString> Localization::GetYearMonthDateFormats(Locale locale)
|
|
{
|
|
auto result = Ptr(new List<WString>);
|
|
locale.GetYearMonthDateFormats(*result.Obj());
|
|
return result;
|
|
}
|
|
|
|
collections::LazyList<WString> Localization::GetLongTimeFormats(Locale locale)
|
|
{
|
|
auto result = Ptr(new List<WString>);
|
|
locale.GetLongTimeFormats(*result.Obj());
|
|
return result;
|
|
}
|
|
|
|
collections::LazyList<WString> Localization::GetShortTimeFormats(Locale locale)
|
|
{
|
|
auto result = Ptr(new List<WString>);
|
|
locale.GetShortTimeFormats(*result.Obj());
|
|
return result;
|
|
}
|
|
|
|
WString Localization::GetShortDayOfWeekName(Locale locale, vint dayOfWeek)
|
|
{
|
|
return locale.GetShortDayOfWeekName(dayOfWeek);
|
|
}
|
|
|
|
WString Localization::GetLongDayOfWeekName(Locale locale, vint dayOfWeek)
|
|
{
|
|
return locale.GetLongDayOfWeekName(dayOfWeek);
|
|
}
|
|
|
|
WString Localization::GetShortMonthName(Locale locale, vint month)
|
|
{
|
|
return locale.GetShortMonthName(month);
|
|
}
|
|
|
|
WString Localization::GetLongMonthName(Locale locale, vint month)
|
|
{
|
|
return locale.GetLongMonthName(month);
|
|
}
|
|
|
|
WString Localization::FormatDate(Locale locale, const WString& format, DateTime date)
|
|
{
|
|
return locale.FormatDate(format, date);
|
|
}
|
|
|
|
WString Localization::FormatTime(Locale locale, const WString& format, DateTime date)
|
|
{
|
|
return locale.FormatTime(format, date);
|
|
}
|
|
|
|
WString Localization::FormatNumber(Locale locale, const WString& number)
|
|
{
|
|
return locale.FormatNumber(number);
|
|
}
|
|
|
|
WString Localization::FormatCurrency(Locale locale, const WString& number)
|
|
{
|
|
return locale.FormatCurrency(number);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
.\WFLIBRARYREFLECTION.CPP
|
|
***********************************************************************/
|
|
#include <limits.h>
|
|
#include <float.h>
|
|
|
|
namespace vl
|
|
{
|
|
using namespace collections;
|
|
using namespace regex;
|
|
|
|
namespace reflection
|
|
{
|
|
namespace description
|
|
{
|
|
|
|
/***********************************************************************
|
|
TypeName
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_DEBUG_NO_REFLECTION
|
|
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::Sys, system::Sys)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::Math, system::Math)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::Localization, system::Localization)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::CoroutineStatus, system::CoroutineStatus)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::CoroutineResult, system::CoroutineResult)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::ICoroutine, system::Coroutine)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::EnumerableCoroutine::IImpl, system::EnumerableCoroutine::IImpl)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::EnumerableCoroutine, system::EnumerableCoroutine)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::AsyncStatus, system::AsyncStatus)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::AsyncContext, system::AsyncContext)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::IAsync, system::Async)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::IPromise, system::Promise)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::IFuture, system::Future)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::IAsyncScheduler, system::AsyncScheduler)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::AsyncCoroutine::IImpl, system::AsyncCoroutine::IImpl)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::AsyncCoroutine, system::AsyncCoroutine)
|
|
IMPL_TYPE_INFO_RENAME(vl::reflection::description::StateMachine, system::StateMachine)
|
|
|
|
#endif
|
|
|
|
/***********************************************************************
|
|
WfLoadLibraryTypes
|
|
***********************************************************************/
|
|
|
|
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
|
|
|
|
#define _ ,
|
|
|
|
BEGIN_CLASS_MEMBER(Sys)
|
|
CLASS_MEMBER_STATIC_METHOD(Int32ToInt, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Int64ToInt, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(IntToInt32, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(IntToInt64, { L"value" })
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(UInt32ToUInt, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(UInt64ToUInt, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(UIntToUInt32, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(UIntToUInt64, { L"value" })
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(Len, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Left, { L"value" _ L"length" })
|
|
CLASS_MEMBER_STATIC_METHOD(Right, { L"value" _ L"length" })
|
|
CLASS_MEMBER_STATIC_METHOD(Mid, { L"value" _ L"start" _ L"length" })
|
|
CLASS_MEMBER_STATIC_METHOD(Find, { L"value" _ L"substr" })
|
|
CLASS_MEMBER_STATIC_METHOD(UCase, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(LCase, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(LoremIpsumTitle, { L"bestLength" })
|
|
CLASS_MEMBER_STATIC_METHOD(LoremIpsumSentence, { L"bestLength" })
|
|
CLASS_MEMBER_STATIC_METHOD(LoremIpsumParagraph, { L"bestLength" })
|
|
CLASS_MEMBER_STATIC_METHOD(ReverseEnumerable, { L"value" })
|
|
#pragma push_macro("CompareString")
|
|
#if defined CompareString
|
|
#undef CompareString
|
|
#endif
|
|
#define DEFINE_COMPARE(TYPE) CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Compare, PROTECT_PARAMETERS({L"a" _ L"b"}), vint(*)(TYPE, TYPE))
|
|
REFLECTION_PREDEFINED_PRIMITIVE_TYPES(DEFINE_COMPARE)
|
|
DEFINE_COMPARE(DateTime)
|
|
#undef DEFINE_COMPARE
|
|
#pragma pop_macro("CompareString")
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(GetLocalTime, NO_PARAMETER)
|
|
CLASS_MEMBER_STATIC_METHOD(GetUtcTime, NO_PARAMETER)
|
|
CLASS_MEMBER_STATIC_METHOD(ToLocalTime, { L"dt" })
|
|
CLASS_MEMBER_STATIC_METHOD(ToUtcTime, { L"dt" })
|
|
CLASS_MEMBER_STATIC_METHOD(Forward, { L"dt" _ L"milliseconds" })
|
|
CLASS_MEMBER_STATIC_METHOD(Backward, { L"dt" _ L"milliseconds" })
|
|
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(CreateDateTime, {L"year" _ L"month" _ L"day" }, DateTime(*)(vint, vint, vint))
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(CreateDateTime, { L"year" _ L"month" _ L"day" _ L"hour" _ L"minute" _ L"second" _ L"milliseconds" }, DateTime(*)(vint, vint, vint, vint, vint, vint, vint))
|
|
END_CLASS_MEMBER(Sys)
|
|
|
|
BEGIN_CLASS_MEMBER(Math)
|
|
CLASS_MEMBER_STATIC_METHOD(Pi, NO_PARAMETER)
|
|
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Abs, { L"value" }, vint8_t(*)(vint8_t))
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Abs, { L"value" }, vint16_t(*)(vint16_t))
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Abs, { L"value" }, vint32_t(*)(vint32_t))
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Abs, { L"value" }, vint64_t(*)(vint64_t))
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Abs, { L"value" }, float(*)(float))
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Abs, { L"value" }, double(*)(double))
|
|
|
|
#define DEFINE_MINMAX(TYPE)\
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Min, PROTECT_PARAMETERS({L"a" _ L"b"}), TYPE(*)(TYPE, TYPE))\
|
|
CLASS_MEMBER_STATIC_METHOD_OVERLOAD(Max, PROTECT_PARAMETERS({L"a" _ L"b"}), TYPE(*)(TYPE, TYPE))\
|
|
|
|
REFLECTION_PREDEFINED_PRIMITIVE_TYPES(DEFINE_MINMAX)
|
|
DEFINE_MINMAX(DateTime)
|
|
#undef DEFINE_MINMAX
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(Sin, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Cos, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Tan, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(ASin, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(ACos, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(ATan, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(ATan2, { L"x" _ L"y" })
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(Exp, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(LogN, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Log10, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Log, { L"value" _ L"base" })
|
|
CLASS_MEMBER_STATIC_METHOD(Pow, { L"value" _ L"power" })
|
|
CLASS_MEMBER_STATIC_METHOD(Ceil, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Floor, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Round, { L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(Trunc, { L"value" })
|
|
END_CLASS_MEMBER(Math)
|
|
|
|
BEGIN_CLASS_MEMBER(Localization)
|
|
CLASS_MEMBER_STATIC_METHOD(Invariant, NO_PARAMETER)
|
|
CLASS_MEMBER_STATIC_METHOD(System, NO_PARAMETER)
|
|
CLASS_MEMBER_STATIC_METHOD(User, NO_PARAMETER)
|
|
CLASS_MEMBER_STATIC_METHOD(Locales, NO_PARAMETER)
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(GetShortDateFormats, { L"locale" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetLongDateFormats, { L"locale" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetYearMonthDateFormats, { L"locale" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetLongTimeFormats, { L"locale" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetShortTimeFormats, { L"locale" })
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(GetShortDayOfWeekName, { L"locale" _ L"dayOfWeek" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetLongDayOfWeekName, { L"locale" _ L"dayOfWeek" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetShortMonthName, { L"locale" _ L"month" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetLongMonthName, { L"locale" _ L"month" })
|
|
|
|
CLASS_MEMBER_STATIC_METHOD(FormatDate, { L"locale" _ L"format" _ L"date" })
|
|
CLASS_MEMBER_STATIC_METHOD(FormatTime, { L"locale" _ L"format" _ L"date" })
|
|
CLASS_MEMBER_STATIC_METHOD(FormatNumber, { L"locale" _ L"number" })
|
|
CLASS_MEMBER_STATIC_METHOD(FormatCurrency, { L"locale" _ L"number" })
|
|
END_CLASS_MEMBER(Localization)
|
|
|
|
BEGIN_ENUM_ITEM(CoroutineStatus)
|
|
ENUM_CLASS_ITEM(Waiting)
|
|
ENUM_CLASS_ITEM(Executing)
|
|
ENUM_CLASS_ITEM(Stopped)
|
|
END_ENUM_ITEM(CoroutineStatus)
|
|
|
|
BEGIN_INTERFACE_MEMBER(ICoroutine)
|
|
CLASS_MEMBER_METHOD(Resume, { L"raiseException" _ L"output" })
|
|
CLASS_MEMBER_PROPERTY_READONLY_FAST(Failure)
|
|
CLASS_MEMBER_PROPERTY_READONLY_FAST(Status)
|
|
END_INTERFACE_MEMBER(ICoroutine)
|
|
|
|
BEGIN_CLASS_MEMBER(CoroutineResult)
|
|
CLASS_MEMBER_CONSTRUCTOR(Ptr<CoroutineResult>(), NO_PARAMETER)
|
|
CLASS_MEMBER_PROPERTY_FAST(Result)
|
|
CLASS_MEMBER_PROPERTY_FAST(Failure)
|
|
END_CLASS_MEMBER(CoroutineResult)
|
|
|
|
BEGIN_INTERFACE_MEMBER_NOPROXY(EnumerableCoroutine::IImpl)
|
|
CLASS_MEMBER_BASE(IValueEnumerator)
|
|
END_INTERFACE_MEMBER(EnumerableCoroutine::IImpl)
|
|
|
|
BEGIN_CLASS_MEMBER(EnumerableCoroutine)
|
|
CLASS_MEMBER_STATIC_METHOD(YieldAndPause, { L"impl" _ L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(JoinAndPause, { L"impl" _ L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(ReturnAndExit, { L"impl" })
|
|
CLASS_MEMBER_STATIC_METHOD(Create, { L"creator" })
|
|
END_CLASS_MEMBER(EnumerableCoroutine)
|
|
|
|
BEGIN_ENUM_ITEM(AsyncStatus)
|
|
ENUM_CLASS_ITEM(Ready)
|
|
ENUM_CLASS_ITEM(Executing)
|
|
ENUM_CLASS_ITEM(Stopped)
|
|
END_ENUM_ITEM(AsyncStatus)
|
|
|
|
BEGIN_CLASS_MEMBER(AsyncContext)
|
|
CLASS_MEMBER_CONSTRUCTOR(Ptr<AsyncContext>(const Value&), {L"context"})
|
|
CLASS_MEMBER_METHOD(IsCancelled, NO_PARAMETER)
|
|
CLASS_MEMBER_METHOD(Cancel, NO_PARAMETER)
|
|
CLASS_MEMBER_PROPERTY_FAST(Context)
|
|
END_CLASS_MEMBER(AsyncContext)
|
|
|
|
BEGIN_INTERFACE_MEMBER(IAsync)
|
|
CLASS_MEMBER_PROPERTY_READONLY_FAST(Status)
|
|
CLASS_MEMBER_METHOD(Execute, { L"callback" _ L"context" })
|
|
CLASS_MEMBER_STATIC_METHOD(Delay, { L"milliseconds" })
|
|
END_INTERFACE_MEMBER(IAsync)
|
|
|
|
BEGIN_INTERFACE_MEMBER_NOPROXY(IPromise)
|
|
CLASS_MEMBER_METHOD(SendResult, { L"result" })
|
|
CLASS_MEMBER_METHOD(SendFailure, { L"failure" })
|
|
END_INTERFACE_MEMBER(IPromise)
|
|
|
|
BEGIN_INTERFACE_MEMBER_NOPROXY(IFuture)
|
|
CLASS_MEMBER_BASE(IAsync)
|
|
CLASS_MEMBER_BASE(IPromise)
|
|
CLASS_MEMBER_PROPERTY_READONLY_FAST(Promise)
|
|
CLASS_MEMBER_STATIC_METHOD(Create, NO_PARAMETER)
|
|
END_INTERFACE_MEMBER(IFuture)
|
|
|
|
BEGIN_INTERFACE_MEMBER_NOPROXY(IAsyncScheduler)
|
|
CLASS_MEMBER_METHOD(Execute, { L"callback" })
|
|
CLASS_MEMBER_METHOD(ExecuteInBackground, { L"callback" })
|
|
CLASS_MEMBER_METHOD(DelayExecute, { L"callback" _ L"milliseconds" })
|
|
CLASS_MEMBER_STATIC_METHOD(GetSchedulerForCurrentThread, NO_PARAMETER)
|
|
END_INTERFACE_MEMBER(IAsyncScheduler)
|
|
|
|
BEGIN_INTERFACE_MEMBER_NOPROXY(AsyncCoroutine::IImpl)
|
|
CLASS_MEMBER_BASE(IAsync)
|
|
END_INTERFACE_MEMBER(AsyncCoroutine::IImpl)
|
|
|
|
BEGIN_CLASS_MEMBER(AsyncCoroutine)
|
|
CLASS_MEMBER_STATIC_METHOD(AwaitAndRead, { L"impl" _ L"value" })
|
|
CLASS_MEMBER_STATIC_METHOD(ReturnAndExit, { L"impl" _ L"value"})
|
|
CLASS_MEMBER_STATIC_METHOD(QueryContext, { L"impl" })
|
|
CLASS_MEMBER_STATIC_METHOD(Create, { L"creator" })
|
|
CLASS_MEMBER_STATIC_METHOD(CreateAndRun, { L"creator" })
|
|
END_CLASS_MEMBER(AsyncCoroutine)
|
|
|
|
BEGIN_CLASS_MEMBER(StateMachine)
|
|
CLASS_MEMBER_FIELD(stateMachineInitialized)
|
|
CLASS_MEMBER_FIELD(stateMachineStopped)
|
|
CLASS_MEMBER_FIELD(stateMachineInput)
|
|
CLASS_MEMBER_FIELD(stateMachineCoroutine)
|
|
|
|
CLASS_MEMBER_CONSTRUCTOR(Ptr<StateMachine>(), NO_PARAMETER)
|
|
CLASS_MEMBER_METHOD(ResumeStateMachine, NO_PARAMETER)
|
|
|
|
CLASS_MEMBER_PROPERTY_READONLY_FAST(StateMachineStatus)
|
|
END_CLASS_MEMBER(StateMachine)
|
|
#undef _
|
|
|
|
class WfLibraryTypeLoader : public Object, public ITypeLoader
|
|
{
|
|
public:
|
|
void Load(ITypeManager* manager)override
|
|
{
|
|
WORKFLOW_LIBRARY_TYPES(ADD_TYPE_INFO)
|
|
}
|
|
|
|
void Unload(ITypeManager* manager)override
|
|
{
|
|
}
|
|
};
|
|
|
|
#endif
|
|
|
|
bool WfLoadLibraryTypes()
|
|
{
|
|
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
|
|
ITypeManager* manager = GetGlobalTypeManager();
|
|
if (manager)
|
|
{
|
|
auto loader = Ptr(new WfLibraryTypeLoader);
|
|
return manager->AddTypeLoader(loader);
|
|
}
|
|
#endif
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|