Я пытаюсь реализовать структуру данных Quad Tree. Когда я уже закончил с этим и запустил проект, я получил перерыв с сообщением:
System.TypeLoadException
HResult=0x80131522
Message= Could not load type: "DataStructures.WorldQuadTree+Node" from "SomeProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null".
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
Вот мой WorldQuadTree
класс:
using System;
using System.Collections.Generic;
using MyMath;
namespace DataStructures
{
class WorldQuadTree
{
public struct Configuration
{
public int nodeCapacity;
public float width;
public float length;
}
struct Node
{
private readonly WorldQuadTree tree;
private bool isSubdivided;
public readonly BoundingBox boundary;
public readonly int index;
public Heap<Node>.Block subNodes;
public Heap<WorldObject>.Block content;
public Node(WorldQuadTree tree, int index, BoundingBox boundary, Heap<WorldObject>.Block content)
{
this.tree = tree;
this.index = index;
this.boundary = boundary;
this.content = content;
this.subNodes = default(Heap<Node>.Block);
this.isSubdivided = false;
}
public bool Contains(Vector3 point)
{
return boundary.Contains(point) != ContainmentType.Disjoint;
}
public bool Intersects(BoundingBox box)
{
return boundary.Intersects(box);
}
public bool Insert(WorldObject obj)
{
for (byte call = 0; call < 2; call++)
{
if (isSubdivided)
{
int capacity = subNodes.Capacity;
for (int i = 0; i < capacity; i++)
{
if (subNodes[i].Insert(obj))
return true;
}
return false;
}
else
{
int capacity = content.Capacity;
for (int i = 0; i < capacity; i++)
{
if (content[i] is null)
{
content[i] = obj;
return true;
}
else if (content[i].Equals(obj))
return false;
}
isSubdivided = true;
subNodes = tree.Subdivide(index);
continue;
}
}
throw new NotImplementedException("Insertion operation has failed.");
}
public bool Remove(WorldObject obj)
{
if (isSubdivided)
{
int capacity = subNodes.Capacity;
for (int i = 0; i < capacity; i++)
{
if (subNodes[i].Remove(obj))
return true;
}
return false;
}
else
{
int index = content.Remove(obj);
return index < 0 ? false : true;
}
}
public int GetResponsibleFor(Vector3 point)
{
if (boundary.Contains(point) == ContainmentType.Disjoint)
return -1;
if (isSubdivided)
{
int capacity = subNodes.Capacity;
for (int current, i = 0; i < capacity; i++)
{
current = subNodes[i].GetResponsibleFor(point);
if (current >= 0)
return current;
}
return -1;
}
else return index;
}
public void Query(BoundingBox box, List<WorldObject> results)
{
if (Intersects(box) is false)
return;
if (isSubdivided)
{
int capacity = subNodes.Capacity;
for (int i = 0; i < capacity; i++)
subNodes[i].Query(box, results);
}
else
{
int capacity = content.Capacity;
for (int i = 0; i < capacity; i++)
{
if (content[i].BoundingBox.Intersects(box))
results.Add(content[i]);
}
}
}
}
private readonly int nodeCapacity;
private readonly Heap<Node> nodesHeap;
private readonly Heap<WorldObject> contentHeap;
private Node root;
public int Capacity => contentHeap.Capacity;
public WorldObject this[int index] => contentHeap[index];
public WorldQuadTree(Configuration config, Heap<WorldObject>.Configuration heapConfig)
{
var boundary = new BoundingBox
{
Min = new Vector3(-config.width * 0.5f, 0, -config.length * 0.5f),
Max = new Vector3( config.width * 0.5f, 0, config.length * 0.5f),
};
this.nodeCapacity = config.nodeCapacity;
this.nodesHeap = new Heap<Node>(4, 16);
this.contentHeap = new Heap<WorldObject>(heapConfig.initialCapacity, heapConfig.growRate);
this.root = new Node(this, 0, boundary, contentHeap.GetBlock(config.nodeCapacity, out _));
}
private Heap<Node>.Block Subdivide(int index)
{
Node node = nodesHeap[index];
Vector3 center = node.boundary.Center;
Vector3 thickness = node.boundary.HalfExtents;
var subNodes = nodesHeap.GetBlock(4, out int pointer);
// begin configuring sub nodes in the conter-clokwise order.
// Configure top-right node.
var boundary = new BoundingBox(center, center + thickness);
subNodes[0] = new Node(this, pointer, boundary, contentHeap.GetBlock(nodeCapacity, out _));
// Configure top-left node.
pointer++;
thickness.X = -thickness.X;
boundary = new BoundingBox(center, center + thickness);
subNodes[1] = new Node(this, pointer, boundary, contentHeap.GetBlock(nodeCapacity, out _));
// Configure down-left node.
pointer++;
thickness.Y = -thickness.Y;
boundary = new BoundingBox(center, center + thickness);
subNodes[2] = new Node(this, pointer, boundary, contentHeap.GetBlock(nodeCapacity, out _));
// Configure down-right node.
pointer++;
thickness.X = -thickness.X;
boundary = new BoundingBox(center, center + thickness);
subNodes[3] = new Node(this, pointer, boundary, contentHeap.GetBlock(nodeCapacity, out _));
// delegate parent node content to sub nodes
int length = node.content.Capacity;
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 4; j++)
{
if (subNodes[j].Contains(node.content[i].Position))
{
subNodes[j].Insert(node.content[i]);
continue;
}
}
}
// free parent node content
node.content.Free();
nodesHeap[index] = node;
return subNodes;
}
public bool Insert(WorldObject obj) => root.Insert(obj);
public bool Remove(WorldObject obj) => root.Remove(obj);
public void Query(BoundingBox box, List<WorldObject> results) => root.Query(box, results);
/// <summary>
/// Updates quad tree according to the object movement.
/// </summary>
/// <returns>
/// Returns false when given object is outside of boundary, otherwise true.
/// </returns>
public bool OnObjectMoved(WorldObject obj, Vector3 displacement)
{
int to = root.GetResponsibleFor(obj.Position);
int from = root.GetResponsibleFor(obj.Position - displacement);
if (from < 0)
{
throw new ArgumentException($"Has not contained object: {obj}, at position: {obj.Position - displacement}.");
}
else nodesHeap[from].Remove(obj);
if (to >= 0)
{
nodesHeap[to].Insert(obj);
}
else return false;
return true;
}
public void Clear(bool shouldMinimizeMemory = false)
{
if (shouldMinimizeMemory)
{
contentHeap.SetMinimumCapacity(nodeCapacity);
}
nodesHeap.Clear();
contentHeap.Clear();
}
}
}
Я знаю, что уже есть популярный: Assembly name should differ from .exe file name
. Но я не знаю, как это проверить. Я имею в виду, у меня есть много файлов .dll
в моей папке bin/x86/Debug
, но ни один из них не имеет такого же имени, как мой файл .exe
. Я также думаю, что VS даже не создавал мой основной (проект) .dll
файл.
Понятия не имею, что происходит не так ...
Кстати, я использую Visual Studio 2019 с проект запущен на. NET framework 4.
РЕДАКТИРОВАТЬ:
Когда я удаляю этот файл (WorldQuadTree.cs) из моего проекта - все работает нормально, и приложение работает работоспособный. Теперь я знаю, что с моим КОДОМ что-то не так. Тем не менее, я не вижу никаких проблем в моем коде, которые могут вызвать "TypeLoadException". Я пытаюсь переименовать каждый класс, который использовал в нем, но результат был тот же Надеюсь, это поможет вам ... и мне.