diff --git a/LaunchAPPL/Server/CMakeLists.txt b/LaunchAPPL/Server/CMakeLists.txt index 3bcfb51c8e..60a625f529 100644 --- a/LaunchAPPL/Server/CMakeLists.txt +++ b/LaunchAPPL/Server/CMakeLists.txt @@ -10,7 +10,10 @@ add_application(LaunchAPPLServer MacSerialStream.cc AppLauncher.h AppLauncher.cc - ToolLauncher.cc) + ToolLauncher.cc + StatusDisplay.h + StatusDisplay.cc +) target_link_libraries(LaunchAPPLServer LaunchAPPLCommon) set_target_properties(LaunchAPPLServer PROPERTIES diff --git a/LaunchAPPL/Server/LaunchAPPLServer.cc b/LaunchAPPL/Server/LaunchAPPLServer.cc index 0b272db9f4..1eabed27ec 100644 --- a/LaunchAPPL/Server/LaunchAPPLServer.cc +++ b/LaunchAPPL/Server/LaunchAPPLServer.cc @@ -33,9 +33,10 @@ #include "MacSerialStream.h" #include "AppLauncher.h" +#include "StatusDisplay.h" #include -#include "ServerProtocol.h" +#include #include #include #include @@ -190,64 +191,8 @@ void DoMenuCommand(long menuCommand) HiliteMenu(0); } +std::unique_ptr statusDisplay; -WindowPtr statusWindow; -Str255 statusString = "\p"; -int progressDone, progressTotal = 0; - -void DoUpdate(WindowRef w) -{ - if(w != statusWindow) - return; - -#if TARGET_API_MAC_CARBON - SetPortWindowPort(w); -#else - SetPort(w); -#endif - BeginUpdate(w); - EraseRect(&w->portRect); - - MoveTo(10,20); - DrawString(statusString); - - Rect r; - - if(progressTotal) - { - SetRect(&r, 10, 40, w->portRect.right-10, 60); - FrameRect(&r); - SetRect(&r, 10, 40, 10 + (w->portRect.right-20) * progressDone / progressTotal, 60); - PaintRect(&r); - } - - Str255 str; - NumToString(FreeMem(), str); - MoveTo(10,80); - DrawString(str); DrawString("\p / "); - NumToString(ApplicationZone()->bkLim - (Ptr)ApplicationZone(), str); - DrawString(str); DrawString("\p bytes free"); - - EndUpdate(w); -} - -enum class AppStatus -{ - ready = 1, - downloading = 2, - running = 3, - uploading = 4 -}; - -void SetStatus(AppStatus stat, int done = 0, int total = 0) -{ - GetIndString(statusString,128,(short)stat); - - progressTotal = total; - progressDone = done; - SetPort(statusWindow); - InvalRect(&statusWindow->portRect); -} class LaunchServer : public StreamListener { @@ -279,7 +224,7 @@ public: void onReset() { - SetStatus(AppStatus::ready, 0, 0); + statusDisplay->SetStatus(AppStatus::ready, 0, 0); state = State::command; } @@ -306,7 +251,7 @@ public: dataSize = *(const uint32_t*)(p+8); rsrcSize = *(const uint32_t*)(p+12); - SetStatus(AppStatus::downloading, 0, dataSize + rsrcSize); + statusDisplay->SetStatus(AppStatus::downloading, 0, dataSize + rsrcSize); FSDelete("\pRetro68App", 0); Create("\pRetro68App", 0, creator, type); @@ -326,7 +271,7 @@ public: FSWrite(refNum, &count, p); remainingSize -= count; - SetStatus(AppStatus::downloading, dataSize - remainingSize, dataSize + rsrcSize); + statusDisplay->SetStatus(AppStatus::downloading, dataSize - remainingSize, dataSize + rsrcSize); if(remainingSize) return count; @@ -347,14 +292,14 @@ public: FSWrite(refNum, &count, p); remainingSize -= count; - SetStatus(AppStatus::downloading, dataSize + rsrcSize - remainingSize, dataSize + rsrcSize); + statusDisplay->SetStatus(AppStatus::downloading, dataSize + rsrcSize - remainingSize, dataSize + rsrcSize); if(remainingSize) return count; FSClose(refNum); - SetStatus(AppStatus::running); + statusDisplay->SetStatus(AppStatus::running); state = State::launch; return count; @@ -382,7 +327,7 @@ void StartResponding(LaunchServer& server, ReliableStream& rStream) OpenDF("\pout", 0, &outRefNum); GetEOF(outRefNum, &outSize); outSizeRemaining = outSize; - SetStatus(AppStatus::uploading, 0, outSize); + statusDisplay->SetStatus(AppStatus::uploading, 0, outSize); rStream.write(&outSize, 4); rStream.flushWrite(); @@ -481,9 +426,8 @@ int main() AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(&aeQuit), 0, false); } - statusWindow = GetNewWindow(129, NULL, (WindowPtr) -1); - SetStatus(AppStatus::ready); - + statusDisplay = std::make_unique(); + { short refNum; if(OpenDF("\pLaunchAPPLServer Preferences", 0, &refNum) == noErr) @@ -569,7 +513,8 @@ int main() } break; case updateEvt: - DoUpdate((WindowRef)e.message); + if(statusDisplay && (WindowRef)e.message == statusDisplay->GetWindow()) + statusDisplay->Update(); break; case kHighLevelEvent: if(hasAppleEvents) @@ -582,7 +527,8 @@ int main() if(server.state != LaunchServer::State::wait) stream.idle(); - + statusDisplay->Idle(); + if(server.state == LaunchServer::State::launch) { gSerialStream->close(); @@ -621,13 +567,13 @@ int main() server.state = LaunchServer::State::wait; nullEventCounter = 0; - SetStatus(AppStatus::running, 0, 0); + statusDisplay->SetStatus(AppStatus::running, 0, 0); } else { server.state = LaunchServer::State::command; gSerialStream->open(); - SetStatus(AppStatus::ready, 0, 0); + statusDisplay->SetStatus(AppStatus::ready, 0, 0); } } else if(server.state == LaunchServer::State::wait && nullEventCounter > 3) @@ -651,7 +597,7 @@ int main() rStream.write(buf, count); outSizeRemaining -= count; } - SetStatus(AppStatus::uploading, outSize - outSizeRemaining, outSize); + statusDisplay->SetStatus(AppStatus::uploading, outSize - outSizeRemaining, outSize); if(outSizeRemaining == 0) { @@ -660,7 +606,7 @@ int main() if(outSizeRemaining == 0 && rStream.allDataArrived()) { server.state = LaunchServer::State::command; - SetStatus(AppStatus::ready, 0, 0); + statusDisplay->SetStatus(AppStatus::ready, 0, 0); rStream.reset(0); } } diff --git a/LaunchAPPL/Server/StatusDisplay.cc b/LaunchAPPL/Server/StatusDisplay.cc new file mode 100644 index 0000000000..af691aacb4 --- /dev/null +++ b/LaunchAPPL/Server/StatusDisplay.cc @@ -0,0 +1,107 @@ +#include "StatusDisplay.h" +#include +#include + +StatusDisplay::StatusDisplay() +{ + statusWindow = GetNewWindow(129, NULL, (WindowPtr) -1); + + Rect bounds = statusWindow->portRect; + + SetRect(&statusRect, 10, 0, bounds.right-10, 30); + SetRect(&progressRect, 10, 30, bounds.right-10, 46); + SetRect(&memRect, 10, 70, bounds.right-10, 100); + RgnHandle tmp = NewRgn(); + background = NewRgn(); + RectRgn(background, &bounds); + RectRgn(tmp, &progressRect); + DiffRgn(background, tmp, background); + DisposeRgn(tmp); + + SetStatus(AppStatus::ready); +} + +StatusDisplay::~StatusDisplay() +{ + DisposeWindow(statusWindow); + DisposeRgn(background); +} + +void StatusDisplay::Update() +{ +#if TARGET_API_MAC_CARBON + SetPortWindowPort(statusWindow); +#else + SetPort(statusWindow); +#endif + BeginUpdate(statusWindow); + EraseRgn(background); + + MoveTo(statusRect.left,statusRect.bottom-10); + DrawString(statusString); + + Rect r; + + if(progressTotal) + { + FrameRect(&progressRect); + InsetRect(&r, 1,1); + SetRect(&r, progressRect.left+1, progressRect.top+1, + progressRect.left+1 + (progressRect.right-progressRect.left-2) * progressDone / progressTotal, + progressRect.bottom-1); + FillRect(&r, &qd.dkGray); + r.left = r.right; + r.right = progressRect.right - 1; + FillRect(&r, &qd.ltGray); + } + else + EraseRect(&progressRect); + + Str255 str; + NumToString(freeMem, str); + MoveTo(memRect.left,memRect.bottom-10); + DrawString(str); DrawString("\p / "); + NumToString(ApplicationZone()->bkLim - (Ptr)ApplicationZone(), str); + DrawString(str); DrawString("\p bytes free"); + + EndUpdate(statusWindow); +} + +void StatusDisplay::Idle() +{ + long newFreeMem = FreeMem(); + if(newFreeMem != freeMem) + { + freeMem = newFreeMem; + SetPort(statusWindow); + InvalRect(&memRect); + } +} + +void StatusDisplay::SetStatus(AppStatus stat) +{ + if(stat != status) + { + status = stat; + GetIndString(statusString,128,(short)stat); + SetPort(statusWindow); + InvalRect(&statusRect); + } +} + +void StatusDisplay::SetProgress(int done, int total) +{ + if(done != progressDone || total != progressTotal) + { + progressTotal = total; + progressDone = done; + SetPort(statusWindow); + InvalRect(&progressRect); + } +} + +void StatusDisplay::SetStatus(AppStatus stat, int done, int total) +{ + SetStatus(stat); + SetProgress(done, total); +} diff --git a/LaunchAPPL/Server/StatusDisplay.h b/LaunchAPPL/Server/StatusDisplay.h new file mode 100644 index 0000000000..99e3c9f8a2 --- /dev/null +++ b/LaunchAPPL/Server/StatusDisplay.h @@ -0,0 +1,38 @@ +#include +#include +#include + +enum class AppStatus +{ + empty = 0, + ready = 1, + downloading = 2, + running = 3, + uploading = 4 +}; + +class StatusDisplay +{ + WindowPtr statusWindow; + Str255 statusString = "\p"; + AppStatus status = AppStatus::empty; + int progressDone, progressTotal = 0; + long freeMem; + + RgnHandle background; + Rect statusRect; + Rect progressRect; + Rect memRect; +public: + StatusDisplay(); + ~StatusDisplay(); + + WindowPtr GetWindow() { return statusWindow; } + void Update(); + + void Idle(); + + void SetStatus(AppStatus s); + void SetProgress(int done = 0, int total = 0); + void SetStatus(AppStatus stat, int done, int total); +};