/// <summary> /// Создание экземпляра класса <see cref="Heap{TKey, TValue}"/> /// </summary> /// <param name="heapType">Тип кучи</param> /// <param name="maxSize">Максимальный размер кучи</param> public Heap(HeapType heapType, int maxSize) { if (maxSize <= 0) { throw new ArgumentException($"{nameof(maxSize)} should be greater than 0", nameof(maxSize)); } _heap = new ComparableElement <TKey, TValue> [maxSize]; switch (heapType) { case HeapType.Min: _heapType = new MinHeapType(); //_isChildCorrect = (index) => index == 0 || _heap[GetParentIndex(index)].Key.CompareTo(_heap[index].Key) <= 0; //_elementCandidateSubstitution = (int first, int second) => _heap[first].Key.CompareTo(_heap[second].Key) <= 0 ? first : second; break; case HeapType.Max: _heapType = new MaxHeapType(); //_isChildCorrect = (index) => index == 0 || _heap[GetParentIndex(index)].Key.CompareTo(_heap[index].Key) >= 0; //_elementCandidateSubstitution = (int first, int second) => _heap[first].Key.CompareTo(_heap[second].Key) >= 0 ? first : second; break; default: throw new ArgumentOutOfRangeException(nameof(heapType), $"unhandled value: {heapType}"); } }
/// <summary> /// Call this method from the currently running constructor to construct the accessor object of the given field. /// </summary> /// <typeparam name="T">The data type of the field.</typeparam> /// <param name="name">The name of the field.</param> /// <returns>The accessor object of the field.</returns> protected HeapedValue <T> ConstructField <T>(string name) { if (this.isDisposed) { throw new ObjectDisposedException("HeapedObject"); } if (this.ctorIndex == this.inheritenceHierarchy.Length) { throw new InvalidOperationException("Last constructor already finished!"); } if (!this.heapedFields[this.ctorIndex].ContainsKey(name)) { throw new InvalidOperationException(string.Format("Field '{0}' doesn't exist in type '{1}'!", name, this.inheritenceHierarchy[this.ctorIndex].Name)); } if (this.heapedFields[this.ctorIndex][name] != null) { throw new InvalidOperationException(string.Format("Field '{0}' in type '{1}' already constructed!", name, this.inheritenceHierarchy[this.ctorIndex].Name)); } Type typeOfRequestedValue = typeof(T); HeapedValueImpl <T> retObj = null; IHeapType fieldType = this.heapManager.GetHeapType(this.inheritenceHierarchy[this.ctorIndex].GetFieldTypeID(name)); if (fieldType.PointedTypeID != -1) { IHeapType pointedType = this.heapManager.GetHeapType(fieldType.PointedTypeID); if (pointedType.PointedTypeID != -1 || typeOfRequestedValue.Name != pointedType.Name) { throw new InvalidOperationException(string.Format("Field '{0}' in type '{1}' is not '{2}'!", name, this.inheritenceHierarchy[this.ctorIndex].Name, typeOfRequestedValue.Name)); } retObj = new HeapedValueImpl <T>(); } else { if ((fieldType.BuiltInType == BuiltInTypeEnum.Byte && typeOfRequestedValue == TYPE_OF_BYTE) || (fieldType.BuiltInType == BuiltInTypeEnum.Short && typeOfRequestedValue == TYPE_OF_SHORT) || (fieldType.BuiltInType == BuiltInTypeEnum.Integer && typeOfRequestedValue == TYPE_OF_INT) || (fieldType.BuiltInType == BuiltInTypeEnum.Long && typeOfRequestedValue == TYPE_OF_LONG) || (fieldType.BuiltInType == BuiltInTypeEnum.Number && typeOfRequestedValue == TYPE_OF_NUMBER) || (fieldType.BuiltInType == BuiltInTypeEnum.IntVector && typeOfRequestedValue == TYPE_OF_INTVECT) || (fieldType.BuiltInType == BuiltInTypeEnum.NumVector && typeOfRequestedValue == TYPE_OF_NUMVECT) || (fieldType.BuiltInType == BuiltInTypeEnum.IntRectangle && typeOfRequestedValue == TYPE_OF_INTRECT) || (fieldType.BuiltInType == BuiltInTypeEnum.NumRectangle && typeOfRequestedValue == TYPE_OF_NUMRECT)) { retObj = new HeapedValueImpl <T>(); } else { throw new InvalidOperationException(string.Format("Type mismatch when constructing field '{0}' of type '{1}'!", name, this.inheritenceHierarchy[this.ctorIndex].Name)); } } this.heapedFields[this.ctorIndex][name] = retObj; this.StepCtorIfNecessary(); return(retObj); }
/// <see cref="IComponent.Start"/> public void Start() { /// Collect the heap types defined in the heap type containers List <HeapType> heapTypes = new List <HeapType>(); foreach (Assembly container in this.heapTypeContainers) { foreach (Type type in container.GetTypes()) { if (type.IsSubclassOf(typeof(HeapedObject))) { HeapType heapType = this.CreateHeapType(type); this.inheritenceTree.Add(type.Name, null); heapTypes.Add(heapType); } } } /// Register the found heap types. this.RegisterNonBuiltInTypes(heapTypes); /// Create the inheritence tree. foreach (IHeapType heapType in heapTypes) { List <IHeapType> inheritencePath = new List <IHeapType>(); IHeapType currHeapType = heapType; inheritencePath.Add(currHeapType); while (currHeapType.HasField(Constants.NAME_OF_BASE_TYPE_FIELD)) { currHeapType = this.GetHeapType(currHeapType.GetFieldTypeID(Constants.NAME_OF_BASE_TYPE_FIELD)); inheritencePath.Add(currHeapType); } inheritencePath.Reverse(); this.inheritenceTree[heapType.Name] = inheritencePath.ToArray(); } }
static void TestSimulationHeap() { List <HeapType> testMetadata = new List <HeapType>() { new HeapType("Unit", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("HitPoints", "short"), new KeyValuePair <string, string>("TestArray", "int*"), new KeyValuePair <string, string>("TestPtrArray", "Building**"), new KeyValuePair <string, string>("TestPtr", "Building*"), }), new HeapType("Building", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("HitPoints", "short"), new KeyValuePair <string, string>("BuildStatus", "short"), }), }; IHeapManagerInternals heapMgr = new HeapManager(testMetadata); IHeapType unitType = heapMgr.GetHeapType("Unit"); int UNIT_HP_IDX = unitType.GetFieldIdx("HitPoints"); short UNIT_HP_TID = unitType.GetFieldTypeID("HitPoints"); int UNIT_TESTARRAY_IDX = unitType.GetFieldIdx("TestArray"); short UNIT_TESTARRAY_TID = unitType.GetFieldTypeID("TestArray"); int UNIT_TESTPTRARRAY_IDX = unitType.GetFieldIdx("TestPtrArray"); short UNIT_TESTPTRARRAY_TID = unitType.GetFieldTypeID("TestPtrArray"); int UNIT_TESTPTR_IDX = unitType.GetFieldIdx("TestPtr"); short UNIT_TESTPTR_TID = unitType.GetFieldTypeID("TestPtr"); IHeapType buildingType = heapMgr.GetHeapType("Building"); int BUILDING_HP_IDX = buildingType.GetFieldIdx("HitPoints"); short BUILDING_HP_TID = buildingType.GetFieldTypeID("HitPoints"); int BUILDING_BUILDSTATUS_IDX = buildingType.GetFieldIdx("BuildStatus"); short BUILDING_BUILDSTATUS_TID = buildingType.GetFieldTypeID("BuildStatus"); Stopwatch watch = new Stopwatch(); watch.Start(); for (int j = 0; j < 100000; j++) { IHeapConnector unit = heapMgr.New(unitType.ID); IHeapConnector building0 = heapMgr.New(buildingType.ID); IHeapConnector building1 = heapMgr.New(buildingType.ID); ((IValueWrite <short>)building0.AccessField(BUILDING_HP_IDX)).Write(100); ((IValueWrite <short>)building0.AccessField(BUILDING_BUILDSTATUS_IDX)).Write(50); ((IValueWrite <short>)building1.AccessField(BUILDING_HP_IDX)).Write(50); ((IValueWrite <short>)building1.AccessField(BUILDING_BUILDSTATUS_IDX)).Write(100); ((IValueWrite <short>)unit.AccessField(UNIT_HP_IDX)).Write(88); unit.AccessField(UNIT_TESTPTR_IDX).PointTo(building0); unit.AccessField(UNIT_TESTARRAY_IDX).PointTo(heapMgr.NewArray(heapMgr.GetHeapType("int").ID, 5)); for (int i = 0; i < 5; ++i) { ((IValueWrite <int>)unit.AccessField(UNIT_TESTARRAY_IDX).Dereference().AccessArrayItem(i)).Write(i); } unit.AccessField(UNIT_TESTPTRARRAY_IDX).PointTo(heapMgr.NewArray(heapMgr.GetHeapType("Building*").ID, 5)); unit.AccessField(UNIT_TESTPTRARRAY_IDX).Dereference().AccessArrayItem(0).PointTo(building0); unit.AccessField(UNIT_TESTPTRARRAY_IDX).Dereference().AccessArrayItem(1).PointTo(building1); unit.AccessField(UNIT_TESTARRAY_IDX).Dereference().DeleteArray(); unit.AccessField(UNIT_TESTPTRARRAY_IDX).Dereference().DeleteArray(); unit.Delete(); building0.Delete(); building1.Delete(); } watch.Stop(); // TODO: test heap saving/loading }