/// <summary> /// Consume a single message off the read queue. /// </summary> private void ConsumeMessage() { messages.Read((target, header, ptr) => { lastUpdateFromUnity = DateTime.Now; if (!handlers.ContainsKey(header.type)) { InteropLogger.Warning($"Unhandled request type {header.type} for {target}"); return(0); } return(handlers[header.type](target, ptr)); }); }
/// <summary> /// Consume a single message off the interop message queue /// </summary> /// <returns>Number of bytes read</returns> private int ConsumeMessage() { var disconnected = false; var bytesRead = messages.Read((target, header, ptr) => { // While not connected - only accept connection requests if (!IsConnected) { if (header.type != RpcRequest.Connect) { Debug.LogWarning($"Unhandled request type {header.type} for {target} - expected RpcRequest.Connect"); } blenderState = FastStructure.PtrToStructure <InteropBlenderState>(ptr); OnConnectToBlender(); return(0); } switch (header.type) { case RpcRequest.UpdateBlenderState: blenderState = FastStructure.PtrToStructure <InteropBlenderState>(ptr); break; case RpcRequest.Disconnect: // Don't call OnDisconnectFromBlender() from within // the read handler - we want to release the read node // safely first before disposing the connection. disconnected = true; break; // Viewport messages case RpcRequest.AddViewport: AddViewport( target, FastStructure.PtrToStructure <InteropViewport>(ptr) ); break; case RpcRequest.RemoveViewport: RemoveViewport(target); break; case RpcRequest.UpdateViewport: GetViewport(target).UpdateFromInterop( FastStructure.PtrToStructure <InteropViewport>(ptr) ); break; case RpcRequest.UpdateVisibleObjects: var visibleObjectIds = new int[header.count]; FastStructure.ReadArray(visibleObjectIds, ptr, 0, header.count); GetViewport(target).SetVisibleObjects( visibleObjectIds ); break; // Object messages case RpcRequest.AddObjectToScene: AddObject( target, FastStructure.PtrToStructure <InteropSceneObject>(ptr) ); break; case RpcRequest.RemoveObjectFromScene: RemoveObject(target); break; case RpcRequest.UpdateSceneObject: UpdateObject( target, FastStructure.PtrToStructure <InteropSceneObject>(ptr) ); break; // Mesh messages case RpcRequest.UpdateTriangles: GetOrCreateMesh(target) .triangles .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; case RpcRequest.UpdateVertices: GetOrCreateMesh(target) .vertices .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; case RpcRequest.UpdateNormals: GetOrCreateMesh(target) .normals .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; case RpcRequest.UpdateUV: GetOrCreateMesh(target) .uv .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; case RpcRequest.UpdateUV2: GetOrCreateMesh(target) .uv2 .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; case RpcRequest.UpdateUV3: GetOrCreateMesh(target) .uv3 .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; case RpcRequest.UpdateUV4: GetOrCreateMesh(target) .uv4 .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; case RpcRequest.UpdateVertexColors: GetOrCreateMesh(target) .colors .Resize(header.length) .CopyFrom(ptr, header.index, header.count); break; // TODO: ... and so on for weights/bones/etc case RpcRequest.UpdateMesh: GetOrCreateMesh(target).UpdateFromInterop( FastStructure.PtrToStructure <InteropMesh>(ptr) ); break; // Texture messages case RpcRequest.UpdateTexture: GetTexture(target).UpdateFromInterop( FastStructure.PtrToStructure <InteropTexture>(ptr) ); break; case RpcRequest.UpdateTextureData: GetTexture(target).CopyFrom( ptr, header.index, header.count, header.length ); break; default: Debug.LogWarning($"Unhandled request type {header.type} for {target}"); break; } // TODO: Necessary to count bytes? We won't read anything off this // buffer at this point so it's safe to drop the whole thing. // bytesRead will count the header size (indicating a message *was* read) return(0); }); // Handle any disconnects that may have occured during the read if (disconnected) { OnDisconnectFromBlender(); } return(bytesRead); }
/// <summary> /// Handle any messages coming from Blender /// </summary> private void ConsumeMessages() { Profiler.BeginSample("Consume Message"); var disconnected = false; // TODO: Some messages should be skipped if !IsConnected. // Otherwise we may get a bad state. E.g. we see a disconnect // from Blender and THEN some other viewport/object data messages. messages.Read((target, header, ptr) => { ObjectController obj; switch (header.type) { case RpcRequest.Connect: blenderState = FastStructure.PtrToStructure <InteropBlenderState>(ptr); OnConnectToBlender(); break; case RpcRequest.UpdateBlenderState: blenderState = FastStructure.PtrToStructure <InteropBlenderState>(ptr); break; case RpcRequest.Disconnect: // Don't call OnDisconnectFromBlender() from within // the read handler - we want to release the read node // safely first before disposing the connection. disconnected = true; break; case RpcRequest.AddViewport: AddViewport( target, FastStructure.PtrToStructure <InteropViewport>(ptr) ); break; case RpcRequest.RemoveViewport: RemoveViewport(target); break; case RpcRequest.UpdateViewport: GetViewport(target).UpdateFromInterop( FastStructure.PtrToStructure <InteropViewport>(ptr) ); break; case RpcRequest.UpdateVisibleObjects: var visibleObjectIds = new int[header.count]; FastStructure.ReadArray(visibleObjectIds, ptr, 0, header.count); GetViewport(target).SetVisibleObjects( visibleObjectIds ); break; case RpcRequest.AddObjectToScene: AddObject( target, FastStructure.PtrToStructure <InteropSceneObject>(ptr) ); break; case RpcRequest.RemoveObjectFromScene: RemoveObject(target); break; case RpcRequest.UpdateSceneObject: GetObject(target).UpdateFromInterop( FastStructure.PtrToStructure <InteropSceneObject>(ptr) ); break; case RpcRequest.UpdateTriangles: obj = GetObject(target); FastStructure.ReadArray(obj.GetOrCreateTriangleBuffer(), ptr, header.index, header.count); obj.OnUpdateTriangleRange(header.index, header.count); break; case RpcRequest.UpdateVertices: obj = GetObject(target); FastStructure.ReadArray(obj.GetOrCreateVertexBuffer(), ptr, header.index, header.count); obj.OnUpdateVertexRange(header.index, header.count); break; case RpcRequest.UpdateNormals: obj = GetObject(target); FastStructure.ReadArray(obj.GetOrCreateNormalBuffer(), ptr, header.index, header.count); obj.OnUpdateNormalRange(header.index, header.count); break; // TODO: ... and so on for UV/weights default: Debug.LogWarning($"Unhandled request type {header.type} for {target}"); break; } // TODO: Necessary to count bytes? We won't read anything off this // buffer at this point so it's safe to drop the whole thing. return(0); }); // Handle any disconnects that may have occured during the read if (disconnected) { OnDisconnectFromBlender(); } Profiler.EndSample(); }