981
975
readonly object syncObject = new object();
982
BackgroundWorker foldSegmentWorker = null;
983
BackgroundWorker FoldSegmentWorker {
985
if (foldSegmentWorker == null) {
986
foldSegmentWorker = new BackgroundWorker ();
987
foldSegmentWorker.WorkerSupportsCancellation = true;
988
foldSegmentWorker.DoWork += UpdateFoldSegmentWorker;
990
return foldSegmentWorker;
994
public void UpdateFoldSegments (List<FoldSegment> newSegments)
996
UpdateFoldSegments (newSegments, true);
1000
public void UpdateFoldSegments (List<FoldSegment> newSegments, bool runInThread)
977
CancellationTokenSource foldSegmentSrc;
978
Task foldSegmentTask;
980
public void UpdateFoldSegments (List<FoldSegment> newSegments, bool startTask = false, bool useApplicationInvoke = false)
1002
982
if (newSegments == null) {
985
Console.WriteLine ("startTask={0}, useApplicationInvoke={1}", startTask, useApplicationInvoke);
1006
987
InterruptFoldWorker ();
1008
UpdateFoldSegmentWorker (null, new DoWorkEventArgs (newSegments));
990
var newFoldedSegments = UpdateFoldSegmentWorker (newSegments, out update);
991
if (useApplicationInvoke) {
992
Gtk.Application.Invoke (delegate {
993
foldedSegments = newFoldedSegments;
994
InformFoldTreeUpdated ();
997
foldedSegments = newFoldedSegments;
998
InformFoldTreeUpdated ();
1011
FoldSegmentWorker.RunWorkerAsync (newSegments);
1002
foldSegmentSrc = new CancellationTokenSource ();
1003
var token = foldSegmentSrc.Token;
1004
foldSegmentTask = Task.Factory.StartNew (delegate {
1005
var segments = UpdateFoldSegmentWorker (newSegments, out update, token);
1006
if (token.IsCancellationRequested)
1008
Gtk.Application.Invoke (delegate {
1009
if (token.IsCancellationRequested)
1011
foldedSegments = segments;
1012
InformFoldTreeUpdated ();
1014
1019
void RemoveFolding (FoldSegment folding)
1023
1028
/// Updates the fold segments in a background worker thread. Don't call this method outside of a background worker.
1024
1029
/// Use UpdateFoldSegments instead.
1026
public void UpdateFoldSegmentWorker (object sender, DoWorkEventArgs e)
1031
HashSet<FoldSegment> UpdateFoldSegmentWorker (List<FoldSegment> newSegments, out bool update, CancellationToken token = default(CancellationToken))
1028
var worker = sender as BackgroundWorker;
1029
var newSegments = (List<FoldSegment>)e.Argument;
1030
1033
var oldSegments = new List<FoldSegment> (FoldSegments);
1031
1034
int oldIndex = 0;
1032
1035
bool foldedSegmentAdded = false;
1033
1036
newSegments.Sort ();
1034
1037
var newFoldedSegments = new HashSet<FoldSegment> ();
1035
1038
foreach (FoldSegment newFoldSegment in newSegments) {
1036
if (worker != null && worker.CancellationPending)
1039
if (token.IsCancellationRequested) {
1038
1043
int offset = newFoldSegment.Offset;
1039
1044
while (oldIndex < oldSegments.Count && offset > oldSegments [oldIndex].Offset) {
1040
1045
RemoveFolding (oldSegments [oldIndex]);
1075
1080
while (oldIndex < oldSegments.Count) {
1081
if (token.IsCancellationRequested) {
1076
1085
RemoveFolding (oldSegments [oldIndex]);
1079
1088
bool countChanged = foldedSegments.Count != newFoldedSegments.Count;
1080
if (worker != null) {
1081
Gtk.Application.Invoke (delegate {
1082
foldedSegments = newFoldedSegments;
1083
InformFoldTreeUpdated ();
1084
if (foldedSegmentAdded || countChanged)
1088
foldedSegments = newFoldedSegments;
1089
InformFoldTreeUpdated ();
1089
update = foldedSegmentAdded || countChanged;
1090
return newFoldedSegments;
1093
1093
public void WaitForFoldUpdateFinished ()
1095
while (FoldSegmentWorker.IsBusy)
1096
System.Threading.Thread.Sleep (10);
1095
if (foldSegmentTask != null) {
1096
foldSegmentTask.Wait (5000);
1097
foldSegmentTask = null;
1099
1101
void InterruptFoldWorker ()
1101
if (!FoldSegmentWorker.IsBusy)
1103
if (foldSegmentSrc == null)
1103
FoldSegmentWorker.CancelAsync ();
1105
foldSegmentSrc.Cancel ();
1104
1106
WaitForFoldUpdateFinished ();
1107
foldSegmentSrc = null;
1107
1110
public void ClearFoldSegments ()
1421
1424
public static bool IsWordSeparator (char ch)
1425
1426
return Char.IsWhiteSpace (ch) || (Char.IsPunctuation (ch) && ch != '_');
1431
1429
public bool IsWholeWordAt (int offset, int length)
1434
1431
return (offset == 0 || IsWordSeparator (GetCharAt (offset - 1))) &&
1435
1432
(offset + length == TextLength || IsWordSeparator (GetCharAt (offset + length)));