diff --git a/src/tools/MonarchPeasantSample/AppState.cpp b/src/tools/MonarchPeasantSample/AppState.cpp index 5f6a9d41407..2d469964b3f 100644 --- a/src/tools/MonarchPeasantSample/AppState.cpp +++ b/src/tools/MonarchPeasantSample/AppState.cpp @@ -82,12 +82,6 @@ MonarchPeasantSample::IPeasant AppState::_createOurPeasant() return *peasant; } -// void AppState::createMonarchAndPeasant() -// { -// _monarch = AppState::instantiateAMonarch(); -// _peasant = _createOurPeasant(); -// } - void AppState::createMonarch() { _monarch = AppState::instantiateAMonarch(); diff --git a/src/tools/MonarchPeasantSample/AppState.h b/src/tools/MonarchPeasantSample/AppState.h index e63160b5e69..0c8389769ca 100644 --- a/src/tools/MonarchPeasantSample/AppState.h +++ b/src/tools/MonarchPeasantSample/AppState.h @@ -17,7 +17,7 @@ class AppState winrt::MonarchPeasantSample::Monarch _monarch{ nullptr }; static winrt::MonarchPeasantSample::Monarch instantiateAMonarch(); - // void createMonarchAndPeasant(); + void createMonarch(); bool processCommandline(); void remindKingWhoTheyAre(const winrt::MonarchPeasantSample::IPeasant& peasant); @@ -36,16 +36,31 @@ bool peasantAppLoop(AppState& state); /* +Useful test script: + +pushd %OPENCON%\bin\x64\Debug\MonarchPeasantSample +wt -d . cmd /k MonarchPeasantSample.exe ; sp -d . cmd /k MonarchPeasantSample.exe ; sp -d . cmd /k MonarchPeasantSample.exe ; sp -d . +popd + + BIG OLE TODO LIST: +* [x] The peasants need to be able to process commandlines passed to them by + other peasants +* [x] press a key in a peasant window to "activate" it +* [x] Add a key to toggle the monarch through ["never", "lastActive", "always"] + glomming behaviors +* [ ] Actually store a stack for the MRU peasant, not just the single MRU one * [ ] The Monarch needs to wait on peasants, to remove them from the map when they're dead -* [ ] The peasants need to be able to process commandlines passed to them by - other peasants -* [ ] press a key in a peasant window to "activate" it -* [ ] Add a key to toggle the monarch through ["never", "lastActive", "always"] - glmming behaviors * [ ] Actually implement the "list peasants" thing * [ ] After an election, the entire MRU window state is lost, because it was only stored in the current monarch. +* [ ] Test: + - Create a monarch(#1) & peasant(#2) + - activate the peasant(#2) + - exit the peasant(#2) + - try running mps.exe -s 0 (or -s 2) + - THIS WILL FAIL, but it _should_ just run the commandline in the monarch + (in the case of `-s 0`) or in a new window (in the `-s 1` case) */ diff --git a/src/tools/MonarchPeasantSample/Monarch.cpp b/src/tools/MonarchPeasantSample/Monarch.cpp index cb2883939de..b2f74508b25 100644 --- a/src/tools/MonarchPeasantSample/Monarch.cpp +++ b/src/tools/MonarchPeasantSample/Monarch.cpp @@ -43,14 +43,22 @@ namespace winrt::MonarchPeasantSample::implementation } auto newPeasantsId = peasant.GetID(); _peasants[newPeasantsId] = peasant; - _mostRecentPeasant = newPeasantsId; + _setMostRecentPeasant(newPeasantsId); printf("(the next new peasant will get the ID %lld)\n", _nextPeasantID); + + peasant.WindowActivated({ this, &Monarch::_peasantWindowActivated }); + return newPeasantsId; } - bool Monarch::IsInSingleInstanceMode() + void Monarch::_peasantWindowActivated(const winrt::Windows::Foundation::IInspectable& sender, + const winrt::Windows::Foundation::IInspectable& /*args*/) { - return false; + if (auto peasant{ sender.try_as() }) + { + auto theirID = peasant.GetID(); + _setMostRecentPeasant(theirID); + } } winrt::MonarchPeasantSample::IPeasant Monarch::GetPeasant(uint64_t peasantID) @@ -63,14 +71,20 @@ namespace winrt::MonarchPeasantSample::implementation return nullptr; } + void Monarch::_setMostRecentPeasant(const uint64_t peasantID) + { + _mostRecentPeasant = peasantID; + printf("\x1b[90mThe most recent peasant is now \x1b[m#%llu\n", _mostRecentPeasant); + } + void Monarch::SetSelfID(const uint64_t selfID) { - _thisPeasantID = selfID; + this->_thisPeasantID = selfID; // TODO: Right now, the monarch assumes the role of the most recent // window. If the monarch dies, and a new monarch takes over, then the // entire stack of MRU windows will go with it. That's not what you // want! - _mostRecentPeasant = _thisPeasantID; + _setMostRecentPeasant(_thisPeasantID); } bool Monarch::ProposeCommandline(array_view args, winrt::hstring cwd) @@ -112,10 +126,12 @@ namespace winrt::MonarchPeasantSample::implementation printf("Found a commandline intended for session %d\n", sessionId); if (sessionId < 0) { - createNewWindow = false; + printf("That certainly isn't a valid ID, they should make a new window.\n"); + createNewWindow = true; } else if (sessionId == 0) { + printf("Session 0 is actually #%llu\n", _mostRecentPeasant); if (auto mruPeasant = GetPeasant(_mostRecentPeasant)) { mruPeasant.ExecuteCommandline(args, cwd); @@ -129,6 +145,10 @@ namespace winrt::MonarchPeasantSample::implementation otherPeasant.ExecuteCommandline(args, cwd); createNewWindow = false; } + else + { + printf("I couldn't find a peasant for that ID, they should make a new window.\n"); + } } } } diff --git a/src/tools/MonarchPeasantSample/Monarch.h b/src/tools/MonarchPeasantSample/Monarch.h index 98ae4ebb42f..d7d55ac05b1 100644 --- a/src/tools/MonarchPeasantSample/Monarch.h +++ b/src/tools/MonarchPeasantSample/Monarch.h @@ -30,8 +30,6 @@ namespace winrt::MonarchPeasantSample::implementation uint64_t AddPeasant(winrt::MonarchPeasantSample::IPeasant peasant); - bool IsInSingleInstanceMode(); - winrt::MonarchPeasantSample::IPeasant GetPeasant(uint64_t peasantID); winrt::MonarchPeasantSample::IPeasant GetMostRecentPeasant(); @@ -45,8 +43,13 @@ namespace winrt::MonarchPeasantSample::implementation uint64_t _nextPeasantID{ 1 }; uint64_t _thisPeasantID{ 0 }; uint64_t _mostRecentPeasant{ 0 }; - GlomToLastWindow _windowingBehavior{ GlomToLastWindow::LastActive }; + GlomToLastWindow _windowingBehavior{ GlomToLastWindow::Never }; std::unordered_map _peasants; + + void _setMostRecentPeasant(const uint64_t peasantID); + + void _peasantWindowActivated(const winrt::Windows::Foundation::IInspectable& sender, + const winrt::Windows::Foundation::IInspectable& args); }; } diff --git a/src/tools/MonarchPeasantSample/Monarch.idl b/src/tools/MonarchPeasantSample/Monarch.idl index 633c9f05966..2d396c18302 100644 --- a/src/tools/MonarchPeasantSample/Monarch.idl +++ b/src/tools/MonarchPeasantSample/Monarch.idl @@ -7,7 +7,7 @@ namespace MonarchPeasantSample UInt64 GetPID(); UInt64 AddPeasant(IPeasant peasant); - Boolean IsInSingleInstanceMode(); + IPeasant GetPeasant(UInt64 peasantID); IPeasant GetMostRecentPeasant(); diff --git a/src/tools/MonarchPeasantSample/Peasant.cpp b/src/tools/MonarchPeasantSample/Peasant.cpp index 0ad1d5b077a..a38013a041b 100644 --- a/src/tools/MonarchPeasantSample/Peasant.cpp +++ b/src/tools/MonarchPeasantSample/Peasant.cpp @@ -43,4 +43,9 @@ namespace winrt::MonarchPeasantSample::implementation return true; } + void Peasant::raiseActivatedEvent() + { + _WindowActivatedHandlers(*this, nullptr); + } + } diff --git a/src/tools/MonarchPeasantSample/Peasant.h b/src/tools/MonarchPeasantSample/Peasant.h index e3309ff356c..75e44695875 100644 --- a/src/tools/MonarchPeasantSample/Peasant.h +++ b/src/tools/MonarchPeasantSample/Peasant.h @@ -23,6 +23,8 @@ namespace winrt::MonarchPeasantSample::implementation bool ExecuteCommandline(winrt::array_view args, winrt::hstring currentDirectory); + void raiseActivatedEvent(); + TYPED_EVENT(WindowActivated, winrt::Windows::Foundation::IInspectable, winrt::Windows::Foundation::IInspectable); private: diff --git a/src/tools/MonarchPeasantSample/Peasant.idl b/src/tools/MonarchPeasantSample/Peasant.idl index fc3c4eddab3..699a99a5f81 100644 --- a/src/tools/MonarchPeasantSample/Peasant.idl +++ b/src/tools/MonarchPeasantSample/Peasant.idl @@ -4,14 +4,14 @@ namespace MonarchPeasantSample { interface IPeasant { - void AssignID(UInt64 id); // Should only be called by the monarch + void AssignID(UInt64 id); UInt64 GetID(); UInt64 GetPID(); Boolean ExecuteCommandline(String[] args, String currentDirectory); event Windows.Foundation.TypedEventHandler WindowActivated; } - [default_interface] runtimeclass Peasant : IPeasant // : IScratchInterface + [default_interface] runtimeclass Peasant : IPeasant { Peasant(); }; diff --git a/src/tools/MonarchPeasantSample/PeasantMain.cpp b/src/tools/MonarchPeasantSample/PeasantMain.cpp index c380446294d..9e8559a9e3c 100644 --- a/src/tools/MonarchPeasantSample/PeasantMain.cpp +++ b/src/tools/MonarchPeasantSample/PeasantMain.cpp @@ -30,6 +30,16 @@ bool peasantReadInput(AppState& state) { return true; } + else + { + printf("This window was activated\n"); + winrt::com_ptr peasantImpl; + peasantImpl.copy_from(winrt::get_self(state._peasant)); + if (peasantImpl) + { + peasantImpl->raiseActivatedEvent(); + } + } break; }