public void Issue20() { RpcRequest <ArithmeticOperationRequest> rpcRequest = new RpcRequest <ArithmeticOperationRequest>(); rpcRequest.Method = "AddTwoNumbers"; ArithmeticOperationRequest request = new ArithmeticOperationRequest(); request.NumA = 5; request.NumB = 8; rpcRequest.Request = request; var msg = MessageBuilder.Create(); var root = msg.BuildRoot <RpcRequest <ArithmeticOperationRequest> .WRITER>(); rpcRequest.serialize(root); var mems = new MemoryStream(); var pump = new FramePump(mems); pump.Send(msg.Frame); mems.Seek(0, SeekOrigin.Begin); var frame = Framing.ReadSegments(mems); var deserializer = DeserializerState.CreateRoot(frame); var mainRequest = new RpcRequest <ArithmeticOperationRequest> .READER(deserializer); var innerRequest = new ArithmeticOperationRequest.READER(mainRequest.Request); Console.WriteLine("Method Name: " + mainRequest.Method); Console.WriteLine("NumA: " + innerRequest.NumA.ToString()); Console.WriteLine("NumB: " + innerRequest.NumB.ToString()); }
public void Forward(WireFrame frame) { _pump.Send(frame); }
public void PipedFramePump() { int UnpackFrame(WireFrame frame) { int count = frame.Segments.Count; for (int i = 0; i < count; i++) { Assert.AreEqual(i + 1, frame.Segments[i].Length); } return(count); } WireFrame PackFrame(int value) { var segments = new Memory <ulong> [value]; for (int i = 0; i < value; i++) { ulong[] a = new ulong[i + 1]; segments[i] = new Memory <ulong>(a); } return(new WireFrame(segments)); } Thread rxRunner = null; using (var server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None)) using (var client = new AnonymousPipeClientStream(PipeDirection.In, server.ClientSafePipeHandle)) using (var bc = new BlockingCollection <int>(8)) { server.ReadMode = PipeTransmissionMode.Byte; client.ReadMode = PipeTransmissionMode.Byte; using (var txPump = new FramePump(server)) using (var rxPump = new FramePump(client)) { rxRunner = new Thread(() => { rxPump.Run(); }); rxPump.FrameReceived += f => bc.Add(UnpackFrame(f)); rxRunner.Start(); for (int i = 0; i < 100; i++) { txPump.Send(PackFrame(1)); txPump.Send(PackFrame(8)); txPump.Send(PackFrame(2)); txPump.Send(PackFrame(7)); txPump.Send(PackFrame(3)); txPump.Send(PackFrame(6)); txPump.Send(PackFrame(4)); txPump.Send(PackFrame(5)); Assert.IsTrue(SpinWait.SpinUntil(() => bc.Count == 8, 500)); Assert.AreEqual(1, bc.Take()); Assert.AreEqual(8, bc.Take()); Assert.AreEqual(2, bc.Take()); Assert.AreEqual(7, bc.Take()); Assert.AreEqual(3, bc.Take()); Assert.AreEqual(6, bc.Take()); Assert.AreEqual(4, bc.Take()); Assert.AreEqual(5, bc.Take()); } } } Assert.IsTrue(rxRunner.Join(500)); }
public void FramePumpDeferredProcessing() { int UnpackAndVerifyFrame(WireFrame frame, int expectedCount) { int count = frame.Segments.Count; Assert.AreEqual(expectedCount, count); for (int i = 0; i < count; i++) { int length = frame.Segments[i].Length; Assert.AreEqual(expectedCount - i, length); for (int j = 0; j < length; j++) { Assert.AreEqual((ulong)(length - j), frame.Segments[i].Span[j]); } } return(count); } WireFrame PackFrame(int value) { var segments = new Memory <ulong> [value]; for (int i = 0; i < value; i++) { ulong[] a = new ulong[value - i]; segments[i] = new Memory <ulong>(a); for (int j = 0; j < a.Length; j++) { a[j] = (ulong)(a.Length - j); } } return(new WireFrame(segments)); } Thread rxRunner = null; using (var server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None)) using (var client = new AnonymousPipeClientStream(PipeDirection.In, server.ClientSafePipeHandle)) using (var bc = new BlockingCollection <WireFrame>(8)) { server.ReadMode = PipeTransmissionMode.Byte; client.ReadMode = PipeTransmissionMode.Byte; using (var txPump = new FramePump(server)) using (var rxPump = new FramePump(client)) { rxRunner = new Thread(() => { rxPump.Run(); }); rxPump.FrameReceived += bc.Add; rxRunner.Start(); txPump.Send(PackFrame(1)); txPump.Send(PackFrame(8)); txPump.Send(PackFrame(2)); txPump.Send(PackFrame(7)); txPump.Send(PackFrame(3)); txPump.Send(PackFrame(6)); txPump.Send(PackFrame(4)); txPump.Send(PackFrame(5)); Assert.IsTrue(SpinWait.SpinUntil(() => bc.Count == 8, 500)); UnpackAndVerifyFrame(bc.Take(), 1); UnpackAndVerifyFrame(bc.Take(), 8); UnpackAndVerifyFrame(bc.Take(), 2); UnpackAndVerifyFrame(bc.Take(), 7); UnpackAndVerifyFrame(bc.Take(), 3); UnpackAndVerifyFrame(bc.Take(), 6); UnpackAndVerifyFrame(bc.Take(), 4); UnpackAndVerifyFrame(bc.Take(), 5); } } Assert.IsTrue(rxRunner.Join(500)); }
public override bool Cook(string luaPath, LuaGlobal environment, string outputDirectory, string intermediateDirectory, out string producedFile, out string error) { error = ""; producedFile = ""; string assetPath = GetAssetPath(luaPath); using (FileStream assetStream = new FileStream(assetPath, FileMode.Open)) { using (Bitmap bmp = new Bitmap(Image.FromStream(assetStream))) { string channelMask = Env.TryGetDefault <string>(environment, "channelMask", "RGBA"); // Try to get all settings from .lua file or acceptable defaults CapnpGen.CapTexture texture = new CapnpGen.CapTexture(); texture.Header = new CapnpGen.CapTextureHeader(); texture.Header.Type = CapnpGen.CapTextureType.simple; // TODO: DDS support? texture.Header.Width = (uint)bmp.Width; texture.Header.Height = (uint)bmp.Height; texture.Header.RChannel = GetChannel(channelMask, 0); texture.Header.GChannel = GetChannel(channelMask, 1); texture.Header.BChannel = GetChannel(channelMask, 2); texture.Header.AChannel = GetChannel(channelMask, 3); PixelFormat pixelFormat = bmp.PixelFormat; int bytesPerPixel = GetBytesPerPixel(pixelFormat); // Lock the bitmap's bits. Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. int bytes = bmp.Width * bmp.Height * bytesPerPixel; byte[] byteValues = new byte[bytes]; // Copy the color values into the array. Marshal.Copy(ptr, byteValues, 0, bytes); MemoryStream memoryStream = new MemoryStream(); // Loop over the pixels int stride = bmpData.Width; for (int row = 0; row < bmpData.Height; row++) { for (int column = 0; column < bmpData.Width; column++) { int pixelIndex = ((row * stride) + column) * bytesPerPixel; WriteChannel(texture.Header.RChannel, byteValues, pixelIndex, pixelFormat, memoryStream); WriteChannel(texture.Header.GChannel, byteValues, pixelIndex, pixelFormat, memoryStream); WriteChannel(texture.Header.BChannel, byteValues, pixelIndex, pixelFormat, memoryStream); WriteChannel(texture.Header.AChannel, byteValues, pixelIndex, pixelFormat, memoryStream); } } texture.Data = memoryStream.ToArray(); bmp.UnlockBits(bmpData); // Create output file producedFile = Path.ChangeExtension(Path.GetFileName(assetPath), ".PurTexture"); string outFilePath = Path.Combine(outputDirectory, "textures", producedFile); Directory.CreateDirectory(Path.GetDirectoryName(outFilePath)); using (FileStream outStream = new FileStream(outFilePath, FileMode.Create)) { MessageBuilder message = MessageBuilder.Create(); var root = message.BuildRoot <CapnpGen.CapTexture.WRITER>(); texture.serialize(root); var pump = new FramePump(outStream); pump.Send(message.Frame); } } } return(true); }
public override bool Cook(string luaPath, LuaGlobal environment, string outputDirectory, string intermediateDirectory, out string producedFile, out string error) { error = ""; producedFile = ""; outputDirectory = Path.Combine(outputDirectory, "materials"); Directory.CreateDirectory(outputDirectory); // Load XML document string materialPath = GetMaterialPath(luaPath, environment); XmlDocument xmlDoc = new XmlDocument(); try { xmlDoc.Load(materialPath); } catch (Exception e) { error = e.Message; return(false); } // Get the root node XmlNode materialFileNode = xmlDoc.SelectSingleNode("//MaterialFile"); if (materialFileNode == null) { error = "Material file does not have a root node called MaterialFile"; return(false); } // Parse all samplers List <CapnpGen.CapSampler> samplers = new List <CapnpGen.CapSampler>(); XmlNodeList samplerNodes = materialFileNode.SelectNodes("Sampler"); foreach (XmlNode samplerNode in samplerNodes) { if (!MaterialParser.ParseSampler(samplerNode, samplers, out error)) { return(false); } } // Parse all blenders List <CapnpGen.CapBlender> blenders = new List <CapnpGen.CapBlender>(); XmlNodeList blenderNodes = materialFileNode.SelectNodes("Blender"); foreach (XmlNode blenderNode in blenderNodes) { if (!MaterialParser.ParseBlender(blenderNode, blenders, out error)) { return(false); } } // Parse all materials List <CapnpGen.CapMaterial> materials = new List <CapnpGen.CapMaterial>(); XmlNodeList materialNodes = materialFileNode.SelectNodes("Material"); foreach (XmlNode materialNode in materialNodes) { if (!MaterialParser.ParseMaterial(materialNode, materials, blenders, samplers, out error)) { return(false); } } // Parse all material instances List <CapnpGen.CapMaterialInstance> materialInstances = new List <CapnpGen.CapMaterialInstance>(); XmlNodeList materialInstanceNodes = materialFileNode.SelectNodes("MaterialInstance"); foreach (XmlNode materialInstanceNode in materialInstanceNodes) { if (!MaterialParser.ParseMaterialInstance(materialInstanceNode, materialInstances, materials, materialPath, out error)) { return(false); } } // Compile all materials foreach (CapnpGen.CapMaterial material in materials) { if (!MaterialCompiler.CompileMaterial(material, outputDirectory, out error)) { return(false); } } // Serialize and save the all material instance headers foreach (CapnpGen.CapMaterialInstance materialInstance in materialInstances) { string headerPath = Path.Combine(outputDirectory, materialInstance.Header.Name + ".material"); Directory.CreateDirectory(Path.GetDirectoryName(headerPath)); using (FileStream outStream = new FileStream(headerPath, FileMode.Create)) { MessageBuilder message = MessageBuilder.Create(); var root = message.BuildRoot <CapnpGen.CapMaterialInstanceHeader.WRITER>(); materialInstance.Header.serialize(root); var pump = new FramePump(outStream); pump.Send(message.Frame); } // Copy all textures used by the material instance into the Data/material folder foreach (CapnpGen.CapMaterialTexture texture in materialInstance.Header.Textures) { string destPath = Path.Combine(outputDirectory, texture.Path); Directory.CreateDirectory(Path.GetDirectoryName(destPath)); File.Copy(texture.ContentPath, destPath, true); } } return(true); }
public override bool Cook(string luaPath, LuaGlobal environment, string outputDirectory, string intermediateDirectory, out string producedFile, out string error) { error = ""; producedFile = ""; string assetPath = GetAssetPath(luaPath); materialStreamProvider.SetAssetPath(assetPath); using (FileStream assetStream = new FileStream(assetPath, FileMode.Open)) { LoadResult result = objLoader.Load(assetStream); CapnpGen.CapModel model = new CapnpGen.CapModel(); // Get all vertex positions List <CapnpGen.CapVector3> vertexPositions = new List <CapnpGen.CapVector3>(); foreach (Vertex vertex in result.Vertices) { CapnpGen.CapVector3 pos = new CapnpGen.CapVector3(); pos.X = vertex.X; pos.Y = vertex.Y; pos.Z = vertex.Z; vertexPositions.Add(pos); } //model.VertexPositions = vertexPositions; // Get all vertex texCoords List <CapnpGen.CapVector2> vertexTexCoords = new List <CapnpGen.CapVector2>(); foreach (Texture texture in result.Textures) { CapnpGen.CapVector2 texCoord = new CapnpGen.CapVector2(); texCoord.X = texture.X; texCoord.Y = texture.Y; vertexTexCoords.Add(texCoord); } // Get all vertex normals List <CapnpGen.CapVector3> vertexNormals = new List <CapnpGen.CapVector3>(); foreach (Normal normal in result.Normals) { CapnpGen.CapVector3 vertexNormal = new CapnpGen.CapVector3(); vertexNormal.X = normal.X; vertexNormal.Y = normal.Y; vertexNormal.Z = normal.Z; vertexNormals.Add(vertexNormal); } // Because .obj stores vertex positions, vertex texcoords and vertex normals separately and without duplication we need to "unpack" combined vertices from this data // Each .obj model has a list of "groups" which represent submeshes // Each group has a list of faces which represent quads, they have 3-4 "indices" that point to vertex positions, vertex texcoords and vertex normals separately // We need to iterate over these, and then build one combined vertex for each unique combination of position, texcoord and normal // Convert indices // This dictionary will hold unique vertices as keys, and it's corresponding index as value, this makes it easy for us to look up indices of duplicated vertices Dictionary <CapnpGen.CapVertex, UInt32> combinedVertices = new Dictionary <CapnpGen.CapVertex, uint>(); List <UInt32> indices = new List <UInt32>(); foreach (ObjLoader.Loader.Data.Elements.Group group in result.Groups) // A group represents a "submesh" { foreach (Face face in group.Faces) { UInt32[] combinedIndices = new UInt32[face.Count]; for (int i = 0; i < face.Count; i++) { CapnpGen.CapVector3 position = vertexPositions[face[i].VertexIndex - 1]; int normalIndex = face[i].NormalIndex; CapnpGen.CapVector3 normal = new CapnpGen.CapVector3(); normal.Y = 1; if (normalIndex > 0) { normal = vertexNormals[normalIndex - 1]; } int texCoordIndex = face[i].TextureIndex; CapnpGen.CapVector2 texCoord = new CapnpGen.CapVector2(); if (texCoordIndex > 0) { texCoord = vertexTexCoords[texCoordIndex - 1]; } combinedIndices[i] = CombineVertex(position, normal, texCoord, ref combinedVertices); } if (face.Count == 4) { // We split the face (quad) into two triangles, the first one with index 0 1 and 2 indices.Add(combinedIndices[0]); indices.Add(combinedIndices[1]); indices.Add(combinedIndices[2]); // The second one with index 2 3 and 0 indices.Add(combinedIndices[2]); indices.Add(combinedIndices[3]); indices.Add(combinedIndices[0]); } else if (face.Count == 3) { // This kind of face only has one triangle, so it's simple indices.Add(combinedIndices[0]); indices.Add(combinedIndices[1]); indices.Add(combinedIndices[2]); } else { Debug.Assert(false); // I haven't seen a model where faces don't have 4 or 3 indices yet } } } CapnpGen.CapVertex[] vertices = new CapnpGen.CapVertex[combinedVertices.Count]; combinedVertices.Keys.CopyTo(vertices, 0); model.Vertices = vertices; model.Indices = indices; // Create output file string outputFileName = Path.ChangeExtension(Path.GetFileName(assetPath), ".model"); producedFile = Path.Combine(outputDirectory, "models", outputFileName); Directory.CreateDirectory(Path.GetDirectoryName(producedFile)); using (FileStream outStream = new FileStream(producedFile, FileMode.Create)) { MessageBuilder message = MessageBuilder.Create(); var root = message.BuildRoot <CapnpGen.CapModel.WRITER>(); model.serialize(root); var pump = new FramePump(outStream); pump.Send(message.Frame); } } return(true); }