From 5794be9dec63f7597833ca988e1237275f52a443 Mon Sep 17 00:00:00 2001
From: Joe Rayhawk <jrayhawk@fairlystable.org>
Date: Sat, 12 Nov 2022 16:39:35 -0800
Subject: Server.initialize: invalidate caches on reconnect

---
 src/obswebsocket.cr | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/src/obswebsocket.cr b/src/obswebsocket.cr
index e6f4623..8e15911 100644
--- a/src/obswebsocket.cr
+++ b/src/obswebsocket.cr
@@ -46,6 +46,7 @@ module OBSWebSocket
     @stats = OBSWebSocket::Stats.new( @@reqchan )
     @negotiated = false
     @connecterror = 0
+    @shutdown = false
     def negotiated?
       return @negotiated
     end
@@ -121,10 +122,13 @@ module OBSWebSocket
     end
     def initialize( uri : String, password : String | Nil = nil )
       spawn do
+        eventsubs = Array( Channel(JSON::Any) ).new # initialize this here to it survives across connection retries
         loop do
-          obs_pubsub = HTTP::WebSocket.new( URI.parse( uri ), HTTP::Headers{"Cookie" => "SESSIONID=1235", "Sec-WebSocket-Protocol" => "obswebsocket.json"} )
+          if @shutdown
+            break
+          end
+          @obs_pubsub = HTTP::WebSocket.new( URI.parse( uri ), HTTP::Headers{"Cookie" => "SESSIONID=1235", "Sec-WebSocket-Protocol" => "obswebsocket.json"} )
           openrequests = Hash( String, Channel( JSON::Any ) ).new
-          eventsubs = Array( Channel(JSON::Any) ).new
           #metachan = Channel( Tuple( String, Channel( JSON::Any ) ) ).new
           spawn do
             queue = Array( Tuple( Channel( JSON::Any ) | Nil, String ) ).new
@@ -138,7 +142,7 @@ module OBSWebSocket
                   if reschan
                     openrequests[ json["d"]["requestId"].as_s ] = reschan
                   end
-                  obs_pubsub.send( msg[1] )
+                  @obs_pubsub.send( msg[1] )
                 end
               elsif msgtuple[1] == "break"
                 break
@@ -155,12 +159,12 @@ module OBSWebSocket
                 if reschan
                   openrequests[ json["d"]["requestId"].as_s ] = reschan
                 end
-                obs_pubsub.send( msgtuple[1] )
+                @obs_pubsub.send( msgtuple[1] )
               elsif JSON.parse( msgtuple[1] )["op"].as_i64 == 1
                 print "SENT: "
                 json = JSON.parse( msgtuple[1] )
                 pp json
-                obs_pubsub.send( msgtuple[1] )
+                @obs_pubsub.send( msgtuple[1] )
               else
                 print "QUEUED: "
                 pp msgtuple[1]
@@ -168,7 +172,7 @@ module OBSWebSocket
               end
             end
           end
-          obs_pubsub.on_message do | message |
+          @obs_pubsub.on_message do | message |
             json = JSON.parse( message )
             print( "RECEIVED: ")
             print( json.to_pretty_json )
@@ -271,7 +275,7 @@ module OBSWebSocket
               Fiber.yield
             end
           end
-          obs_pubsub.run
+          @obs_pubsub.run
         rescue ex : Socket::ConnectError | IO::Error
           if @connecterror < 3
             print ex.message
@@ -283,14 +287,25 @@ module OBSWebSocket
           pp ex
           pp ex.backtrace?
         ensure
-          obs_pubsub && obs_pubsub.close
+          @obs_pubsub && @obs_pubsub.close
           @negotiated = false
           @@reqchan.send( { nil, "break" } ) # ask reader fiber to terminate
-          # Should we invalidate all the cached ORM data here?
           sleep 10
+          # invalidate state on everything
+          @scenecollection = OBSWebSocket::SceneCollection.new( @@reqchan, @@inputs )
+          @@inputs = OBSWebSocket::Inputs.new( @@reqchan )
+          @@scenes = OBSWebSocket::SceneList.new( @@reqchan, @@inputs )
+          @sources = OBSWebSocket::Sources.new( @@reqchan, @@inputs, @@scenes )
+          @outputs = OBSWebSocket::Outputs.new( @@reqchan )
+          @video = OBSWebSocket::VideoSettings.new( @@reqchan )
+          @stats = OBSWebSocket::Stats.new( @@reqchan )
         end
       end
     end
+    def close
+      @shutdown = true
+      @obs_pubsub && @obs_pubsub.close
+    end
   end
 
   class Outputs
-- 
cgit v1.2.3