diff --git a/src/tools/MonarchPeasantSample/Monarch.cpp b/src/tools/MonarchPeasantSample/Monarch.cpp index 1ef0bde4153..cb2883939de 100644 --- a/src/tools/MonarchPeasantSample/Monarch.cpp +++ b/src/tools/MonarchPeasantSample/Monarch.cpp @@ -8,24 +8,16 @@ using namespace winrt; using namespace winrt::Windows::Foundation; using namespace ::Microsoft::Console; -extern std::mutex m; -extern std::condition_variable cv; -extern bool dtored; - namespace winrt::MonarchPeasantSample::implementation { Monarch::Monarch() { printf("Instantiated a Monarch\n"); - // _peasants = winrt::single_threaded_observable_map(); } Monarch::~Monarch() { printf("~Monarch()\n"); - std::unique_lock lk(m); - dtored = true; - cv.notify_one(); } uint64_t Monarch::GetPID() @@ -35,8 +27,8 @@ namespace winrt::MonarchPeasantSample::implementation uint64_t Monarch::AddPeasant(winrt::MonarchPeasantSample::IPeasant peasant) { - // TODO: This whole algo is terrible. There's gotta be a better way of - // finding the first opening in a non-consecutive map of int->object + // TODO: This whole algorithm is terrible. There's gotta be a better way + // of finding the first opening in a non-consecutive map of int->object auto providedID = peasant.GetID(); if (providedID == 0) diff --git a/src/tools/MonarchPeasantSample/main.cpp b/src/tools/MonarchPeasantSample/main.cpp index aefba484766..8eec60b5519 100644 --- a/src/tools/MonarchPeasantSample/main.cpp +++ b/src/tools/MonarchPeasantSample/main.cpp @@ -10,9 +10,13 @@ using namespace winrt::Windows::Foundation; using namespace ::Microsoft::Console; //////////////////////////////////////////////////////////////////////////////// -std::mutex m; -std::condition_variable cv; -bool dtored = false; +// This seems liks a hack, but it works. +// +// This class factory works so that there's only ever one instance of a Monarch +// per-process. Once the first monarch is created, we'll stash it in g_weak. +// Future callers who try to instantiate a Monarch will get the one that's +// already been made. +// winrt::weak_ref g_weak{ nullptr }; struct MonarchFactory : implements @@ -52,6 +56,9 @@ struct MonarchFactory : implements }; //////////////////////////////////////////////////////////////////////////////// +// Function Description: +// - Register the Monarch object with COM. This allows other processes to create +// Monarch's in our process space with CoCreateInstance and the Monarch_clsid. DWORD registerAsMonarch() { DWORD registrationHostClass{}; @@ -63,6 +70,11 @@ DWORD registerAsMonarch() return registrationHostClass; } +// Function Description: +// - Called when the old monarch dies. Create a new connection to the new +// monarch. This might be us! If we're the new monarch, then update the +// Monarch to know which Peasant it came from. Otherwise, tell the new monarch +// that we exist. void electNewMonarch(AppState& state) { state._monarch = AppState::instantiateAMonarch(); @@ -83,9 +95,6 @@ void electNewMonarch(AppState& state) void appLoop(AppState& state) { - // Tricky - first, we have to ask the monarch to handle the commandline. - // They will tell us if we need to create a peasant. - auto dwRegistration = registerAsMonarch(); // IMPORTANT! Tear down the registration as soon as we exit. If we're not a // real peasant window (the monarch passed our commandline to someone else), @@ -95,15 +104,22 @@ void appLoop(AppState& state) check_hresult(CoRevokeClassObject(dwRegistration)); }); - // state.createMonarchAndPeasant(); + // Tricky - first, we have to ask the monarch to handle the commandline. + // They will tell us if we need to create a peasant. state.createMonarch(); - + // processCommandline will return true if we should exit early. if (state.processCommandline()) { return; } + bool isMonarch = state.areWeTheKing(true); bool exitRequested = false; + + // (monarch|peasant)AppLoop will return when they've run to completion. If + // they return true, then just exit the application (the user might have + // pressed 'q' to exit). If the peasant returns false, then it detected the + // monarch died. Attempt to elect a new one. while (!exitRequested) { if (isMonarch) @@ -127,6 +143,7 @@ int main(int argc, char** argv) AppState state; state.initializeState(); + // Collect up all the commandline arguments printf("args:["); for (auto& elem : wil::make_range(argv, argc)) {