internal void EventIDTests( DateTime timestamp, BatchID batchID, EventID id, EventID next ) { GIVEN["a BatchID"] = () => batchID = new BatchID(timestamp = DateTime.UtcNow); WHEN["calling GetFirst"] = () => id = EventID.GetFirst(batchID); THEN["a new value with given batch ID is returned"] = () => id.BatchID.Should().Be(batchID); AND["its Sequence is 1"] = () => id.Sequence.Should().Be(1); WHEN["calling GetNext"] = () => next = id.GetNext(); THEN["a new EventID is returned"] = () => next.Should().NotBeSameAs(id); AND["its BatchID is the original one"] = () => next.BatchID.Should().Be(batchID); AND["its Sequence is 2"] = () => next.Sequence.Should().Be(2); GIVEN["a EventID with max sequence"] = () => { id = EventID.GetFirst(batchID); for (int i = 2; i <= 65535; i++) { id = id.GetNext(); } id.Sequence.Should().Be(65535); }; WHEN["calling GetNext", ThenIsThrown <InvalidOperationException>()] = () => id.GetNext(); }
internal void EventIDGeneratorTests(EventIDGenerator gen, BatchID batch, EventID res) { GIVEN["a batch ID"] = () => batch = new BatchID(DateTime.UtcNow); AND["a generator"] = () => gen = new EventIDGenerator(batch); WHEN["calling Next"] = () => res = gen.Next(); THEN["the sequence of the EventID is 1"] = () => res.Sequence.Should().Be(1); AND["its batch sequence is 1"] = () => res.BatchID.Sequence.Should().Be(1); WHEN["calling Next again"] = () => res = gen.Next(); THEN["the sequence of the EventID is 2"] = () => res.Sequence.Should().Be(2); GIVEN["a new generator"] = () => gen = new EventIDGenerator(batch); WHEN["calling Next 65535 times"] = () => Enumerable.Range(1, 65535).ForEach(i => res = gen.Next()); THEN["the sequence of the EventID is 6555 (max)"] = () => res.Sequence.Should().Be(65535); WHEN["calling Next once more", ThenIsThrown <InvalidOperationException>()] = () => gen.Next(); }
internal void EventIDSerialization( BatchID batch, DateTime timestamp, long raw, EventID id, EventID deserialized ) { GIVEN["a BatchID"] = () => batch = new BatchID(timestamp = DateTime.UtcNow); AND["its last EventID"] = () => id = EventID.GetLast(batch); WHEN["calling Serialize"] = () => raw = id.Serialize(); THEN["the last 2 bytes should contain the event sequence"] = () => (raw & 0xFFFF).Should().Be(65535); AND["the next 9 bits should contain the batch sequence"] = () => (raw >> 16 & 0x1FF).Should().Be(1); AND["the first 31 bits should contain the timestamp"] = () => new DateTime(2015, 1, 1).AddSeconds((raw >> 32 & 0x7FFFFFFF)).Should().BeCloseTo(timestamp, precision: 1000); WHEN["it is serialized and deserialized"] = () => deserialized = new EventID(id.Serialize()); THEN["its value is the same"] = () => deserialized.Should().Be(id); GIVEN["a timestamp with zero ms"] = () => timestamp = new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc); AND["the subseconds serialize to 0"] = () => Subseconds(timestamp).Should().Be(0); GIVEN["a timestamp with 9 ms"] = null; AND["the subseconds serialize to 0"] = () => Subseconds(timestamp.AddMilliseconds(9)).Should().Be(0); GIVEN["a timestamp with 10 ms"] = null; AND["the subseconds serialize to 1"] = () => Subseconds(timestamp.AddMilliseconds(10)).Should().Be(1); GIVEN["a timestamp with 19 ms"] = null; AND["the subseconds serialize to 1"] = () => Subseconds(timestamp.AddMilliseconds(19)).Should().Be(1); GIVEN["a timestamp with 999 ms"] = null; AND["the subseconds serialize to 99"] = () => Subseconds(timestamp.AddMilliseconds(999)).Should().Be(99); long Subseconds(DateTime ts) { long r = EventID.GetFirst(new BatchID(ts)).Serialize(); return(r >> 25 & 0x7F); }; }
internal void BatchIDTests(BatchID id, DateTime timestamp, bool result) { WHEN["creating an instance with invalid Timestamp (before MinTimestamp)", ThenIsThrown <InvalidOperationException>()] = () => new BatchID(new DateTime(2015, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(-1)); WHEN["creating an instance with invalid Timestamp (after MaxTimestamp)", ThenIsThrown <InvalidOperationException>()] = () => new BatchID(new DateTime(2083, 1, 19, 3, 14, 7, DateTimeKind.Utc).AddMilliseconds(1)); WHEN["creating an instance with a local timezoned timestamp", ThenIsThrown <InvalidOperationException>()] = () => new BatchID(DateTime.Now); GIVEN["a new BatchID"] = () => id = new BatchID(timestamp = DateTime.UtcNow); THEN["its Sequence is 1"] = () => id.Sequence.Should().Be(1); AND["its timestamp is rounded to 10ms"] = () => (id.Timestamp.Ticks % (TimeSpan.TicksPerMillisecond * 10)).Should().Be(0); WHEN["calling TryToAdvance with same timestamp"] = () => result = id.TryToAdvance(timestamp); THEN["it should return true"] = () => result.Should().BeTrue(); AND["its Sequence is 2"] = () => id.Sequence.Should().Be(2); GIVEN["a BatchID with a sequence one below maximum sequence"] = () => id = BatchID.DeserializeInternal(EventID.GetTimestampDate(timestamp), 510); WHEN["calling TryToAdvance"] = () => id.TryToAdvance(timestamp); THEN["Sequence is max sequence"] = () => id.Sequence.Should().Be(511); WHEN["calling TryToAdvance once more"] = () => result = id.TryToAdvance(timestamp); THEN["it returns false"] = () => result.Should().BeFalse(); AND["Sequence is max"] = () => id.Sequence.Should().Be(511); WHEN["calling TryToAdvance with timestamp + 10 ticks"] = () => result = id.TryToAdvance(timestamp.AddTicks(10)); THEN["it still returns false"] = () => result.Should().BeFalse(); WHEN["calling TryToAdvance with timestamp + 10ms"] = () => result = id.TryToAdvance(timestamp = timestamp.AddMilliseconds(10)); THEN["it returns true"] = () => result.Should().BeTrue(); AND["its Timestamp is set to the new timestamp"] = () => id.Timestamp.Should().Be(EventID.GetTimestampDate(timestamp)); AND["its Sequence should be 1"] = () => id.Sequence.Should().Be(1); WHEN["calling TryToAdvance with an invalid timestamp", ThenIsThrown <InvalidOperationException>()] = () => id.TryToAdvance(new DateTime(2090, 1, 1)); WHEN["calling TryToAdvance with a timestamp before the current timestamp", ThenIsThrown <InvalidOperationException>()] = () => id.TryToAdvance(timestamp.AddMilliseconds(-10)); }
// Start is called before the first frame update void Start() { m_BatchRendererGroup = new BatchRendererGroup(this.OnPerformCulling, IntPtr.Zero); #if ENABLE_PICKING m_PickingMaterial = LoadMaterialWithHideAndDontSave("Hidden/HDRP/BRGPicking"); m_BatchRendererGroup.SetPickingMaterial(m_PickingMaterial); #endif #if ENABLE_ERROR_LOADING_MATERIALS if (SetFallbackMaterialsOnStart) { m_ErrorMaterial = LoadMaterialWithHideAndDontSave("Hidden/HDRP/MaterialError"); m_BatchRendererGroup.SetErrorMaterial(m_ErrorMaterial); m_LoadingMaterial = LoadMaterialWithHideAndDontSave("Hidden/HDRP/MaterialLoading"); m_BatchRendererGroup.SetLoadingMaterial(m_LoadingMaterial); } #endif // Create a batch... var renderers = FindObjectsOfType <MeshRenderer>(); Debug.Log("Converting " + renderers.Length + " renderers..."); m_renderers = new NativeArray <DrawRenderer>(renderers.Length, Allocator.Persistent); m_batchHash = new NativeHashMap <DrawKey, int>(1024, Allocator.Persistent); m_rangeHash = new NativeHashMap <RangeKey, int>(1024, Allocator.Persistent); m_drawBatches = new NativeList <DrawBatch>(Allocator.Persistent); m_drawRanges = new NativeList <DrawRange>(Allocator.Persistent); // Fill the GPU-persistent scene data ComputeBuffer int bigDataBufferVector4Count = 4 /*zero*/ + 1 /*probes*/ + 1 /*speccube*/ + 7 /*SH*/ + m_renderers.Length * 3 * 2 /*per renderer 4x3 matrix+inverse*/; var vectorBuffer = new NativeArray <Vector4>(bigDataBufferVector4Count, Allocator.Temp); // First 4xfloat4 of ComputeBuffer needed to be zero filled for default property fall back! vectorBuffer[0] = new Vector4(0, 0, 0, 0); vectorBuffer[1] = new Vector4(0, 0, 0, 0); vectorBuffer[2] = new Vector4(0, 0, 0, 0); vectorBuffer[3] = new Vector4(0, 0, 0, 0); var startOffset = 4; // Fill global data (shared between all batches) var probesOcclusionOffset = startOffset; vectorBuffer[probesOcclusionOffset] = new Vector4(1, 1, 1, 1); startOffset++; var specCubeOffset = startOffset; vectorBuffer[specCubeOffset] = ReflectionProbe.defaultTextureHDRDecodeValues; startOffset++; var SHOffset = startOffset; var SH = new SHProperties(RenderSettings.ambientProbe); vectorBuffer[SHOffset + 0] = SH.SHAr; vectorBuffer[SHOffset + 1] = SH.SHAg; vectorBuffer[SHOffset + 2] = SH.SHAb; vectorBuffer[SHOffset + 3] = SH.SHBr; vectorBuffer[SHOffset + 4] = SH.SHBg; vectorBuffer[SHOffset + 5] = SH.SHBb; vectorBuffer[SHOffset + 6] = SH.SHC; startOffset += 7; var localToWorldOffset = startOffset; var worldToLocalOffset = localToWorldOffset + m_renderers.Length * 3; m_instances = new NativeList <DrawInstance>(1024, Allocator.Persistent); for (int i = 0; i < renderers.Length; i++) { var renderer = renderers[i]; m_renderers[i] = new DrawRenderer { bounds = new AABB { Center = new float3(0, 0, 0), Extents = new float3(0, 0, 0) } }; var meshFilter = renderer.gameObject.GetComponent <MeshFilter>(); if (!renderer || !meshFilter || !meshFilter.sharedMesh || renderer.enabled == false) { continue; } // Disable the existing Unity MeshRenderer to avoid double rendering! renderer.enabled = false; /* mat4x3 packed like this: * p1.x, p1.w, p2.z, p3.y, * p1.y, p2.x, p2.w, p3.z, * p1.z, p2.y, p3.x, p3.w, * 0.0, 0.0, 0.0, 1.0 */ var m = renderer.transform.localToWorldMatrix; vectorBuffer[i * 3 + 0 + localToWorldOffset] = new Vector4(m.m00, m.m10, m.m20, m.m01); vectorBuffer[i * 3 + 1 + localToWorldOffset] = new Vector4(m.m11, m.m21, m.m02, m.m12); vectorBuffer[i * 3 + 2 + localToWorldOffset] = new Vector4(m.m22, m.m03, m.m13, m.m23); var mi = renderer.transform.worldToLocalMatrix; vectorBuffer[i * 3 + 0 + worldToLocalOffset] = new Vector4(mi.m00, mi.m10, mi.m20, mi.m01); vectorBuffer[i * 3 + 1 + worldToLocalOffset] = new Vector4(mi.m11, mi.m21, mi.m02, mi.m12); vectorBuffer[i * 3 + 2 + worldToLocalOffset] = new Vector4(mi.m22, mi.m03, mi.m13, mi.m23); // Renderer bounds var transformedBounds = AABB.Transform(m, meshFilter.sharedMesh.bounds.ToAABB()); m_renderers[i] = new DrawRenderer { bounds = transformedBounds }; var mesh = m_BatchRendererGroup.RegisterMesh(meshFilter.sharedMesh); var sharedMaterials = new List <Material>(); renderer.GetSharedMaterials(sharedMaterials); var shadows = renderer.shadowCastingMode; for (int matIndex = 0; matIndex < sharedMaterials.Count; matIndex++) { var material = m_BatchRendererGroup.RegisterMaterial(sharedMaterials[matIndex]); var key = new DrawKey { material = material, meshID = mesh, submeshIndex = (uint)matIndex, shadows = shadows }; #if ENABLE_PICKING key.pickableObjectInstanceID = renderer.gameObject.GetInstanceID(); #endif var drawBatch = new DrawBatch { key = key, instanceCount = 0, instanceOffset = 0 }; m_instances.Add(new DrawInstance { key = key, instanceIndex = i }); int drawBatchIndex; if (m_batchHash.TryGetValue(key, out drawBatchIndex)) { drawBatch = m_drawBatches[drawBatchIndex]; } else { drawBatchIndex = m_drawBatches.Length; m_drawBatches.Add(drawBatch); m_batchHash[key] = drawBatchIndex; // Different renderer settings? -> new range var rangeKey = new RangeKey { shadows = shadows }; var drawRange = new DrawRange { key = rangeKey, drawCount = 0, drawOffset = 0, }; int drawRangeIndex; if (m_rangeHash.TryGetValue(rangeKey, out drawRangeIndex)) { drawRange = m_drawRanges[drawRangeIndex]; } else { drawRangeIndex = m_drawRanges.Length; m_drawRanges.Add(drawRange); m_rangeHash[rangeKey] = drawRangeIndex; } drawRange.drawCount++; m_drawRanges[drawRangeIndex] = drawRange; } drawBatch.instanceCount++; m_drawBatches[drawBatchIndex] = drawBatch; } } m_GPUPersistentInstanceData = new GraphicsBuffer(GraphicsBuffer.Target.Raw, (int)bigDataBufferVector4Count * 16 / 4, 4); m_GPUPersistentInstanceData.SetData(vectorBuffer); Debug.Log("DrawRanges: " + m_drawRanges.Length + ", DrawBatches: " + m_drawBatches.Length + ", Instances: " + m_instances.Length); // Prefix sum to calculate draw offsets for each DrawRange int prefixSum = 0; for (int i = 0; i < m_drawRanges.Length; i++) { var drawRange = m_drawRanges[i]; drawRange.drawOffset = prefixSum; m_drawRanges[i] = drawRange; prefixSum += drawRange.drawCount; } // Generate draw index ranges for each DrawRange m_drawIndices = new NativeArray <int>(m_drawBatches.Length, Allocator.Persistent); var m_internalRangeIndex = new NativeArray <int>(m_drawRanges.Length, Allocator.Temp); for (int i = 0; i < m_drawBatches.Length; i++) { var draw = m_drawBatches[i]; if (m_rangeHash.TryGetValue(new RangeKey { shadows = draw.key.shadows }, out int drawRangeIndex)) { var drawRange = m_drawRanges[drawRangeIndex]; m_drawIndices[drawRange.drawOffset + m_internalRangeIndex[drawRangeIndex]] = i; m_internalRangeIndex[drawRangeIndex]++; } } m_internalRangeIndex.Dispose(); // Prefix sum to calculate instance offsets for each DrawCommand prefixSum = 0; for (int i = 0; i < m_drawBatches.Length; i++) { // DrawIndices remap to get DrawCommands ordered by DrawRange var remappedIndex = m_drawIndices[i]; var drawBatch = m_drawBatches[remappedIndex]; drawBatch.instanceOffset = prefixSum; m_drawBatches[remappedIndex] = drawBatch; prefixSum += drawBatch.instanceCount; } // Generate instance index ranges for each DrawCommand m_instanceIndices = new NativeArray <int>(m_instances.Length, Allocator.Persistent); var m_internalDrawIndex = new NativeArray <int>(m_drawBatches.Length, Allocator.Temp); for (int i = 0; i < m_instances.Length; i++) { var instance = m_instances[i]; if (m_batchHash.TryGetValue(instance.key, out int drawBatchIndex)) { var drawBatch = m_drawBatches[drawBatchIndex]; m_instanceIndices[drawBatch.instanceOffset + m_internalDrawIndex[drawBatchIndex]] = instance.instanceIndex; m_internalDrawIndex[drawBatchIndex]++; } } m_internalDrawIndex.Dispose(); // Bounds ("infinite") UnityEngine.Bounds bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(1048576.0f, 1048576.0f, 1048576.0f)); m_BatchRendererGroup.SetGlobalBounds(bounds); // Batch metadata buffer... // Per instance data int objectToWorldID = Shader.PropertyToID("unity_ObjectToWorld"); int worldToObjectID = Shader.PropertyToID("unity_WorldToObject"); int colorID = Shader.PropertyToID("_BaseColor"); // Global data (should be moved to C++ side) int probesOcclusionID = Shader.PropertyToID("unity_ProbesOcclusion"); int specCubeID = Shader.PropertyToID("unity_SpecCube0_HDR"); int SHArID = Shader.PropertyToID("unity_SHAr"); int SHAgID = Shader.PropertyToID("unity_SHAg"); int SHAbID = Shader.PropertyToID("unity_SHAb"); int SHBrID = Shader.PropertyToID("unity_SHBr"); int SHBgID = Shader.PropertyToID("unity_SHBg"); int SHBbID = Shader.PropertyToID("unity_SHBb"); int SHCID = Shader.PropertyToID("unity_SHC"); var batchMetadata = new NativeArray <MetadataValue>(11, Allocator.Temp); batchMetadata[0] = CreateMetadataValue(objectToWorldID, localToWorldOffset * UnsafeUtility.SizeOf <Vector4>(), true); batchMetadata[1] = CreateMetadataValue(worldToObjectID, worldToLocalOffset * UnsafeUtility.SizeOf <Vector4>(), true); batchMetadata[2] = CreateMetadataValue(probesOcclusionID, probesOcclusionOffset * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[3] = CreateMetadataValue(specCubeID, specCubeOffset * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[4] = CreateMetadataValue(SHArID, (SHOffset + 0) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[5] = CreateMetadataValue(SHAgID, (SHOffset + 1) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[6] = CreateMetadataValue(SHAbID, (SHOffset + 2) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[7] = CreateMetadataValue(SHBrID, (SHOffset + 3) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[8] = CreateMetadataValue(SHBgID, (SHOffset + 4) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[9] = CreateMetadataValue(SHBbID, (SHOffset + 5) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[10] = CreateMetadataValue(SHCID, (SHOffset + 6) * UnsafeUtility.SizeOf <Vector4>(), false); // Register batch m_batchID = m_BatchRendererGroup.AddBatch(batchMetadata, m_GPUPersistentInstanceData.bufferHandle); m_initialized = true; }
internal void Save( MongoFake db, MongoEventStore store, IEventStoreTransaction tx, PresetIDGenerator generator, EventBatch <Customer> s, BatchID batch ) { GIVEN["a configured store"] = () => store = CreateStore( new List <StreamConfiguration> { new StreamConfiguration(typeof(Customer), "customer"), new StreamConfiguration(typeof(OrderProcessor), "order_processor") }, db = new MongoFake(), generator = new PresetIDGenerator() ); Given["a transaction"] = async() => tx = store.UseTransaction(await db.StartTransactionAsync()); Then["saving an unregistered stream type", ThrowsA <EventStoreConfigurationException>()] = () => tx.Save(CreateStream <Order>(streamID: Guid.NewGuid())); GIVEN["a stream with some events"] = () => s = CreateStream <Customer>( streamID: Guid.NewGuid(), new Customer.Created(), new Customer.Relocated { OldAddress = "ADR 1", NewAddress = "ADR 2" } ); When["saving the stream"] = () => { batch = new BatchID(DateTime.UtcNow); generator.Enqueue(batch); return(tx.Save(s)); }; THEN["an EventID is assigned to each event"] = () => { EventIDGenerator gen = new EventIDGenerator(batch); s.Events.Select(x => x.ID).Should() .AllBeOfType <EventID>().And .ContainInOrder(gen.Next(), gen.Next()); }; AND["the events are persisted properly"] = () => db.Log.Should().BeExactly(b => b .Transaction(t => t .InsertMany("Events", s.Events.ToArray()) // TODO: Better interface on Fake... .Upsert("customer_Info", s.StreamID, new StreamInfo(s.StreamID)) ) ); List <RecordedEvent> act = default; WHEN["getting the saved stream"] = () => act = tx.Get(new StreamLocator <Customer>(s.StreamID)).Result.ToList().Result; THEN["it contains the original events"] = () => act.Should().BeEquivalentTo(s.Events); }
public EventIDGenerator(BatchID batchID) => _currentID = EventID.GetFirst(batchID);
// Start is called before the first frame update void Start() { m_BatchRendererGroup = new BatchRendererGroup(this.OnPerformCulling, IntPtr.Zero); int itemCount = itemGridSize * itemGridSize; m_itemCount = itemCount; // Bounds UnityEngine.Bounds bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(1048576.0f, 1048576.0f, 1048576.0f)); m_BatchRendererGroup.SetGlobalBounds(bounds); // Register mesh and material if (m_mesh) { m_meshID = m_BatchRendererGroup.RegisterMesh(m_mesh); } if (m_material) { m_materialID = m_BatchRendererGroup.RegisterMaterial(m_material); } // Batch metadata buffer int objectToWorldID = Shader.PropertyToID("unity_ObjectToWorld"); int matrixPreviousMID = Shader.PropertyToID("unity_MatrixPreviousM"); int worldToObjectID = Shader.PropertyToID("unity_WorldToObject"); int colorID = Shader.PropertyToID("_BaseColor"); // Generate a grid of objects... int bigDataBufferVector4Count = 4 + itemCount * (3 * 3 + 1); // 4xfloat4 zero + per instance = { 3x mat4x3, 1x float4 color } m_sysmemBuffer = new NativeArray <Vector4>(bigDataBufferVector4Count, Allocator.Persistent, NativeArrayOptions.ClearMemory); m_GPUPersistentInstanceData = new GraphicsBuffer(GraphicsBuffer.Target.Raw, (int)bigDataBufferVector4Count * 16 / 4, 4); // 64 bytes of zeroes, so loads from address 0 return zeroes. This is a BatchRendererGroup convention. int positionOffset = 4; m_sysmemBuffer[0] = new Vector4(0, 0, 0, 0); m_sysmemBuffer[1] = new Vector4(0, 0, 0, 0); m_sysmemBuffer[2] = new Vector4(0, 0, 0, 0); m_sysmemBuffer[3] = new Vector4(0, 0, 0, 0); // Matrices UpdatePositions(m_center); // Colors int colorOffset = positionOffset + itemCount * 3 * 3; for (int i = 0; i < itemCount; i++) { Color col = Color.HSVToRGB(((float)(i) / (float)itemCount) % 1.0f, 1.0f, 1.0f); // write colors right after the 4x3 matrices m_sysmemBuffer[colorOffset + i] = new Vector4(col.r, col.g, col.b, 1.0f); } m_GPUPersistentInstanceData.SetData(m_sysmemBuffer); var batchMetadata = new NativeArray <MetadataValue>(4, Allocator.Temp, NativeArrayOptions.UninitializedMemory); batchMetadata[0] = CreateMetadataValue(objectToWorldID, 64, true); // matrices batchMetadata[1] = CreateMetadataValue(matrixPreviousMID, 64 + itemCount * UnsafeUtility.SizeOf <Vector4>() * 3, true); // previous matrices batchMetadata[2] = CreateMetadataValue(worldToObjectID, 64 + itemCount * UnsafeUtility.SizeOf <Vector4>() * 3 * 2, true); // inverse matrices batchMetadata[3] = CreateMetadataValue(colorID, 64 + itemCount * UnsafeUtility.SizeOf <Vector4>() * 3 * 3, true); // colors // Register batch m_batchID = m_BatchRendererGroup.AddBatch(batchMetadata, m_GPUPersistentInstanceData.bufferHandle); m_initialized = true; }
// During initialization, we will allocate all required objects, and set up our custom instance data. void Start() { // Create the BatchRendererGroup and register assets m_BRG = new BatchRendererGroup(this.OnPerformCulling, IntPtr.Zero); m_MeshID = m_BRG.RegisterMesh(mesh); m_MaterialID = m_BRG.RegisterMaterial(material); // Create the buffer that holds our instance data m_InstanceData = new GraphicsBuffer(GraphicsBuffer.Target.Raw, (kExtraBytes + kBytesPerInstance * kNumInstances) / sizeof(int), sizeof(int)); // Place one zero matrix at the start of the instance data buffer, so loads from address 0 will return zero var zero = new Matrix4x4[1] { Matrix4x4.zero }; // Create transform matrices for our three example instances var matrices = new Matrix4x4[kNumInstances] { Matrix4x4.Translate(new Vector3(-2, 0, 0)), Matrix4x4.Translate(new Vector3(0, 0, 0)), Matrix4x4.Translate(new Vector3(2, 0, 0)), }; // Convert the transform matrices into the packed format expected by the shader var objectToWorld = new PackedMatrix[kNumInstances] { new PackedMatrix(matrices[0]), new PackedMatrix(matrices[1]), new PackedMatrix(matrices[2]), }; // Also create packed inverse matrices var worldToObject = new PackedMatrix[kNumInstances] { new PackedMatrix(matrices[0].inverse), new PackedMatrix(matrices[1].inverse), new PackedMatrix(matrices[2].inverse), }; // Make all instances have unique colors var colors = new Vector4[kNumInstances] { new Vector4(1, 0, 0, 1), new Vector4(0, 1, 0, 1), new Vector4(0, 0, 1, 1), }; // In this simple example, the instance data is placed into the buffer like this: // Offset | Description // 0 | 64 bytes of zeroes, so loads from address 0 return zeroes // 64 | 32 uninitialized bytes to make working with SetData easier, otherwise unnecessary // 96 | unity_ObjectToWorld, three packed float3x4 matrices // 240 | unity_WorldToObject, three packed float3x4 matrices // 384 | _BaseColor, three float4s // Compute start addresses for the different instanced properties. unity_ObjectToWorld starts // at address 96 instead of 64, because the computeBufferStartIndex parameter of SetData // is expressed as source array elements, so it is easier to work in multiples of sizeof(PackedMatrix). uint byteAddressObjectToWorld = kSizeOfPackedMatrix * 2; uint byteAddressWorldToObject = byteAddressObjectToWorld + kSizeOfPackedMatrix * kNumInstances; uint byteAddressColor = byteAddressWorldToObject + kSizeOfPackedMatrix * kNumInstances; // Upload our instance data to the GraphicsBuffer, from where the shader can load them. m_InstanceData.SetData(zero, 0, 0, 1); m_InstanceData.SetData(objectToWorld, 0, (int)(byteAddressObjectToWorld / kSizeOfPackedMatrix), objectToWorld.Length); m_InstanceData.SetData(worldToObject, 0, (int)(byteAddressWorldToObject / kSizeOfPackedMatrix), worldToObject.Length); m_InstanceData.SetData(colors, 0, (int)(byteAddressColor / kSizeOfFloat4), colors.Length); // Set up metadata values to point to the instance data. Set the most significant bit 0x80000000 in each, // which instructs the shader that the data is an array with one value per instance, indexed by the instance index. // Any metadata values used by the shader and not set here will be zero. When such a value is used with // UNITY_ACCESS_DOTS_INSTANCED_PROP (i.e. without a default), the shader will interpret the // 0x00000000 metadata value so that the value will be loaded from the start of the buffer, which is // where we uploaded the matrix "zero" to, so such loads are guaranteed to return zero, which is a reasonable // default value. var metadata = new NativeArray <MetadataValue>(3, Allocator.Temp); metadata[0] = new MetadataValue { NameID = Shader.PropertyToID("unity_ObjectToWorld"), Value = 0x80000000 | byteAddressObjectToWorld, }; metadata[1] = new MetadataValue { NameID = Shader.PropertyToID("unity_WorldToObject"), Value = 0x80000000 | byteAddressWorldToObject, }; metadata[2] = new MetadataValue { NameID = Shader.PropertyToID("_BaseColor"), Value = 0x80000000 | byteAddressColor, }; // Finally, create a batch for our instances, and make the batch use the GraphicsBuffer with our // instance data, and the metadata values that specify where the properties are. Note that // we do not need to pass any batch size here. m_BatchID = m_BRG.AddBatch(metadata, m_InstanceData.bufferHandle); }
public HttpResponseMessage GetSearchResult(object data) { var db = DbUtils.GetDBConnection(); db.Connection.Open(); IEnumerable <IDictionary <string, object> > response = null; var jsonData = JsonConvert.SerializeObject(data); var dictJson = JsonConvert.DeserializeObject <Dictionary <string, object> >(jsonData); object actionObject; dictJson.TryGetValue("actionName", out actionObject); string Action = actionObject.ToString(); string input_queryapi = ""; object userName; dictJson.TryGetValue("queried_by_username", out userName); if (Action.Equals("GetTableSchema")) { object tableName; dictJson.TryGetValue("TableName", out tableName); input_queryapi = tableName.ToString(); response = db.Query("INFORMATION_SCHEMA.COLUMNS").Select("COLUMN_NAME").WhereRaw("TABLE_NAME = ?", tableName).Get().Cast <IDictionary <string, object> >(); return(Request.CreateResponse(HttpStatusCode.OK, response)); } if (Action.Equals("GetInstructorByName")) { object empName; dictJson.TryGetValue("EmpName", out empName); input_queryapi = empName.ToString(); response = db.Query("Employee").WhereRaw("lower(EmpName) = ?", empName).Get().Cast <IDictionary <string, object> >(); //response = db.Query("Employee").WhereRaw("lower(EmpName) = ?", "dr. abdul aziz").Get().Cast<IDictionary<string, object>>(); } else if (Action.Equals("GetInstructorByEmail")) { object email; dictJson.TryGetValue("Email", out email); input_queryapi = email.ToString(); response = db.Query("Employee").WhereRaw("lower(Email) = ?", email).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetInstructorByRank")) { object designationTitle; dictJson.TryGetValue("DesignationTitle", out designationTitle); input_queryapi = designationTitle.ToString(); response = db.Query("Employee").Join("Designation", "Employee.DesignationID", "Designation.DesignationID").Where("DesignationTitle", designationTitle).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetInstructorByDepartment")) { object departmentID; dictJson.TryGetValue("DepartmentID", out departmentID); input_queryapi = departmentID.ToString(); response = db.Query("Employee").Join("Department", "Employee.DepartmentID", "Department.DepartmentID").Where("Department.DepartmentID", departmentID).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetInstructorByNameStartsWith")) { object startNamePrefix; dictJson.TryGetValue("EmpName", out startNamePrefix); string prefixString = startNamePrefix.ToString() + "%"; input_queryapi = startNamePrefix.ToString(); response = db.Query("Employee").WhereLike("EmpName", prefixString).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetInstructorByNameContains")) { object startNamePrefix; dictJson.TryGetValue("EmpName", out startNamePrefix); string prefixString = "%" + startNamePrefix.ToString() + "%"; input_queryapi = startNamePrefix.ToString(); response = db.Query("Employee").WhereLike("EmpName", prefixString).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetInstructorByCourseName")) { object courseName; dictJson.TryGetValue("CourseName", out courseName); input_queryapi = courseName.ToString(); response = db.Query("Employee").Join("CourseFaculty", "Employee.EmpID", "CourseFaculty.EmpID").Join("CourseOffered", "CourseOffered.CourseOfferedID", "CourseFaculty.CourseOfferedID").Join("Course", "CourseOffered.CourseID", "Course.CourseID").Where("CourseName", courseName).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetInstructorByCourseCode")) { object courseCode; dictJson.TryGetValue("CourseCode", out courseCode); input_queryapi = courseCode.ToString(); response = db.Query("Employee").Join("CourseFaculty", "Employee.EmpID", "CourseFaculty.EmpID").Join("CourseOffered", "CourseOffered.CourseOfferedID", "CourseFaculty.CourseOfferedID").Join("Course", "CourseOffered.CourseID", "Course.CourseID").Where("CourseCode", courseCode).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetCoursesTaughtByASpecificInstructor")) { object EmpName; dictJson.TryGetValue("EmpName", out EmpName); input_queryapi = EmpName.ToString(); response = db.Query("Semester").Select("CourseName").Join("CourseOffered", "Semester.SemesterID", "CourseOffered.SemesterID").Join("Course", "Course.CourseID", "CourseOffered.CourseID") .Join("CourseFaculty", "CourseFaculty.CourseOfferedID", "CourseOffered.CourseOfferedID") .Join("Employee", "Employee.EmpID", "CourseFaculty.EmpID") .Where("EmpName", EmpName).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetCoursesTaughtByAInstructorInAParticularSemester")) { object semesterName; object empName; dictJson.TryGetValue("EmpName", out empName); dictJson.TryGetValue("SemesterName", out semesterName); input_queryapi = empName.ToString() + " " + semesterName.ToString(); response = db.Query("Semester").Join("CourseOffered", "Semester.SemesterID", "CourseOffered.SemesterID").Join("Course", "Course.CourseID", "CourseOffered.CourseID") .Join("CourseFaculty", "CourseFaculty.CourseOfferedID", "CourseOffered.CourseOfferedID") .Join("Employee", "Employee.EmpID", "CourseFaculty.EmpID") .Where("SemesterName", semesterName) .Where("EmpName", empName).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } // STUDENT QUERIES else if (Action.Equals("GetStudentByName")) { object SName; dictJson.TryGetValue("SName", out SName); input_queryapi = SName.ToString(); response = db.Query("Student").WhereRaw("lower(SName) = ?", SName).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentByStudentID")) { object RollNumber; dictJson.TryGetValue("RollNumber", out RollNumber); input_queryapi = RollNumber.ToString(); response = db.Query("Student").WhereRaw("lower(RollNumber) = ?", RollNumber).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentByBatchID")) { object BatchID; dictJson.TryGetValue("BatchID", out BatchID); input_queryapi = BatchID.ToString(); response = db.Query("Student").WhereRaw("BatchID = ?", BatchID).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentsByDepartment")) { object DepartmentName; dictJson.TryGetValue("DepartmentName", out DepartmentName); input_queryapi = DepartmentName.ToString(); response = db.Query("Student").Join("Programme", "Programme.ProgrammeID", "Student.ProgrammeID").Join("Department", "Department.DepartmentID", "Programme.DepartmentID") .Where("DepartmentName", DepartmentName).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentsBySection")) { object SectionName; dictJson.TryGetValue("SectionName", out SectionName); input_queryapi = SectionName.ToString(); response = db.Query("Student").Join("Section", "Section.BatchID", "Student.BatchID") .Where("SectionName", SectionName).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentByNUEmail")) { object Email; dictJson.TryGetValue("Email", out Email); input_queryapi = Email.ToString(); response = db.Query("Student").Join("CandidateStudent", "CandidateStudent.CandidateID", "Student.CandidateID") .Where("Student.Email", Email).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentByPrimaryEmail")) { object Email; dictJson.TryGetValue("Email", out Email); input_queryapi = Email.ToString(); response = db.Query("Student").Join("CandidateStudent", "CandidateStudent.CandidateID", "Student.CandidateID") .Where("CandidateStudent.Email", Email).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentsByNameStartsWith")) { object startNamePrefix; dictJson.TryGetValue("Sname", out startNamePrefix); input_queryapi = startNamePrefix.ToString(); string prefixString = startNamePrefix.ToString() + "%"; response = db.Query("Student").WhereLike("Sname", prefixString).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetStudentsByNameContains")) { object startNamePrefix; dictJson.TryGetValue("EmpName", out startNamePrefix); input_queryapi = startNamePrefix.ToString(); string prefixString = "%" + startNamePrefix.ToString() + "%"; response = db.Query("Student").WhereLike("Sname", prefixString).Get().Cast <IDictionary <string, object> >(); //get product by id=1 } else if (Action.Equals("GetStudentsByCourseName")) { object CourseName; dictJson.TryGetValue("CourseName", out CourseName); input_queryapi = CourseName.ToString(); response = db.Query("Student").Join("CourseEnrollment", "CourseEnrollment.StudentID", "Student.StudentID").Join("Course", "Course.CourseID", "CourseEnrollment.CourseID") .Where("CourseName", CourseName).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentsByCourseCode")) { object CourseCode; dictJson.TryGetValue("CourseCode", out CourseCode); input_queryapi = CourseCode.ToString(); response = db.Query("Student").Join("CourseEnrollment", "CourseEnrollment.StudentID", "Student.StudentID").Join("Course", "Course.CourseID", "CourseEnrollment.CourseID") .Where("CourseCode", CourseCode).Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentsBySkill")) { response = db.Query("StudentSkills").Join("Skill", "Skill.SkillID", "StudentSkills.SkillID").Join("Student", "StudentSkills.StudentID", "Student.StudentID") .Get().Cast <IDictionary <string, object> >(); } else if (Action.Equals("GetStudentsByDomain")) { response = db.Query("Domain").Join("Skill", "Skill.DomainID", "Domain.DomainID").Join("StudentSkills", "StudentSkills.SkillID", "Skill.SkillID").Join("Student", "Student.StudentID", "StudentSkills.StudentID") .Get().Cast <IDictionary <string, object> >(); } //var db1 = DbUtils.GetDBConnection(); //db1.Connection.Open(); SqlConnection dbConnection = new SqlConnection(ConfigurationManager.AppSettings["SqlDBConn"].ToString()); try { /** * db1.Query("dbo.SearchLog").AsInsert(new * { * input_query = input_queryapi, * actionName = Action, * queried_by_username = userName.ToString() * }); **/ string query = "INSERT INTO dbo.SearchLog(input_query, actionName, queried_by_username) VALUES(@input_query,@actionName,@queried_by_username)"; using (SqlCommand command = new SqlCommand(query, dbConnection)) { command.Parameters.AddWithValue("@input_query", input_queryapi); command.Parameters.AddWithValue("@actionName", Action); command.Parameters.AddWithValue("@queried_by_username", userName.ToString()); dbConnection.Open(); int result = command.ExecuteNonQuery(); // Check Error if (result < 0) { Console.WriteLine("Error inserting data into Database!"); } } } catch (Exception e) { } return(Request.CreateResponse(HttpStatusCode.OK, response)); }