using System; using System.Linq; namespace FooEditEngine { class FoldingGenerator : ILineInfoGenerator { public FoldingCollection FoldingCollection = new FoldingCollection(); const long AllowCallTicks = 1000 * 10000; //see.DateTime.Ticks プロパティ long lastUpdateTicks = DateTime.Now.Ticks; IFoldingStrategy _folding; bool _IsSync = true; public IFoldingStrategy FoldingStrategy { get { return this._folding; } set { this._folding = value; if (value == null) this.FoldingCollection.Clear(); } } public void Clear(LineToIndexTable lti) { this.FoldingCollection.Clear(); this._IsSync = false; } public bool Generate(Document doc,LineToIndexTable lti, bool force = true) { if (doc.Length == 0) return false; long nowTick = DateTime.Now.Ticks; bool sync = force || !this._IsSync; if (sync && Math.Abs(nowTick - this.lastUpdateTicks) >= AllowCallTicks) { this.GenerateFolding(doc, lti, 0, doc.Length - 1); this.lastUpdateTicks = nowTick; this._IsSync = true; return true; } return false; } void GenerateFolding(Document doc, LineToIndexTable lti,int start, int end) { if (start > end) throw new ArgumentException("start <= endである必要があります"); if (this.FoldingStrategy != null) { //再生成するとすべて展開状態になってしまうので、閉じてるやつだけを保存しておく FoldingItem[] closed_items = this.FoldingCollection.Where((e) => { return !e.Expand; }).ToArray(); this.FoldingCollection.Clear(); var items = this.FoldingStrategy.AnalyzeDocument(doc, start, end) .Where((item) => { int startRow = lti.GetLineNumberFromIndex(item.Start); int endRow = lti.GetLineNumberFromIndex(item.End); return startRow != endRow; }) .Select((item) => item); this.FoldingCollection.AddRange(items); this.FoldingCollection.ApplyExpandStatus(closed_items); } } public void Update(Document doc, int startIndex, int insertLength, int removeLength) { this.FoldingCollection.UpdateData(doc, startIndex, insertLength, removeLength); this._IsSync = false; this.lastUpdateTicks = DateTime.Now.Ticks; } } }