plac

Roon remote in GTK4

Commits at 347297ee11a7b9315451271b43536edef518a9e1

  1. ac959c70 core: Remove macOS build output It's no longer used. Shota FUJI authored at Shota FUJI comitted at
  2. 87a170f9 macos: Implement core logic in Swift Managing long-live object and handling IO in C API was mistake. Every Zig/Swift nicities are eliminated at C API boundary. It must be stupid make/free (or retain/release) function calls and they always have to be heap allocoated using cAllocator. Everything has to be thread-safe by using manual reference counting. Good practices in each languages are no longer available due to C API barrier. Although I had to duplicated Roon API handling logic, I believe this work is worth the added code. IO and concurrent things are done in a Swift-y way, avoiding small heap allocations are now easier (I guess it's already less than the previous?), and most importantly, I have deeper understandings of Swift and Apple frameworks than before. UI layer code is way cleaner than the before. Especially watching incoming message is very ergnomic--I can just iterate on `compactMap`-ed async iterator, as you can see in "plac/DataModel/ZoneDataModel.swift". As a bonus, every async task now handles cancellation (e.g. closing window) perfectly. In terms of performance, I don't think there is any regression. Moreover, I feel this rewrite version performs better. Not profiled (I've never profiled Plac macOS app...) but playback control actions are instant without any UI stutter. Considering it now uses more high-level API provided by Apple, this rewrite should improve stability and portability. Despite of these good things, there is one I'm not satisfied with--message parsing (MOO / SOOD.) Swift does not have a good reader/writer interface unlike Zig. The closest thing is SwiftNIO's `ByteBuffer`, but I avoided it to keep dependence to third-party libraries lower (the repository is in Apple org, though.) I've considered using Zig code for that part or write a dedicated C module using Wuffs but abandoned the ideas too, because of Xcode signing gotchas (ugh.) Speaking of Xcode signing, the app now works on iOS simulator. It probably won't work on real device due to multicast entitlement, but this is huge advancement. Some entry point tweaks are necessary, like UI for entering IP/port of Roon server. Revising suspension and resume is also necessary. Not ready to use, but this is great starting point. Overall, I'm satisfied the result and enjoyed this whole learning process. Shota FUJI authored at Shota FUJI comitted at
  3. 03091367 macos: Display now playing artwork Shota FUJI authored at Shota FUJI comitted at
  4. 92b7d54f core: C API for getting image URL SwiftUI has AsyncImage view, which takes a URL. Shota FUJI authored at Shota FUJI comitted at
  5. 4cafdb7f macos: Use Environment for passing connection down Future views such as artwork requires connection, but passing a connection down to each view via initializer is tedious. Shota FUJI authored at Shota FUJI comitted at
  6. 84d0916a macos: Disconnect on window close Shota FUJI authored at Shota FUJI comitted at
  7. 19572656 macos: Playback controls Shota FUJI authored at Shota FUJI comitted at
  8. 619caed7 macos: Start message loop earlier Shota FUJI authored at Shota FUJI comitted at
  9. a4dd6513 macos: Save IP/port for quick connection Shota FUJI authored at Shota FUJI comitted at
  10. fc8a826e macos: Save and restore authorization token Shota FUJI authored at Shota FUJI comitted at
  11. 4570e084 macos: Disconnect menu items In GTK-Adwaita, it's easy thanks to "gsettings" CLI application. In macOS, however, there seems to no way to clear an application's "@AppStorage" data. Shota FUJI authored at Shota FUJI comitted at
  12. 3b0a3dc9 core: Expose disconnect function Shota FUJI authored at Shota FUJI comitted at
  13. cf516079 macos: Accept Xcode project settings recommendation It has been showing a warning and it was annoying. Shota FUJI authored at Shota FUJI comitted at
  14. 1dd7aab4 macos: Change non-modified variable to immutable Addressed a Xcode warning. Shota FUJI authored at Shota FUJI comitted at
  15. afb2d6b4 macos: Merge server discovery and main window The former is (most of the case) shown once. The reason I changed the payload of ".found" case is, without that, the only reference will be "ConnectedView" and every updates to the View would release then re-create a connection. Shota FUJI authored at Shota FUJI comitted at
  16. d53ccec3 macos: Save connected server ID and reconnect on launch The current UX is not complete, as there is no way to disconnect. Considering the usecase of connecting to more than one Roon server is rare, the discovery window should be integrated into the main window. Then it can conditionally render server discovery or connected view without going to discovery view first. Shota FUJI authored at Shota FUJI comitted at
  17. 37c16ed0 core: Allow clients to set custom extension ID/name/version It has been pain to manage authorization tokens in Roon settings page. Shota FUJI authored at Shota FUJI comitted at
  18. dfc4cec0 macos: Display loading UI during extension authorization It has been unclear what it's doing and what a user should do. Shota FUJI authored at Shota FUJI comitted at
  19. 2bb754a9 macos: Polish PlaybackBar It was bit odd. Shota FUJI authored at Shota FUJI comitted at
  20. 8b8802c2 macos: Display now playing texts (title and artist, mostly) Shota FUJI authored at Shota FUJI comitted at
  21. 9e6bf7bf macos: Fix more than one element in array crashes application I don't know how I got to that iteration code, but the `UnsafePointer<T>.successor` is NOT a method to iterate over an array. <https://codeberg.org/pocka/plac/issues/17> Shota FUJI authored at Shota FUJI comitted at
  22. c972d09c macos: Fix app crash when server scan found nothing Shota FUJI authored at Shota FUJI comitted at
  23. 065d06d6 core: Print debug log on macOS build Ideally, integrating OSLog is the best. However, it's time-consuming and a lot of work needs to be done. This is good for now. Shota FUJI authored at Shota FUJI comitted at
  24. 790bc7fc macos: Fix crash on network error at server discovery Shota FUJI authored at Shota FUJI comitted at
  25. 8fdfb08d gtk-adwaita: Remove "develop build" style from window Even though there is some missing features (search and disconnect menu option,) it's usable for my day-to-day usage. Now all concurrency and memory bugs are fixed, this is the best timing to remove WIP label. Shota FUJI authored at Shota FUJI comitted at
  26. 5ed1b013 core: Give WS read and event handlers dedicated threads <https://codeberg.org/pocka/plac/issues/16> Parsing and handling incoming message in the same thread that reads WebSocket message from socket sometime drops WebSocket message, due to the thread being busy. This redesign solves that by separating reading and parsing/handling using dedicated threads. Although volume change operation now feels little bit sluggish, no more dropped response. Every operation is working correctly. Shota FUJI authored at Shota FUJI comitted at
  27. 12dfcdb9 core: Fix potential race condition Extremely rare, though (I saw only once.) Shota FUJI authored at Shota FUJI comitted at
  28. 03235177 core: Output request ID on control request send log "/control" endpoint suffers response loss as well as "/change_volume" endpoint. Request ID helps debugging this, because it's visible on data payload in Wireshark. Shota FUJI authored at Shota FUJI comitted at
  29. 05a6f716 gtk-adwaita: Volume controls While "it works," user experience is not great. For some reason, response for "/change_volume" got lost even though my machine sees a TCP packet. I also see this at "/control" endpoint too. However, "/seek" endpoint, which is called more frequently, does not encounter this. Most likely application problem given my experience on low-level programming, but it could be packet issue (Roon Server) or transport layer issue (websocket.zig or Linux?) I don't know, really. Shota FUJI authored at Shota FUJI comitted at
  30. 0a075ca6 core: Volume change functions Shota FUJI authored at Shota FUJI comitted at