NBTExplorer/SearchWorker.cs

194 lines
5.5 KiB
C#
Raw Normal View History

2012-09-02 00:08:54 +00:00
using System;
using System.Collections.Generic;
using NBTExplorer.Model;
using System.Diagnostics;
2012-09-02 00:08:54 +00:00
namespace NBTExplorer
{
2012-11-10 19:00:11 +00:00
internal interface ISearchState
2012-09-02 00:08:54 +00:00
{
2012-11-10 19:00:11 +00:00
DataNode RootNode { get; set; }
2012-09-02 00:08:54 +00:00
2012-11-10 19:00:11 +00:00
IEnumerator<DataNode> State { get; set; }
2013-08-09 06:02:22 +00:00
bool TerminateOnDiscover { get; set; }
2012-09-02 00:08:54 +00:00
float ProgressRate { get; set; }
2012-11-10 19:00:11 +00:00
void InvokeDiscoverCallback (DataNode node);
void InvokeProgressCallback (DataNode node);
void InvokeCollapseCallback (DataNode node);
void InvokeEndCallback (DataNode node);
2012-11-20 06:02:35 +00:00
bool TestNode (DataNode node);
}
internal abstract class NameValueSearchState : ISearchState
{
public virtual string SearchName { get; set; }
public virtual string SearchValue { get; set; }
public DataNode RootNode { get; set; }
public IEnumerator<DataNode> State { get; set; }
2013-08-09 06:02:22 +00:00
public bool TerminateOnDiscover { get; set; }
public float ProgressRate { get; set; }
2012-11-20 06:02:35 +00:00
public abstract void InvokeDiscoverCallback (DataNode node);
public abstract void InvokeProgressCallback (DataNode node);
public abstract void InvokeCollapseCallback (DataNode node);
public abstract void InvokeEndCallback (DataNode node);
2013-08-09 06:02:22 +00:00
protected NameValueSearchState ()
{
TerminateOnDiscover = true;
ProgressRate = .5f;
2013-08-09 06:02:22 +00:00
}
2012-11-20 06:02:35 +00:00
public bool TestNode (DataNode node)
{
bool mName = SearchName == null;
bool mValue = SearchValue == null;
if (SearchName != null) {
string tagName = node.NodeName;
if (tagName != null)
mName = tagName.Contains(SearchName);
}
if (SearchValue != null) {
string tagValue = node.NodeDisplay;
if (tagValue != null)
mValue = tagValue.Contains(SearchValue);
}
if (mName && mValue) {
return true;
}
return false;
}
2012-09-02 00:08:54 +00:00
}
internal class SearchWorker
{
2012-11-10 19:00:11 +00:00
private ISearchState _state;
2012-09-02 00:08:54 +00:00
private bool _cancel;
private object _lock;
private Stopwatch _progressWatch;
private float _progressTime;
private float _lastSampleTime;
2012-11-10 19:00:11 +00:00
public SearchWorker (ISearchState state)
2012-09-02 00:08:54 +00:00
{
_state = state;
_lock = new object();
}
public void Cancel ()
{
lock (_lock) {
_cancel = true;
}
}
public void Run ()
{
_progressWatch = new Stopwatch();
_progressWatch.Start();
2012-09-02 00:08:54 +00:00
if (_state.State == null)
_state.State = FindNode(_state.RootNode).GetEnumerator();
if (!_state.State.MoveNext())
InvokeEndCallback();
_progressWatch.Stop();
2012-09-02 00:08:54 +00:00
}
private IEnumerable<DataNode> FindNode (DataNode node)
{
lock (_lock) {
if (_cancel)
yield break;
}
if (node == null)
yield break;
bool searchExpanded = false;
if (!node.IsExpanded) {
node.Expand();
searchExpanded = true;
}
TagDataNode tagNode = node as TagDataNode;
if (tagNode != null) {
float currentSampleTime = (float)_progressWatch.Elapsed.TotalSeconds;
_progressTime += (currentSampleTime - _lastSampleTime);
_lastSampleTime = currentSampleTime;
if (_progressTime > _state.ProgressRate) {
InvokeProgressCallback(node);
_progressTime -= _state.ProgressRate;
}
2013-08-09 06:02:22 +00:00
2012-11-20 06:02:35 +00:00
if (_state.TestNode(tagNode)) {
InvokeDiscoverCallback(node);
2013-08-09 06:02:22 +00:00
if (_state.TerminateOnDiscover)
yield return node;
2012-11-20 06:02:35 +00:00
}
/*bool mName = _state.SearchName == null;
2012-09-02 00:08:54 +00:00
bool mValue = _state.SearchValue == null;
if (_state.SearchName != null) {
string tagName = node.NodeName;
if (tagName != null)
mName = tagName.Contains(_state.SearchName);
}
if (_state.SearchValue != null) {
string tagValue = node.NodeDisplay;
if (tagValue != null)
mValue = tagValue.Contains(_state.SearchValue);
}
if (mName && mValue) {
InvokeDiscoverCallback(node);
yield return node;
2012-11-20 06:02:35 +00:00
}*/
2012-09-02 00:08:54 +00:00
}
foreach (DataNode sub in node.Nodes) {
foreach (DataNode s in FindNode(sub))
yield return s;
}
if (searchExpanded) {
if (!node.IsModified) {
node.Collapse();
InvokeCollapseCallback(node);
}
}
}
2013-08-09 06:02:22 +00:00
private void InvokeProgressCallback (DataNode node)
{
_state.InvokeProgressCallback(node);
}
2012-09-02 00:08:54 +00:00
private void InvokeDiscoverCallback (DataNode node)
{
2012-11-10 19:00:11 +00:00
_state.InvokeDiscoverCallback(node);
2012-09-02 00:08:54 +00:00
}
private void InvokeCollapseCallback (DataNode node)
{
2012-11-10 19:00:11 +00:00
_state.InvokeCollapseCallback(node);
2012-09-02 00:08:54 +00:00
}
private void InvokeEndCallback ()
{
2012-11-10 19:00:11 +00:00
_state.InvokeEndCallback(null);
2012-09-02 00:08:54 +00:00
}
}
}