So I've been writing this data structure for a few days, and now I'm really curious about what it actually is, and to get some critique on my logic.
A branch, based on this usage, exists when a HEAD node contains at least one node of the same type referenced.
The purpose of the structure is to have branches that are arranged by type. Each node on the branch has a reference to the next node on the branch (Always of the same type) and an entry point to a Subdata branch. Subdata in this case being an instance of an object that inherits from the AchievementNode. When subdata is added and it is the first of it's kind on that branch it has the HEAD tag applied to it, additionally, it also has a tag that contains the metadata of the type of data contained (to bypass the typeof calls).
Implementation:
public abstract class AchievementNode : ScriptableObject
{
public enum NodeTypes
{
NONE = 0x0,
HEAD = 0x1,
TAIL = 0x2,
TYPE = 0x4,
DATA = 0x8,
LEVEL = 0x16,
GLOBAL = 0x32
}
public NodeTypes nodeType;
public AchievementNode nextOfType;
public AchievementNode headOfSubnode;
public void OnEnable ()
{
hideFlags = HideFlags.HideAndDontSave;
}
public virtual void Init(NodeTypes type, int enumData)
{
nodeType = type;
}
protected void AddNode(NodeTypes type, AchievementNode originNode, AchievementNode newNode)
{
//Create SubNode branch notch when types mismatch.
if((originNode.nodeType & type) != type)
{
//If Has subNode Data Run to the end and assign new node
if(originNode.headOfSubnode!=null)
{
newNode.nodeType = type | NodeTypes.TAIL;
AppendToTail(type,GetEndOfBranch(originNode.headOfSubnode),newNode);
}//Search for proper SubNodeTypes then add. Wicked Recursion warning here...
else if((originNode.headOfSubnode.nodeType & type) != type)
{
Debug.LogError("Do Gnarly Search To Find!");
return;
}//Doesn't have subnode... add new Subnode.
else
{
newNode.nodeType = type | NodeTypes.HEAD | NodeTypes.TAIL;
originNode.headOfSubnode = newNode;
}
}
else
{
//Add to the current branch
newNode.nodeType = type | NodeTypes.TAIL;
AppendToTail(type,GetEndOfBranch(originNode),newNode);
}
}
private void AppendToTail(NodeTypes type,AchievementNode tailNode, AchievementNode newNode)
{
if((tailNode.nodeType & NodeTypes.HEAD) == NodeTypes.HEAD)
{
tailNode.nodeType = tailNode.nodeType | type;
}
else
{
tailNode.nodeType = type;
}
tailNode.nextOfType = newNode;
}
protected AchievementNode GetEndOfBranch(AchievementNode currentNode)
{
//Special Case where Node is HEAD and TAIL.
if((currentNode.nextOfType.nodeType & NodeTypes.TAIL) != NodeTypes.TAIL)
{
return GetEndOfBranch(currentNode.nextOfType);
}
else
{
return currentNode;
}
}
protected void SetType(NodeTypes type)
{
nodeType = type;
}
protected virtual AchievementNode FindInHierarchy(NodeTypes nodeCheck, AchievementNode currentNode)
{
if(currentNode == null)
{
return null;
}
else if((currentNode.nodeType & nodeCheck) == nodeCheck)
{
return currentNode;
}
else
{
return FindInHierarchy(nodeCheck,currentNode.nextOfType);
}
}
}
Thanks for taking the time to check this out. It means a lot.