Update release

This commit is contained in:
vczh
2025-08-25 18:51:42 -07:00
parent f9947fc69c
commit 78b054d4d7
7 changed files with 205 additions and 33 deletions
+12 -1
View File
@@ -1494,7 +1494,9 @@ UnitTestRemoteProtocol
UnitTestRemoteProtocol_IOCommands UnitTestRemoteProtocol_IOCommands
>::Type; >::Type;
class UnitTestRemoteProtocol : public UnitTestRemoteProtocolFeatures class UnitTestRemoteProtocol
: public UnitTestRemoteProtocolFeatures
, protected virtual IGuiRemoteEventProcessor
{ {
using EventPair = collections::Pair<Nullable<WString>, Func<void()>>; using EventPair = collections::Pair<Nullable<WString>, Func<void()>>;
protected: protected:
@@ -1551,6 +1553,8 @@ IGuiRemoteProtocol
// TODO: Failure injection to disconnected // TODO: Failure injection to disconnected
} }
protected:
void ProcessRemoteEvents() override void ProcessRemoteEvents() override
{ {
#define ERROR_MESSAGE_PREFIX L"vl::presentation::unittest::UnitTestRemoteProtocol::ProcessRemoteEvents()#" #define ERROR_MESSAGE_PREFIX L"vl::presentation::unittest::UnitTestRemoteProtocol::ProcessRemoteEvents()#"
@@ -1574,6 +1578,13 @@ IGuiRemoteProtocol
} }
#undef ERROR_MESSAGE_PREFIX #undef ERROR_MESSAGE_PREFIX
} }
public:
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
{
return this;
}
}; };
} }
+10 -7
View File
@@ -38512,7 +38512,10 @@ GuiRemoteController::INativeWindowService
{ {
if (!connectionStopped) if (!connectionStopped)
{ {
remoteProtocol->ProcessRemoteEvents(); if (auto processor = remoteProtocol->GetRemoteEventProcessor())
{
processor->ProcessRemoteEvents();
}
bool disconnected = false; bool disconnected = false;
remoteMessages.Submit(disconnected); remoteMessages.Submit(disconnected);
if (timerEnabled && !disconnected) if (timerEnabled && !disconnected)
@@ -40838,9 +40841,9 @@ GuiRemoteProtocolFromJsonChannel
channel->Submit(disconnected); channel->Submit(disconnected);
} }
void GuiRemoteProtocolFromJsonChannel::ProcessRemoteEvents() IGuiRemoteEventProcessor* GuiRemoteProtocolFromJsonChannel::GetRemoteEventProcessor()
{ {
channel->ProcessRemoteEvents(); return channel->GetRemoteEventProcessor();
} }
/*********************************************************************** /***********************************************************************
@@ -40989,9 +40992,9 @@ GuiRemoteJsonChannelFromProtocol
protocol->Submit(disconnected); protocol->Submit(disconnected);
} }
void GuiRemoteJsonChannelFromProtocol::ProcessRemoteEvents() IGuiRemoteEventProcessor* GuiRemoteJsonChannelFromProtocol::GetRemoteEventProcessor()
{ {
protocol->ProcessRemoteEvents(); return protocol->GetRemoteEventProcessor();
} }
/*********************************************************************** /***********************************************************************
@@ -44614,9 +44617,9 @@ namespace vl::presentation::remote_renderer
CHECK_FAIL(L"This function should not be called!"); CHECK_FAIL(L"This function should not be called!");
} }
void GuiRemoteRendererSingle::ProcessRemoteEvents() IGuiRemoteEventProcessor* GuiRemoteRendererSingle::GetRemoteEventProcessor()
{ {
CHECK_FAIL(L"This function should not be called!"); return nullptr;
} }
} }
+71 -25
View File
@@ -23304,6 +23304,16 @@ IGuiRemoteProtocolConfig
virtual WString GetExecutablePath() = 0; virtual WString GetExecutablePath() = 0;
}; };
/***********************************************************************
IGuiRemoteEventProcessor
***********************************************************************/
class IGuiRemoteEventProcessor : public virtual Interface
{
public:
virtual void ProcessRemoteEvents() = 0;
};
/*********************************************************************** /***********************************************************************
IGuiRemoteProtocol IGuiRemoteProtocol
***********************************************************************/ ***********************************************************************/
@@ -23313,9 +23323,9 @@ IGuiRemoteProtocol
, public virtual IGuiRemoteProtocolMessages , public virtual IGuiRemoteProtocolMessages
{ {
public: public:
virtual void Initialize(IGuiRemoteProtocolEvents* events) = 0; virtual void Initialize(IGuiRemoteProtocolEvents* events) = 0;
virtual void Submit(bool& disconnected) = 0; virtual void Submit(bool& disconnected) = 0;
virtual void ProcessRemoteEvents() = 0; virtual IGuiRemoteEventProcessor* GetRemoteEventProcessor() = 0;
}; };
class GuiRemoteEventCombinator : public Object, public virtual IGuiRemoteProtocolEvents class GuiRemoteEventCombinator : public Object, public virtual IGuiRemoteProtocolEvents
@@ -23359,9 +23369,9 @@ IGuiRemoteProtocol
targetProtocol->Submit(disconnected); targetProtocol->Submit(disconnected);
} }
void ProcessRemoteEvents() override IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
{ {
targetProtocol->ProcessRemoteEvents(); return targetProtocol->GetRemoteEventProcessor();
} }
}; };
@@ -23396,9 +23406,9 @@ IGuiRemoteProtocol
targetProtocol->Submit(disconnected); targetProtocol->Submit(disconnected);
} }
void ProcessRemoteEvents() override IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
{ {
targetProtocol->ProcessRemoteEvents(); return targetProtocol->GetRemoteEventProcessor();
} }
}; };
@@ -23491,7 +23501,7 @@ IGuiRemoteProtocolChannel<T>
virtual void Write(const TPackage& package) = 0; virtual void Write(const TPackage& package) = 0;
virtual WString GetExecutablePath() = 0; virtual WString GetExecutablePath() = 0;
virtual void Submit(bool& disconnected) = 0; virtual void Submit(bool& disconnected) = 0;
virtual void ProcessRemoteEvents() = 0; virtual IGuiRemoteEventProcessor* GetRemoteEventProcessor() = 0;
}; };
/*********************************************************************** /***********************************************************************
@@ -23535,9 +23545,9 @@ Serialization
channel->Submit(disconnected); channel->Submit(disconnected);
} }
void ProcessRemoteEvents() override IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
{ {
channel->ProcessRemoteEvents(); return channel->GetRemoteEventProcessor();
} }
}; };
@@ -23719,11 +23729,18 @@ void ChannelPackageSemanticUnpack(
~GuiRemoteProtocolAsyncChannelSerializerBase(); ~GuiRemoteProtocolAsyncChannelSerializerBase();
}; };
#ifdef _DEBUG
#define ENSURE_THREAD_ID(ID) CHECK_ERROR(ID == Thread::GetCurrentThreadId(), L"Expected to be called in thread: " ## #ID)
#else
#define ENSURE_THREAD_ID(ID) ((void)0)
#endif
template<typename TPackage> template<typename TPackage>
class GuiRemoteProtocolAsyncChannelSerializer class GuiRemoteProtocolAsyncChannelSerializer
: public GuiRemoteProtocolAsyncChannelSerializerBase : public GuiRemoteProtocolAsyncChannelSerializerBase
, public virtual IGuiRemoteProtocolChannel<TPackage> , public virtual IGuiRemoteProtocolChannel<TPackage>
, protected virtual IGuiRemoteProtocolChannelReceiver<TPackage> , protected virtual IGuiRemoteProtocolChannelReceiver<TPackage>
, protected virtual IGuiRemoteEventProcessor
{ {
static_assert( static_assert(
std::is_same_v<void, decltype(ChannelPackageSemanticUnpack( std::is_same_v<void, decltype(ChannelPackageSemanticUnpack(
@@ -23747,6 +23764,9 @@ void ChannelPackageSemanticUnpack(
collections::List<vint> requestIds; collections::List<vint> requestIds;
}; };
vint threadIdUI = -1;
vint threadIdChannel = -1;
IGuiRemoteProtocolChannel<TPackage>* channel = nullptr; IGuiRemoteProtocolChannel<TPackage>* channel = nullptr;
IGuiRemoteProtocolChannelReceiver<TPackage>* receiver = nullptr; IGuiRemoteProtocolChannelReceiver<TPackage>* receiver = nullptr;
TUIMainProc uiMainProc; TUIMainProc uiMainProc;
@@ -23775,6 +23795,7 @@ void ChannelPackageSemanticUnpack(
void UIThreadProc() void UIThreadProc()
{ {
threadIdUI = Thread::GetCurrentThreadId();
uiMainProc(this); uiMainProc(this);
uiMainProc = {}; uiMainProc = {};
@@ -23800,6 +23821,7 @@ void ChannelPackageSemanticUnpack(
// So that the implementation does not need to care about thread safety // So that the implementation does not need to care about thread safety
// The thread stopped after receiving a signal from UIThreadProc // The thread stopped after receiving a signal from UIThreadProc
threadIdChannel = Thread::GetCurrentThreadId();
while (!stopping) while (!stopping)
{ {
eventAutoChannelTaskQueued.Wait(); eventAutoChannelTaskQueued.Wait();
@@ -23871,6 +23893,7 @@ void ChannelPackageSemanticUnpack(
void Write(const TPackage& package) override void Write(const TPackage& package) override
{ {
// Called from UI thread // Called from UI thread
ENSURE_THREAD_ID(threadIdUI);
uiPendingPackages.Add(package); uiPendingPackages.Add(package);
} }
@@ -23879,6 +23902,7 @@ void ChannelPackageSemanticUnpack(
// Called from UI thread // Called from UI thread
#define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::GuiRemoteProtocolAsyncChannelSerializer<TPackage>::Submit(...)#" #define ERROR_MESSAGE_PREFIX L"vl::presentation::remoteprotocol::channeling::GuiRemoteProtocolAsyncChannelSerializer<TPackage>::Submit(...)#"
ENSURE_THREAD_ID(threadIdUI);
SPIN_LOCK(lockConnection) SPIN_LOCK(lockConnection)
{ {
if (!connectionAvailable) if (!connectionAvailable)
@@ -23910,14 +23934,15 @@ void ChannelPackageSemanticUnpack(
QueueToChannelThread([this, requestGroup, packages = std::move(uiPendingPackages)]() QueueToChannelThread([this, requestGroup, packages = std::move(uiPendingPackages)]()
{ {
ENSURE_THREAD_ID(threadIdChannel);
for (auto&& package : packages) for (auto&& package : packages)
{ {
channel->Write(package); channel->Write(package);
} }
bool disconnected = false; bool disconnected = false;
channel->Submit(disconnected); channel->Submit(disconnected);
if (disconnected) if (disconnected)
{ {
SPIN_LOCK(lockConnection) SPIN_LOCK(lockConnection)
{ {
if (requestGroup->connectionCounter == connectionCounter) if (requestGroup->connectionCounter == connectionCounter)
@@ -23967,13 +23992,20 @@ void ChannelPackageSemanticUnpack(
#undef ERROR_MESSAGE_PREFIX #undef ERROR_MESSAGE_PREFIX
} }
protected:
void ProcessRemoteEvents() override void ProcessRemoteEvents() override
{ {
// Called from UI thread // Called from UI thread
QueueToChannelThread([this]() ENSURE_THREAD_ID(threadIdUI);
if (channel->GetRemoteEventProcessor())
{ {
channel->ProcessRemoteEvents(); QueueToChannelThread([this]()
}, &eventAutoChannelTaskQueued); {
ENSURE_THREAD_ID(threadIdChannel);
channel->GetRemoteEventProcessor()->ProcessRemoteEvents();
}, &eventAutoChannelTaskQueued);
}
FetchAndExecuteUITasks(); FetchAndExecuteUITasks();
@@ -24003,6 +24035,13 @@ void ChannelPackageSemanticUnpack(
} }
} }
public:
IGuiRemoteEventProcessor* GetRemoteEventProcessor() override
{
return this;
}
public: public:
/// <summary> /// <summary>
@@ -24091,9 +24130,11 @@ void ChannelPackageSemanticUnpack(
void Initialize(IGuiRemoteProtocolChannelReceiver<TPackage>* _receiver) override void Initialize(IGuiRemoteProtocolChannelReceiver<TPackage>* _receiver) override
{ {
// Called from UI thread // Called from UI thread
ENSURE_THREAD_ID(threadIdUI);
receiver = _receiver; receiver = _receiver;
QueueToChannelThreadAndWait([this]() QueueToChannelThreadAndWait([this]()
{ {
ENSURE_THREAD_ID(threadIdChannel);
channel->Initialize(this); channel->Initialize(this);
}, &eventAutoChannelTaskQueued); }, &eventAutoChannelTaskQueued);
} }
@@ -24101,16 +24142,19 @@ void ChannelPackageSemanticUnpack(
IGuiRemoteProtocolChannelReceiver<TPackage>* GetReceiver() override IGuiRemoteProtocolChannelReceiver<TPackage>* GetReceiver() override
{ {
// Called from UI thread // Called from UI thread
ENSURE_THREAD_ID(threadIdUI);
return receiver; return receiver;
} }
WString GetExecutablePath() override WString GetExecutablePath() override
{ {
// Called from UI thread // Called from UI thread
ENSURE_THREAD_ID(threadIdUI);
if (!executablePath) if (!executablePath)
{ {
QueueToChannelThreadAndWait([this]() QueueToChannelThreadAndWait([this]()
{ {
ENSURE_THREAD_ID(threadIdChannel);
executablePath = channel->GetExecutablePath(); executablePath = channel->GetExecutablePath();
}, &eventAutoChannelTaskQueued); }, &eventAutoChannelTaskQueued);
} }
@@ -24119,6 +24163,8 @@ void ChannelPackageSemanticUnpack(
}; };
} }
#undef ENSURE_THREAD_ID
#endif #endif
/*********************************************************************** /***********************************************************************
@@ -24211,7 +24257,7 @@ GuiRemoteProtocolFromJsonChannel
void Initialize(IGuiRemoteProtocolEvents* _events) override; void Initialize(IGuiRemoteProtocolEvents* _events) override;
WString GetExecutablePath() override; WString GetExecutablePath() override;
void Submit(bool& disconnected) override; void Submit(bool& disconnected) override;
void ProcessRemoteEvents() override; IGuiRemoteEventProcessor* GetRemoteEventProcessor() override;
}; };
/*********************************************************************** /***********************************************************************
@@ -24274,7 +24320,7 @@ GuiRemoteJsonChannelFromProtocol
void Write(const Ptr<glr::json::JsonObject>& package) override; void Write(const Ptr<glr::json::JsonObject>& package) override;
WString GetExecutablePath() override; WString GetExecutablePath() override;
void Submit(bool& disconnected) override; void Submit(bool& disconnected) override;
void ProcessRemoteEvents() override; IGuiRemoteEventProcessor* GetRemoteEventProcessor() override;
}; };
/*********************************************************************** /***********************************************************************
@@ -24799,14 +24845,14 @@ namespace vl::presentation::remote_renderer
GuiRemoteRendererSingle(); GuiRemoteRendererSingle();
~GuiRemoteRendererSingle(); ~GuiRemoteRendererSingle();
void RegisterMainWindow(INativeWindow* _window); void RegisterMainWindow(INativeWindow* _window);
void UnregisterMainWindow(); void UnregisterMainWindow();
void ForceExitByFatelError(); void ForceExitByFatelError();
WString GetExecutablePath() override; WString GetExecutablePath() override;
void Initialize(IGuiRemoteProtocolEvents* _events) override; void Initialize(IGuiRemoteProtocolEvents* _events) override;
void Submit(bool& disconnected) override; void Submit(bool& disconnected) override;
void ProcessRemoteEvents() override; IGuiRemoteEventProcessor* GetRemoteEventProcessor() override;
#define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE) void Request ## NAME() override; #define MESSAGE_NOREQ_NORES(NAME, REQUEST, RESPONSE) void Request ## NAME() override;
+3
View File
@@ -1511,6 +1511,9 @@ UnitTest
int UnitTest::RunAndDisposeTests(const collections::Array<WString>& options) int UnitTest::RunAndDisposeTests(const collections::Array<WString>& options)
{ {
#ifdef VCZH_MSVC
_set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif
bool unrecognized = false; bool unrecognized = false;
bool _D = false; bool _D = false;
bool _R = false; bool _R = false;
+109
View File
@@ -6075,6 +6075,115 @@ Range-Based For-Loop Iterator with Index
{ {
return {}; return {};
} }
/***********************************************************************
Optimized Range-Based For-Loop Iterator for ArrayBase
***********************************************************************/
template<typename T>
struct RangeBasedForLoopIteratorForList
{
protected:
const ArrayBase<T>& arrayBase;
vint index;
public:
RangeBasedForLoopIteratorForList(const ArrayBase<T>& _arrayBase)
: arrayBase(_arrayBase)
, index(0)
{
}
void operator++()
{
++index;
}
const T& operator*() const
{
return arrayBase.Get(index);
}
bool operator==(const RangeBasedForLoopEnding&) const
{
return index >= arrayBase.Count();
}
bool operator!=(const RangeBasedForLoopEnding&) const
{
return index < arrayBase.Count();
}
friend bool operator==(const RangeBasedForLoopEnding&, const RangeBasedForLoopIteratorForList<T>& iterator)
{
return iterator.index >= iterator.arrayBase.Count();
}
friend bool operator!=(const RangeBasedForLoopEnding&, const RangeBasedForLoopIteratorForList<T>& iterator)
{
return iterator.index < iterator.arrayBase.Count();
}
};
template<typename T>
RangeBasedForLoopIteratorForList<T> begin(const ArrayBase<T>& arrayBase)
{
return { arrayBase };
}
template<typename T>
RangeBasedForLoopEnding end(const ArrayBase<T>& arrayBase)
{
return {};
}
/***********************************************************************
Optimized Range-Based For-Loop Iterator for ArrayBase with Index
***********************************************************************/
template<typename T>
struct RangeBasedForLoopIteratorWithIndexForList : public RangeBasedForLoopIteratorForList<T>
{
public:
RangeBasedForLoopIteratorWithIndexForList(const ArrayBase<T>& arrayBase)
: RangeBasedForLoopIteratorForList<T>(arrayBase)
{
}
Tuple<const T&, vint> operator*() const
{
return { this->arrayBase.Get(this->index), this->index };
}
};
template<typename T>
struct ArrayBaseWithIndex
{
const ArrayBase<T>& arrayBase;
ArrayBaseWithIndex(const ArrayBase<T>& _arrayBase)
: arrayBase(_arrayBase)
{
}
};
template<typename T>
ArrayBaseWithIndex<T> indexed(const ArrayBase<T>& arrayBase)
{
return { arrayBase };
}
template<typename T>
RangeBasedForLoopIteratorWithIndexForList<T> begin(const ArrayBaseWithIndex<T>& wrapper)
{
return { wrapper.arrayBase };
}
template<typename T>
RangeBasedForLoopEnding end(const ArrayBaseWithIndex<T>& wrapper)
{
return {};
}
} }
} }
Binary file not shown.
Binary file not shown.