OK, went ahead and played with StreamController and built something anyway. Just pushed tiltontec.example.x020-reactive-stream. The beef:
(defn make-app []
(fx/material-app
{:title "Flutter/MX Counter Demo"
:theme (m/ThemeData .primarySwatch m.Colors/blue)}
(fx/scaffold
{:appBar (fx/app-bar
{:title (m/Text "Welcome to Flutter/MX World")})
:floatingActionButton
(cF (fx/floating-action-button
{:onPressed (as-dart-callback []
(.add (.-sink ^#/(async/StreamController String) (mget me :messages)) "ping"))
:tooltip "Increment"}
{
:name :clicker-fab
:messages (new #/(async/StreamController String))
}
(m/Icon m.Icons/add .color m.Colors/black)))}
(fx/center
(fx/column
{:mainAxisAlignment m.MainAxisAlignment/center}
(fx/text {:style (p/TextStyle .color m.Colors/black
.fontSize 18.0)}
"Traffic so far:")
(fx/text!
{:style (fx/in-my-context [me ctx]
(.-headline4 (.-textTheme (m.Theme/of ctx))))}
{:name :z-counter
:click-source (cF+ [;; todo validate options, ie :watch, not :obs
:watch (fn [_ me ^#/(async/StreamController String) new-source _ _]
;; todo when old unlisten
(.listen (.-stream ^#/(async/StreamController String) new-source)
(fn [^String msg]
(with-integrity [:change :click-heard]
(mswap! me :messages-heard inc)))))]
(mget (fm* :clicker-fab) :messages))
:messages-heard (cI 0)}
(str "msgs heard " (mget me :messages-heard))))))))
This is crazy simple, but might help implement code handling an external Stream.
Not sure if this is what you had in mind, @zenflowapp.Also not sure if I am even using the Dart Streams API correctly, so feel free anyone to critique!
Sorry for the late response, and thank you for the explanation and the example! The context for this is trying to wrap https://github.com/boskokg/flutter_blue_plus and the example code in dart I'm referencing is here: https://github.com/boskokg/flutter_blue_plus/blob/master/example/lib/main.dart
Forgot to mention I swiped the Counter demo code to create the streaming hack, explaining any oddities such as the "Increment" tooltip. 🙂
Wow, Flutter Blue looks nice and simple...oops. Gotta talk to location services for authorization. There's a lost week! 🤣
Anyway, I am reminded of the TodoMVC demo, which has to begin by asynchronously getting an instance of shared preferences: https://github.com/kennytilton/flutter-mx/blob/32044a21ae2f0047b2cbf0c71c2f3a7739c5956f/src/tiltontec/demo/todoMVC/core.cljd#L83,
...and "wait" for that instance to be retrieved (signified by it reactively going from nil to not nil) before using it: https://github.com/kennytilton/flutter-mx/blob/32044a21ae2f0047b2cbf0c71c2f3a7739c5956f/src/tiltontec/demo/todoMVC/core.cljd#L83
That shared prefs instance feels like a global, so I make it a property of the top of the MX tree, and load it into an async formula (sth new, by the way, created once I saw how Flutter leaned hard on async).
Reactive rocks, but sometimes the "steady state" quality makes us think a bit to express such procedural sequences reactively.
Final thought: I am already wondering if a stream formula would make sense, but I feel like open-coding a few stream varieties first to get the lay of the land.
Do you have enough to continue, or can I enhance that example?
I think that will do it, thanks!
Cleaned up the streams demo and also replicated to the sandbox repo: https://github.com/kennytilton/flutter-mx-sandbox/blob/main/src/tiltontec/example/x020_reactive_stream.cljd Nothing substantial changed. FYI