Skip to content

Instantly share code, notes, and snippets.

@INTERNALINTERFERENCE
Last active February 2, 2023 11:31
Show Gist options
  • Save INTERNALINTERFERENCE/3a441db8175e599e2cb5882042d14581 to your computer and use it in GitHub Desktop.
Save INTERNALINTERFERENCE/3a441db8175e599e2cb5882042d14581 to your computer and use it in GitHub Desktop.
Tree logic
public class TreeNode
: ViewModelBase
{
protected TreeNode(string part)
: this( part, -1, null)
{
}
private TreeNode(
string part,
int level,
TreeNode? parent)
{
Part = part;
Level = level;
Parent = parent;
Root = parent?.Root ?? this;
if ( parent != null )
MessagesCount = 1;
}
#region IO
private bool _updateEnqueued;
public int Level { get; }
public TreeNode? Parent { get; }
public TreeNode Root { get; }
private bool _isExpanded;
public bool IsExpanded
{
get => _isExpanded;
set
{
this.RaiseAndSetIfChanged(ref _isExpanded, value);
Root.EnqueueUpdate();
}
}
private AvaloniaList<TreeNode> _visibleChildren = new();
public IAvaloniaReadOnlyList<TreeNode> VisibleChildren
=> _visibleChildren;
public readonly Dictionary<string, TreeNode> _treeChildren = new();
public ObservableCollection<ReceivedHistoryMessage> UiHistoryMessages { get; set; } = new();
#endregion
public bool Add(
string[] subTopic,
MqttDelivery delivery)
=> Add(subTopic, Level + 1, delivery);
public void ForceResync()
=> Root.Update();
private bool Add(
string[] topic,
int level,
MqttDelivery delivery )
{
if ( level >= topic.Length )
{
Topic = delivery.Topic;
Header = delivery.Header?.ToJsonString( true );
Payload = delivery.Payload?.ToJsonString( true );
Delivery = delivery;
AddToHistory( delivery );
return false;
}
var part = topic[level];
if (!_treeChildren.ContainsKey(part))
{
TopicsCount++;
_treeChildren.Add(part, new TreeNode(part, level, this));
Root.EnqueueUpdate(); // node update
}
MessagesCount++;
_treeChildren[ part ].Add(topic, level + 1, delivery);
return true;
}
private void EnqueueUpdate()
{
if (_updateEnqueued)
return;
_updateEnqueued = true;
Dispatcher.UIThread.Post(
Update,
DispatcherPriority.Background);
}
private void AppendItems()
{
_updateEnqueued = false;
var flatTreeList = new AvaloniaList<TreeNode>();
AppendItems(flatTreeList, this);
_visibleChildren = flatTreeList;
}
private void AppendItems(
AvaloniaList<TreeNode> flatTreeList,
TreeNode treeNode )
{
flatTreeList.Add(treeNode);
if (!treeNode.IsExpanded)
return;
foreach (var ch in treeNode._treeChildren)
AppendItems(flatTreeList, ch.Value);
}
private void Update()
{
AppendItems();
Root.RaisePropertyChanged(nameof(Root.VisibleChildren));
}
private void AddToHistory( MqttDelivery mqttMessage )
{
while ( UiHistoryMessages.Count >= 30 )
UiHistoryMessages.RemoveAt( UiHistoryMessages.Count - 1 );
UiHistoryMessages.Insert( 0, new ReceivedHistoryMessage
{
Id = _historyId++,
Time = DateTime.Now,
Message = mqttMessage,
UIFormattedMessage = $"{DateTime.Now:hh:mm:ss},
{mqttMessage.Header.ToJsonString()}"
} );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment