-
-
Save INTERNALINTERFERENCE/9a385e5b65321e8973971d8ea1c61a2d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Trie : ViewModelBase | |
{ | |
public Trie( | |
string part, | |
int level, | |
Trie? root = null, | |
Trie? parent = null ) | |
{ | |
Part = part; | |
Level = level; | |
Parent = parent; | |
Root = root ?? this; | |
MessagesCount = 1; | |
TopicsCount = 0; | |
History | |
.Connect() | |
.ObserveOn( RxApp.TaskpoolScheduler ) // to run on background thread | |
.Sort( SortExpressionComparer<ReceivedHistoryMessage> | |
.Descending( e => e.Id ) ) | |
.ObserveOn( RxApp.MainThreadScheduler ) //this needed because UI updates need to run on the main | |
.Bind( out _uiHistoryMessages ) | |
.DisposeMany() | |
.Subscribe(); | |
Observable | |
.Interval( TimeSpan.FromSeconds( 1 ) ) | |
.Subscribe( _ => | |
{ | |
Root.EnqueueUpdate(); | |
} ); | |
} | |
#region IO | |
public SourceList<ReceivedHistoryMessage> History { get; } = new(); | |
private readonly ReadOnlyObservableCollection<ReceivedHistoryMessage> _uiHistoryMessages; | |
private readonly Dictionary<string, Trie> _trieChildren = new(); | |
private AvaloniaList<Trie> _visibleChildren = new(); | |
public IAvaloniaReadOnlyList<Trie> VisibleChildren | |
=> _visibleChildren; | |
public ReadOnlyObservableCollection<ReceivedHistoryMessage> UiHistoryMessages | |
=> _uiHistoryMessages; | |
[Reactive] private int TopicsCount { get; set; } | |
[Reactive] private int MessagesCount { get; set; } | |
[Reactive] public bool IsShowMessagesChecked { get; set; } | |
[Reactive] public string? Header { get; set; } | |
[Reactive] public string? Payload { get; set; } | |
[Reactive] public string? Topic { get; set; } | |
[Reactive] public MqttDelivery Delivery { get; set; } = new(); | |
public string Part { get; } | |
public int Level { get; } | |
public Trie? Parent { get; } | |
private Trie Root { get; } | |
private bool _updateEnqueued; | |
private int _historyId; | |
private bool _isExpanded; | |
public bool IsExpanded | |
{ | |
get => _isExpanded; | |
set | |
{ | |
this.RaiseAndSetIfChanged( ref _isExpanded, value ); | |
Root.EnqueueUpdate(); | |
} | |
} | |
#endregion IO | |
public bool Add( | |
string[] topic, | |
int level, | |
MqttDelivery delivery ) | |
{ | |
var changedTopicCount = false; | |
if ( topic.IsNullOrEmpty() ) | |
{ | |
Delivery = delivery; | |
Topic = delivery.Topic; | |
Header = delivery.Header?.ToJsonString( true ); | |
Payload = delivery.Payload?.ToJsonString( true ); | |
TopicsCount = 1; | |
AddToHistory( delivery ); | |
return false; | |
} | |
MessagesCount++; | |
if ( !_trieChildren.ContainsKey( topic[ 0 ] ) ) | |
{ | |
var node = new Trie( topic[ 0 ], level, Root, this ); | |
_trieChildren.TryAdd( topic[ 0 ], node ); | |
changedTopicCount = true; | |
} | |
if ( !_trieChildren[ topic[ 0 ] ] | |
.Add( topic.Skip( 1 ).ToArray(), level + 1, delivery ) | |
&& !changedTopicCount ) | |
return changedTopicCount; | |
changedTopicCount = true; | |
TopicsCount++; | |
return changedTopicCount; | |
} | |
public void EnqueueUpdate() | |
{ | |
if ( _updateEnqueued ) return; | |
_updateEnqueued = true; | |
Dispatcher.UIThread.Post( | |
Update, | |
DispatcherPriority.Background ); | |
} | |
private void AppendItems() | |
{ | |
_updateEnqueued = false; | |
var flatTrieList = new AvaloniaList<Trie>(); | |
AppendItems( | |
flatTrieList, | |
this ); | |
_visibleChildren = flatTrieList; | |
} | |
private void AppendItems( | |
AvaloniaList<Trie> flatTrieList, | |
Trie node ) | |
{ | |
flatTrieList.Add( node ); | |
if ( !node.IsExpanded | |
|| IsShowMessagesChecked ) return; | |
foreach ( var ch in node._trieChildren ) | |
AppendItems( flatTrieList, ch.Value ); | |
} | |
private void Update() | |
{ | |
AppendItems(); | |
Root.RaisePropertyChanged( nameof( Root.VisibleChildren ) ); | |
} | |
public void ForceResync() | |
{ | |
Root.Update(); | |
} | |
private void AddToHistory( MqttMessage mqttMessage ) | |
{ | |
while ( History.Count >= 43 ) | |
History.RemoveAt( History.Count - 1 ); | |
History.Insert( 0, new ReceivedHistoryMessage | |
{ | |
Id = _historyId++, | |
Time = DateTime.Now, | |
Message = mqttMessage | |
} ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
спасибо вам, получилось красиво