From: Jean-Philippe Bruyère Date: Sun, 17 Jan 2021 15:09:01 +0000 (+0100) Subject: clean somme unneeded allocations X-Git-Tag: v0.9.5-beta~98 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=11a8c292f7e646b4a16e18a0c5c246e103ea7a36;p=jp%2Fcrow.git clean somme unneeded allocations --- diff --git a/.gitignore b/.gitignore index 31d6ffa8..7f31f93a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ src/GraphicObjects/HorizontalWrappingWidget.cs TestResult.xml *.swp *.perf -.vscode +*.vscode +*.diagsession diff --git a/Crow/src/2d/Size.cs b/Crow/src/2d/Size.cs index 77347f06..2d1d1717 100644 --- a/Crow/src/2d/Size.cs +++ b/Crow/src/2d/Size.cs @@ -63,7 +63,7 @@ namespace Crow public override string ToString () => $"{Width},{Height}"; public static Size Parse(string s) { - string[] d = s.Split(new char[] { ',' }); + string[] d = s.Split(','); return d.Length == 1 ? new Size(int.Parse(d[0])) : new Size( int.Parse(d[0]), int.Parse(d[1])); diff --git a/Crow/src/Font.cs b/Crow/src/Font.cs index 4bf5fab3..89ce7edb 100644 --- a/Crow/src/Font.cs +++ b/Crow/src/Font.cs @@ -93,12 +93,12 @@ namespace Crow Font f = new Font (); if (!string.IsNullOrEmpty (s)) { - string[] c = s.TrimStart().TrimEnd().Split (new char[] { ',' }); + string[] c = s.TrimStart().TrimEnd().Split (','); if (c.Length == 2) f.Size = int.Parse (c [1].TrimStart()); - string[] n = c [0].TrimEnd().Split (new char[] { ' ' }); + string[] n = c [0].TrimEnd().Split (' '); f.Name = n [0]; diff --git a/Crow/src/Widgets/Label.cs b/Crow/src/Widgets/Label.cs index 3232c4e4..486f58dc 100644 --- a/Crow/src/Widgets/Label.cs +++ b/Crow/src/Widgets/Label.cs @@ -11,6 +11,7 @@ using System.ComponentModel; using System.Text; using System.Diagnostics; using Glfw; +using System.Collections; namespace Crow { internal struct TextSpan @@ -52,20 +53,103 @@ namespace Crow { HashCode.Combine (Line, Column); } } - internal struct LineSpan + internal class LineCollection : ICollection { - public readonly int Start; - public readonly int End; - public readonly int EndIncludingLineBreak; + LineSpan[] lines; + + public int Count => throw new NotImplementedException (); + + public bool IsReadOnly => throw new NotImplementedException (); + + public void Add (LineSpan item) { + throw new NotImplementedException (); + } + + public void Clear () { + throw new NotImplementedException (); + } + + public bool Contains (LineSpan item) { + throw new NotImplementedException (); + } + + public void CopyTo (LineSpan[] array, int arrayIndex) { + throw new NotImplementedException (); + } + + public IEnumerator GetEnumerator () { + throw new NotImplementedException (); + } + + public bool Remove (LineSpan item) { + throw new NotImplementedException (); + } + + IEnumerator IEnumerable.GetEnumerator () { + throw new NotImplementedException (); + } + + /*public LineSpan this[int index] { + get => lines[index]; + set => lines[index] = value; + } + public int Count => lines.Length; + public bool IsReadOnly => false; + + public void Add (LineSpan item) { + + } + + public void Clear () { + throw new NotImplementedException (); + } + + public bool Contains (LineSpan item) { + throw new NotImplementedException (); + } + + public void CopyTo (LineSpan[] array, int arrayIndex) { + throw new NotImplementedException (); + } + + public IEnumerator GetEnumerator () { + throw new NotImplementedException (); + } + + public int IndexOf (LineSpan item) { + throw new NotImplementedException (); + } + + public void Insert (int index, LineSpan item) { + throw new NotImplementedException (); + } + + public bool Remove (LineSpan item) { + throw new NotImplementedException (); + } + + public void RemoveAt (int index) { + throw new NotImplementedException (); + } + + IEnumerator IEnumerable.GetEnumerator () { + throw new NotImplementedException (); + }*/ + } + internal struct LineSpan + { + public int Start; + public int Length; + public int LengthIncludingLineBreak; public int LengthInPixel; - public int Length => End - Start; - public int LengthIncludingLineBreak => EndIncludingLineBreak - Start; - public int LineBreakLength => EndIncludingLineBreak - End; + public int End => Start + Length; + public int EndIncludingLineBreak => Start + LengthIncludingLineBreak; + public int LineBreakLength => LengthIncludingLineBreak - Length; public bool HasLineBreak => LineBreakLength > 0; public LineSpan (int start, int end, int endIncludingLineBreak) { Start = start; - End = end; - EndIncludingLineBreak = endIncludingLineBreak; + Length = end - start; + LengthIncludingLineBreak = endIncludingLineBreak - start; LengthInPixel = -1; } public LineSpan WithStartOffset (int start) => new LineSpan (Start + start, End, EndIncludingLineBreak); @@ -845,13 +929,6 @@ namespace Crow { #endregion #region Keyboard handling - void checkShift () { - if (IFace.Shift) { - if (!selectionStart.HasValue) - selectionStart = currentLoc; - } else - selectionStart = null; - } public override void onKeyDown (object sender, KeyEventArgs e) { switch (e.Key) { @@ -912,12 +989,19 @@ namespace Crow { e.Handled = true; } - #endregion - /// - /// Update Current Column, line and TextCursorPos - /// from mouseLocalPos - /// - void updateLocation (Context gr, int clientWidth, ref CharLocation? location) + void checkShift () { + if (IFace.Shift) { + if (!selectionStart.HasValue) + selectionStart = currentLoc; + } else + selectionStart = null; + } + + #endregion + /// + /// location column from + /// + void updateLocation (Context gr, int clientWidth, ref CharLocation? location) { if (location == null) return; diff --git a/Crow/src/Widgets/OldTextBox.cs b/Crow/src/Widgets/OldTextBox.cs new file mode 100644 index 00000000..8c0fce1f --- /dev/null +++ b/Crow/src/Widgets/OldTextBox.cs @@ -0,0 +1,184 @@ +// Copyright (c) 2013-2020 Jean-Philippe Bruyère +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using Crow.Cairo; +using Glfw; + +namespace Crow +{ + public class OldTextBox : OldLabel + { + #region CTOR + protected OldTextBox() {} + public OldTextBox(Interface iface, string style = null) : base (iface, style) { } + #endregion + + #region GraphicObject overrides + [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam + { + get => base.HasFocus; + set { + if (base.HasFocus == value) + return; + base.HasFocus = value; + RegisterForRedraw(); + } + } + + protected override void onDraw (Context gr) + { + base.onDraw (gr); + } + #endregion + + #region Keyboard handling + public override void onKeyDown (object sender, KeyEventArgs e) + { + Key key = e.Key; + + switch (key) + { + case Key.Backspace: + if (CurrentPosition == 0) + return; + DeleteChar(); + break; + case Key.Delete: + if (selectionIsEmpty) { + if (!MoveRight ()) + return; + }else if (IFace.Shift) + IFace.Clipboard = SelectedText; + DeleteChar (); + break; + case Key.KeypadEnter: + case Key.Enter: + if (!selectionIsEmpty) + DeleteChar (); + if (Multiline) + InsertLineBreak (); + else + OnTextChanged(this,new TextChangeEventArgs(Text)); + break; + case Key.Escape: + Text = ""; + CurrentColumn = 0; + SelRelease = -1; + break; + case Key.Home: + if (IFace.Shift) { + if (selectionIsEmpty) + SelBegin = new Point (CurrentColumn, CurrentLine); + if (IFace.Ctrl) + CurrentLine = 0; + CurrentColumn = 0; + SelRelease = new Point (CurrentColumn, CurrentLine); + break; + } + SelRelease = -1; + if (IFace.Ctrl) + CurrentLine = 0; + CurrentColumn = 0; + break; + case Key.End: + if (IFace.Shift) { + if (selectionIsEmpty) + SelBegin = CurrentPosition; + if (IFace.Ctrl) + CurrentLine = int.MaxValue; + CurrentColumn = int.MaxValue; + SelRelease = CurrentPosition; + break; + } + SelRelease = -1; + if (IFace.Ctrl) + CurrentLine = int.MaxValue; + CurrentColumn = int.MaxValue; + break; + case Key.Insert: + if (IFace.Shift) + this.Insert (IFace.Clipboard); + else if (IFace.Ctrl && !selectionIsEmpty) + IFace.Clipboard = this.SelectedText; + break; + case Key.Left: + if (IFace.Shift) { + if (selectionIsEmpty) + SelBegin = new Point(CurrentColumn, CurrentLine); + if (IFace.Ctrl) + GotoWordStart (); + else if (!MoveLeft ()) + return; + SelRelease = CurrentPosition; + break; + } + SelRelease = -1; + if (IFace.Ctrl) + GotoWordStart (); + else + MoveLeft(); + break; + case Key.Right: + if (IFace.Shift) { + if (selectionIsEmpty) + SelBegin = CurrentPosition; + if (IFace.Ctrl) + GotoWordEnd (); + else if (!MoveRight ()) + return; + SelRelease = CurrentPosition; + break; + } + SelRelease = -1; + if (IFace.Ctrl) + GotoWordEnd (); + else + MoveRight (); + break; + case Key.Up: + if (IFace.Shift) { + if (selectionIsEmpty) + SelBegin = CurrentPosition; + CurrentLine--; + SelRelease = CurrentPosition; + break; + } + SelRelease = -1; + CurrentLine--; + break; + case Key.Down: + if (IFace.Shift) { + if (selectionIsEmpty) + SelBegin = CurrentPosition; + CurrentLine++; + SelRelease = CurrentPosition; + break; + } + SelRelease = -1; + CurrentLine++; + break; + case Key.Tab: + this.Insert ("\t"); + break; + default: + break; + } + e.Handled = true; + base.onKeyDown (sender, e); + RegisterForGraphicUpdate (); + } + public override void onKeyPress (object sender, KeyPressEventArgs e) + { + base.onKeyPress (sender, e); + + this.Insert (e.KeyChar.ToString()); + + SelRelease = -1; + SelBegin = new Point(CurrentColumn, SelBegin.Y); + + RegisterForGraphicUpdate(); + } + #endregion + } +} diff --git a/Crow/src/Widgets/TextBox.cs b/Crow/src/Widgets/TextBox.cs index aa916999..f33f89d0 100644 --- a/Crow/src/Widgets/TextBox.cs +++ b/Crow/src/Widgets/TextBox.cs @@ -7,30 +7,13 @@ using Glfw; namespace Crow { - public class TextBox : OldLabel + public class TextBox : Label { #region CTOR protected TextBox() {} public TextBox(Interface iface, string style = null) : base (iface, style) { } #endregion - #region GraphicObject overrides - [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam - { - get => base.HasFocus; - set { - if (base.HasFocus == value) - return; - base.HasFocus = value; - RegisterForRedraw(); - } - } - - protected override void onDraw (Context gr) - { - base.onDraw (gr); - } - #endregion #region Keyboard handling public override void onKeyDown (object sender, KeyEventArgs e) @@ -39,7 +22,7 @@ namespace Crow switch (key) { - case Key.Backspace: + /*case Key.Backspace: if (CurrentPosition == 0) return; DeleteChar(); @@ -160,24 +143,23 @@ namespace Crow break; case Key.Tab: this.Insert ("\t"); - break; + break;*/ default: + base.onKeyDown (sender, e); break; } e.Handled = true; - base.onKeyDown (sender, e); - RegisterForGraphicUpdate (); } public override void onKeyPress (object sender, KeyPressEventArgs e) { base.onKeyPress (sender, e); - this.Insert (e.KeyChar.ToString()); + /*Insert (e.KeyChar.ToString()); SelRelease = -1; SelBegin = new Point(CurrentColumn, SelBegin.Y); - RegisterForGraphicUpdate(); + RegisterForGraphicUpdate();*/ } #endregion } diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index afaeebeb..e76c807f 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -203,11 +203,13 @@ namespace Crow public virtual void NotifyValueChanged(string MemberName, object _value) { //Debug.WriteLine ("Value changed: {0}->{1} = {2}", this, MemberName, _value); - ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value)); + if (ValueChanged != null) + ValueChanged.Invoke(this, new ValueChangeEventArgs(MemberName, _value)); } public void NotifyValueChangedAuto (object _value, [CallerMemberName] string caller = null) { - NotifyValueChanged (caller, _value); + if (ValueChanged != null) + NotifyValueChanged (caller, _value); } #endregion @@ -1573,10 +1575,12 @@ namespace Crow RegisterForLayouting (LayoutingType.Y); break; } - LayoutChanged.Raise (this, new LayoutingEventArgs (layoutType)); + if (LayoutChanged != null) + LayoutChanged.Invoke (this, new LayoutingEventArgs (layoutType)); } internal protected void raiseLayoutChanged(LayoutingEventArgs e){ - LayoutChanged.Raise (this, e); + if (LayoutChanged != null) + LayoutChanged.Raise (this, e); } /// Update layout component only one at a time, this is where the computation of alignement /// and size take place. diff --git a/Crow/src/styling/StyleReader.cs b/Crow/src/styling/StyleReader.cs index 84839890..2602b7a8 100644 --- a/Crow/src/styling/StyleReader.cs +++ b/Crow/src/styling/StyleReader.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text.RegularExpressions; +using System.Globalization; using Crow.Coding; namespace Crow @@ -15,8 +16,7 @@ namespace Crow /// Parser for style files. /// //TODO: style key shared by different class may use only first encouneter class setter, which can cause bug. - public class StyleReader : StreamReader - { + public class StyleReader : StreamReader { enum States { classNames, members, value, endOfStatement } States curState = States.classNames; @@ -24,17 +24,24 @@ namespace Crow int line = 1; #region Character ValidityCheck - static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); - static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}"); - static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); - static Regex rxDecimal = new Regex(@"[0-9]+"); - static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+"); + /*static Regex rxValidChar = new Regex (@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); + static Regex rxNameStartChar = new Regex (@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}"); + static Regex rxNameChar = new Regex (@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}"); + static Regex rxDecimal = new Regex (@"[0-9]+"); + static Regex rxHexadecimal = new Regex (@"[0-9a-fA-F]+");*/ - bool nextCharIsValidCharStartName { - get => rxNameStartChar.IsMatch(new string(new char[]{PeekChar()})); - } + bool nextCharIsValidCharStartName => Char.IsLetter (PeekChar ()) || PeekChar () == '_'; bool nextCharIsValidCharName { - get => rxNameChar.IsMatch(new string(new char[]{PeekChar()})); + get { + if (Char.IsLetterOrDigit (PeekChar ())) + return true; + UnicodeCategory uc = Char.GetUnicodeCategory (PeekChar ()); + return + uc == UnicodeCategory.NonSpacingMark || + uc == UnicodeCategory.SpacingCombiningMark || + uc == UnicodeCategory.ConnectorPunctuation || + uc == UnicodeCategory.Format; + } } #endregion diff --git a/Samples/HelloWorld/main.cs b/Samples/HelloWorld/main.cs index 44ec3fb8..73288f1b 100644 --- a/Samples/HelloWorld/main.cs +++ b/Samples/HelloWorld/main.cs @@ -3,10 +3,10 @@ using Crow; namespace HelloWorld { - class Program { + class Program : SampleBase { static void Main (string[] args) { - using (Interface app = new Interface ()) { - app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow"); + using (Interface app = new Program ()) { + app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow").DataSource = sender; app.Run (); } } diff --git a/Samples/HelloWorld/ui/helloworld.crow b/Samples/HelloWorld/ui/helloworld.crow index fe05d1e2..b178bbf2 100644 --- a/Samples/HelloWorld/ui/helloworld.crow +++ b/Samples/HelloWorld/ui/helloworld.crow @@ -1,2 +1,26 @@  -