public bool ReplaceOrQueue <T>(RpcRequest type, string target, ref T data) where T : struct { var header = new InteropMessageHeader { type = type, index = 0, count = 0 }; var payload = FastStructure.ToBytes(ref data); // If it's already queued, replace the payload var queued = FindQueuedMessage(target, ref header); if (queued != null) { queued.payload = payload; return(true); } outboundQueue.Enqueue(new InteropMessage { target = target, header = header, payload = payload }); return(false); }
/// <summary> /// Queue an outbound message containing a <typeparamref name="T"/> payload /// </summary> /// <typeparam name="T"></typeparam> /// <param name="target"></param> /// <param name="type"></param> /// <param name="data"></param> public void Queue <T>(RpcRequest type, string target, ref T data) where T : struct { outboundQueue.Enqueue(new InteropMessage { target = target, header = new InteropMessageHeader { type = type, index = 0, count = 0 }, payload = FastStructure.ToBytes(ref data) }); }
/// <summary> /// Copy the RenderTexture data from the ViewportController into shared memory with Blender. /// /// <para> /// The <paramref name="pixelsRGB24Func"/> callback is executed IFF we have room in the /// buffer to write - letting us skip the heavy pixel copy operations if the consumer /// is backed up in processing data. /// </para> /// </summary> internal void PublishRenderTexture(ViewportController viewport, Func <byte[]> pixelsRGB24Func) { if (!IsConnected) { Debug.LogWarning("Cannot send RT - No connection"); } Profiler.BeginSample("Write wait on pixelsProducer"); int bytesWritten = pixelsProducer.Write((ptr) => { // If we have a node we can write on, actually do the heavy lifting // of pulling the pixel data from the RenderTexture (in the callback) // and write into the buffer. var pixelsRGB24 = pixelsRGB24Func(); Profiler.BeginSample("Write Pixels into Shared Memory"); // Pack a header into shared memory var header = new InteropRenderHeader { viewportId = viewport.ID, width = viewport.Width, height = viewport.Height }; var headerSize = FastStructure.SizeOf <InteropRenderHeader>(); FastStructure.WriteBytes(ptr, FastStructure.ToBytes(ref header), 0, headerSize); // Copy render image data into shared memory FastStructure.WriteBytes(ptr + headerSize, pixelsRGB24, 0, pixelsRGB24.Length); /*InteropLogger.Debug($"Writing {pixelsRGB24.Length} bytes with meta {header.width} x {header.height} and pix 0 is " + * $"{pixelsRGB24[0]}, {pixelsRGB24[1]}, {pixelsRGB24[2]}" * );*/ Profiler.EndSample(); return(headerSize + pixelsRGB24.Length); }, WRITE_WAIT); /* * if (bytesWritten < 1) * { * Debug.LogWarning("pixelsProducer buffer is backed up. Skipped write."); * }*/ Profiler.EndSample(); }
public bool ReplaceOrQueue <T>(RpcRequest type, string target, ref T data) where T : struct { var header = new InteropMessageHeader { type = type, index = 0, length = 0, count = 0 }; var payload = FastStructure.ToBytes(ref data); // If it's already queued, replace the payload /*var queued = FindQueuedMessage(target, ref header); * if (queued != null) * { * queued.payload = payload; * return true; * }*/ // Remove the old one to then queue up one at the end // This ensures messages that are queued up together // remain in their queued order. RemoveQueuedMessage(target, ref header); InteropLogger.Debug($" ROQ-> {target}:{header.type:F}"); outboundQueue.Enqueue(new InteropMessage { target = target, header = header, payload = payload }); return(false); }