Structural organization question.

This is more of a design question then a monogame one.
Sort of having a brainfart on this one.

I have a linked tree were each node or item is basically a button.
For one of the buttons i want to make i want it to act sort of like file explorer where when i click a folder i sort of dive into it from the initial Explorer Node (call it A) which will then show a Back button or Forward button if i reverse the direction.

However im at a loss as to how to track the current node (which ever it may be in the tree call it B) and present it inside of A. Im sort of unable to visualize the proper way to handle this sort of thing since i have to traverse thru the tree to select a thing in the first place then i need to either callback to A or tell A which thing to draw which means passing some sort of instruction.

I dunno just fishing for input from anyone who has a idea my brain is going in circles on this.

Your description reminded me of these:

This may help?:
https://introprogramming.info/tag/tree-data-structures/#_Toc362296540

This may help:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/

This has some interesting code shared:

Maybe you are wanting a Binary Tree?:

That sounds like it fits your requirements…

Good Luck!

Could you not just use a stack to represent the active track? The stack would consist of nodes which are just references to a specific item in your full tree. Whenever you click to dive down into an item, you push a reference to that tree node onto the stack and it becomes the “active” item. Clicking back would just require popping the top item off the stack and displaying whatever data is the new top of the stack. Breaking the data apart from the controlling traversal structure seems like it would make things a little easier than sticking with just the tree.

I could also be misunderstanding the intention here. Sorry if so.

Well its hard to explain it
The Image i posted starts at A but in reality the A node could be any node in the tree so too could the B node it could be a great granchild or further.

if you imagine a long unbalanced tree were a specific type of node N has a certain type of property which will affect all child nodes under it. However nodes of other types can be added or removed to nodes of children below node N that is the origin of the affect such that they have no direct access to the grandparent to know of the affect. Further i might add other affects later on so that i would then need to deal with both the possibility of clashing affects and multiple affects to be tracked. In the case at hand though node N tracks the current node and could in fact keep a stack or list with a index to the current selected node. However this sort of implys offloading responsibility for things to the N node that previously were the responsibility of individual nodes so its all sort of maddening.

The way ive started to implement it is to make a special command method and add two additional public references to the base class commander and subordinate kinda like a army pattern were there is a hierarchical structure but orders are carried thru the ranks via a method. For, who it applys to, that directly bypasses the chain of command and establishes a connection with the command originator or commander.
I still haven’t worked out all the details that might end up trashed.

Basically the structure looks something like this well this is just conceptual i just typed the core idea and there is more going on that makes it more difficult.

class BaseClass
{
BaseClass parent;
List<BaseClass> children;
BaseClass Commander;
BaseClass Subordinate; //active subordinate for commander
// abstract properties and methods ..
}
class Concrete
{
// ,, concrete properties and methods and concrete instance local methods ect.
RecalcDirty()
{
// ,, do specific stuff.  iterate recursively.
}

PassCommand(base commandnode, int commandCode)
{
 if( ImeetSpecificConditions && commandCodeIsSuchNsuch)
     this.Commander = commandnode;
}

Update()
{
if(ClickAndAllConditionsMet)
{
   this.Commander.Subordinate = this;
}
if(root && dirty)
{
      // fire children and run down the chain
}
//...
}

If the tree nodes have references to their parent’s then couldn’t you have a node look recursively up through it’s parents to look for affects. Or you could keep a stack/list of the current affects and pass that into the child nodes?

For me these problems come down to two cases.

  • Re-entrant
    By this I mean that things can be executed in any order. So the event driving changes can happen at any stage. The state of A could be updated at any time regardless of the state of any children

    For this case I always end up with horrible code that keeps copies of the parent for each level and you work your way up the chain till you get to A. Then you have a none re-entrant method that executes afterwards to actually do whatever this mess is supposed to do.

Pros
bullet proof
Cons
slow
needs extra pass

  • Single threaded

    In this case the parent calls the update on the child. So A updates all it’s children, each of which updates it’s children, etc. You all know this paradigm

    I always end up with a static state vector in this case.

The code you have above is close to what I normally end up with, but is very basic.

I normally end up with a lot more data in the state vector. A stack of old states (or partial states) to make it easy to go backwards. A mutex to make it thread safe, mainly because I am paranoid, but what’s wrong with being paranoid. And all output data so whatever is using the system can grab a single pointer to work with.

Pros
Simple to work with for external code
Easy to debug
Flexible

Cons
Liable to code bloat. I hate the words “wouldn’t it be cool if…”
Not very memory efficient
Whole tree needs updating every pass

So I hope that gives you something to think about.

Ya no matter how i seem to set it up its a mess. I mean i guess if the base class isn’t bloated its ok i guess but.
The concrete classes are getting terribly complicated to work together when i have to recalculate sizes though as the parent size relys on the childrens sizes.

Well i finally made some progress on my like 100xxx th ui attempt just need to say that.

3 Likes