浏览代码

Merge remote-tracking branch 'origin/master' into image

/main
gewentao 6 年前
当前提交
873f85c2
共有 85 个文件被更改,包括 5320 次插入268 次删除
  1. 5
      Assets/UIWidgets/Tests/Menu.cs
  2. 61
      Assets/UIWidgets/Tests/Paragraph.cs
  3. 90
      Assets/UIWidgets/editor/editor_window.cs
  4. 57
      Assets/UIWidgets/foundation/node.cs
  5. 249
      Assets/UIWidgets/gestures/arena.cs
  6. 56
      Assets/UIWidgets/rendering/binding.cs
  7. 73
      Assets/UIWidgets/rendering/box.cs
  8. 40
      Assets/UIWidgets/rendering/object.cs
  9. 124
      Assets/UIWidgets/rendering/proxy_box.cs
  10. 2
      Assets/UIWidgets/rendering/sliver_multi_box_adaptor.cs
  11. 12
      Assets/UIWidgets/rendering/view.cs
  12. 221
      Assets/UIWidgets/scheduler/binding.cs
  13. 6
      Assets/UIWidgets/ui/geometry.cs
  14. 4
      Assets/UIWidgets/ui/painting/canvas.cs
  15. 5
      Assets/UIWidgets/ui/painting/canvas_impl.cs
  16. 11
      Assets/UIWidgets/ui/painting/draw_cmd.cs
  17. 4
      Assets/UIWidgets/ui/painting/picture.cs
  18. 5
      Assets/UIWidgets/ui/text.cs
  19. 29
      Assets/UIWidgets/ui/txt/linebreaker.cs
  20. 226
      Assets/UIWidgets/ui/txt/paragraph.cs
  21. 34
      Assets/UIWidgets/ui/window.cs
  22. 5
      Packages/manifest.json
  23. 2
      ProjectSettings/ProjectVersion.txt
  24. 102
      Assets/UIWidgets/Tests/Gestures.cs
  25. 3
      Assets/UIWidgets/Tests/Gestures.cs.meta
  26. 8
      Assets/UIWidgets/async.meta
  27. 144
      Assets/UIWidgets/foundation/assertions.cs
  28. 3
      Assets/UIWidgets/foundation/assertions.cs.meta
  29. 52
      Assets/UIWidgets/foundation/basic_types.cs
  30. 3
      Assets/UIWidgets/foundation/basic_types.cs.meta
  31. 38
      Assets/UIWidgets/foundation/debug.cs
  32. 3
      Assets/UIWidgets/foundation/debug.cs.meta
  33. 1001
      Assets/UIWidgets/foundation/diagnostics.cs
  34. 3
      Assets/UIWidgets/foundation/diagnostics.cs.meta
  35. 163
      Assets/UIWidgets/foundation/node.mixin.gen.cs
  36. 11
      Assets/UIWidgets/foundation/node.mixin.gen.cs.meta
  37. 88
      Assets/UIWidgets/foundation/node.mixin.njk
  38. 3
      Assets/UIWidgets/foundation/node.mixin.njk.meta
  39. 95
      Assets/UIWidgets/foundation/print.cs
  40. 3
      Assets/UIWidgets/foundation/print.cs.meta
  41. 8
      Assets/UIWidgets/gestures.meta
  42. 11
      Assets/UIWidgets/gestures/arena.cs.meta
  43. 100
      Assets/UIWidgets/gestures/binding.cs
  44. 3
      Assets/UIWidgets/gestures/binding.cs.meta
  45. 21
      Assets/UIWidgets/gestures/constants.cs
  46. 3
      Assets/UIWidgets/gestures/constants.cs.meta
  47. 142
      Assets/UIWidgets/gestures/converter.cs
  48. 3
      Assets/UIWidgets/gestures/converter.cs.meta
  49. 90
      Assets/UIWidgets/gestures/drag_details.cs
  50. 3
      Assets/UIWidgets/gestures/drag_details.cs.meta
  51. 142
      Assets/UIWidgets/gestures/events.cs
  52. 3
      Assets/UIWidgets/gestures/events.cs.meta
  53. 57
      Assets/UIWidgets/gestures/hit_test.cs
  54. 3
      Assets/UIWidgets/gestures/hit_test.cs.meta
  55. 186
      Assets/UIWidgets/gestures/lsq_resolver.cs
  56. 3
      Assets/UIWidgets/gestures/lsq_resolver.cs.meta
  57. 281
      Assets/UIWidgets/gestures/monodrag.cs
  58. 3
      Assets/UIWidgets/gestures/monodrag.cs.meta
  59. 190
      Assets/UIWidgets/gestures/multitap.cs
  60. 3
      Assets/UIWidgets/gestures/multitap.cs.meta
  61. 66
      Assets/UIWidgets/gestures/pointer_router.cs
  62. 3
      Assets/UIWidgets/gestures/pointer_router.cs.meta
  63. 239
      Assets/UIWidgets/gestures/recognizer.cs
  64. 3
      Assets/UIWidgets/gestures/recognizer.cs.meta
  65. 154
      Assets/UIWidgets/gestures/tap.cs
  66. 3
      Assets/UIWidgets/gestures/tap.cs.meta
  67. 118
      Assets/UIWidgets/gestures/team.cs
  68. 3
      Assets/UIWidgets/gestures/team.cs.meta
  69. 214
      Assets/UIWidgets/gestures/velocity_tracker.cs
  70. 3
      Assets/UIWidgets/gestures/velocity_tracker.cs.meta
  71. 51
      Assets/UIWidgets/ui/pointer.cs
  72. 3
      Assets/UIWidgets/ui/pointer.cs.meta
  73. 73
      Assets/UIWidgets/ui/txt/font_manager.cs
  74. 3
      Assets/UIWidgets/ui/txt/font_manager.cs.meta
  75. 119
      Assets/UIWidgets/ui/txt/mesh.cs
  76. 3
      Assets/UIWidgets/ui/txt/mesh.cs.meta
  77. 13
      Assets/UIWidgets/ui/txt/utils.cs
  78. 3
      Assets/UIWidgets/ui/txt/utils.cs.meta
  79. 26
      Assets/UIWidgets/async/microtask_queue.cs
  80. 3
      Assets/UIWidgets/async/microtask_queue.cs.meta
  81. 105
      Assets/UIWidgets/async/priority_queue.cs
  82. 3
      Assets/UIWidgets/async/priority_queue.cs.meta
  83. 67
      Assets/UIWidgets/async/timer.cs
  84. 11
      Assets/UIWidgets/async/timer.cs.meta

5
Assets/UIWidgets/Tests/Menu.cs


public static void renderRenderParagraph() {
EditorWindow.GetWindow(typeof(Paragraph));
}
[MenuItem("UIWidgetsTests/Gestures")]
public static void gestures() {
EditorWindow.GetWindow(typeof(Gestures));
}
}
}

61
Assets/UIWidgets/Tests/Paragraph.cs


using UnityEngine;
using Color = UIWidgets.ui.Color;
using FontStyle = UIWidgets.ui.FontStyle;
using Rect = UIWidgets.ui.Rect;
namespace UIWidgets.Tests
{

this._options = new Func<RenderBox>[] {
this.text,
this.textHeight,
this.textOverflow
this.textOverflow,
this.textAlign,
this.titleContent = new GUIContent("RenderBoxes");
this.titleContent = new GUIContent("RenderParagraph");
}
private WindowAdapter windowAdapter;

return null;
}
private RenderBox box(RenderParagraph p, int width = 300, int height = 300)
private RenderBox box(RenderParagraph p, int width = 200, int height = 200)
{
return new RenderConstrainedOverflowBox(
minWidth: width,

alignment: Alignment.center,
child: p
)
;
}
private RenderBox flexItemBox(RenderParagraph p, int width = 200, int height = 150)
{
return new RenderConstrainedBox(
additionalConstraints: new BoxConstraints(minWidth: width, maxWidth: width, minHeight: height,
maxHeight: height),
child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFFFFFFFF),

child: new RenderPadding(EdgeInsets.all(10), p
)
);
));
}
RenderBox text()

})));
}
RenderBox textAlign()
{
var flexbox = new RenderFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center);
var height = 120;
flexbox.add(flexItemBox(
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + "Align To Left\nMaterials define how light reacts with the " +
"surface of a model, and are an essential ingredient in making " +
"believable visuals. When you’ve created a "), textAlign: TextAlign.left),
height: height
));
flexbox.add(flexItemBox(
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + "Align To Rgit\nMaterials define how light reacts with the " +
"surface of a model, and are an essential ingredient in making " +
"believable visuals. When you’ve created a "), textAlign: TextAlign.right),
height: height
));
flexbox.add(flexItemBox(
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + "Align To Center\nMaterials define how light reacts with the " +
"surface of a model, and are an essential ingredient in making " +
"believable visuals. When you’ve created a "), textAlign: TextAlign.center),
height: height
));
flexbox.add(flexItemBox(
new RenderParagraph(new TextSpan("Align To Justify\nMaterials define how light reacts with the " +
"surface of a model, and are an essential ingredient in making " +
"believable visuals. When you’ve created a "), textAlign: TextAlign.justify),
height: height
));
return flexbox;
}
RenderBox textOverflow()
{
return box(

new TextSpan("Real-time 3D revolutionizes:\n the animation pipeline.\n\n\revolutionizesn\n\nReal-time 3D revolutionizes the animation pipeline ", null),
new TextSpan("Real-time 3D revolutionizes:\n the animation pipeline.\n\n\nrevolutionizesn\n\nReal-time 3D revolutionizes the animation pipeline ", null),
})), 200, 80);
}

text: "Height 1.2 Text:" + text),
new TextSpan(style: new painting.TextStyle(height: 1.5),
text: "Height 1.5 Text:" + text),
})));
})), width: 300, height: 300);
}
}

90
Assets/UIWidgets/editor/editor_window.cs


using System;
using System.Collections.Generic;
using System.Diagnostics;
using UIWidgets.async;
using UIWidgets.ui;
using UnityEditor;
using UnityEngine;

public class WindowAdapter : Window {
public WindowAdapter(EditorWindow editorWindow) {
this.editorWindow = editorWindow;
this.editorWindow.wantsMouseMove = false;
this.editorWindow.wantsMouseEnterLeaveWindow = false;
this._physicalSize = new Size(this._lastPosition.width, this._lastPosition.height);
this._physicalSize = new Size(
this._lastPosition.width * EditorGUIUtility.pixelsPerPoint,
this._lastPosition.height * EditorGUIUtility.pixelsPerPoint);
public EditorWindow editorWindow;
public Rect _lastPosition;
public readonly DateTime _epoch = DateTime.Now;
public readonly EditorWindow editorWindow;
Rect _lastPosition;
readonly DateTime _epoch = new DateTime(Stopwatch.GetTimestamp());
readonly MicrotaskQueue _microtaskQueue = new MicrotaskQueue();
readonly TimerProvider _timerProvider = new TimerProvider();
if (Event.current.type == EventType.Repaint) {
var evt = Event.current;
if (evt.type == EventType.Repaint) {
this.onBeginFrame(DateTime.Now - this._epoch);
this.onBeginFrame(new DateTime(Stopwatch.GetTimestamp()) - this._epoch);
this.flushMicrotasks();
return;
}
if (this.onPointerEvent != null) {
PointerData pointerData = null;
if (evt.type == EventType.MouseDown) {
pointerData = new PointerData(
timeStamp: DateTime.Now,
change: PointerChange.down,
kind: PointerDeviceKind.mouse,
device: evt.button,
physicalX: evt.mousePosition.x * this._devicePixelRatio,
physicalY: evt.mousePosition.y * this._devicePixelRatio
);
} else if (evt.type == EventType.MouseUp || evt.rawType == EventType.MouseUp) {
pointerData = new PointerData(
timeStamp: DateTime.Now,
change: PointerChange.up,
kind: PointerDeviceKind.mouse,
device: evt.button,
physicalX: evt.mousePosition.x * this._devicePixelRatio,
physicalY: evt.mousePosition.y * this._devicePixelRatio
);
} else if (evt.type == EventType.MouseDrag) {
pointerData = new PointerData(
timeStamp: DateTime.Now,
change: PointerChange.move,
kind: PointerDeviceKind.mouse,
device: evt.button,
physicalX: evt.mousePosition.x * this._devicePixelRatio,
physicalY: evt.mousePosition.y * this._devicePixelRatio
);
}
if (pointerData != null) {
this.onPointerEvent(new PointerDataPacket(new List<PointerData> {
pointerData
}));
}
this.flushMicrotasks();
this._timerProvider.update();
bool dirty = false;
if (this._devicePixelRatio != EditorGUIUtility.pixelsPerPoint) {
dirty = true;

this._lastPosition.width * EditorGUIUtility.pixelsPerPoint,
this._lastPosition.height * EditorGUIUtility.pixelsPerPoint);
if (this._onMetricsChanged != null) {
this._onMetricsChanged();
if (this.onMetricsChanged != null) {
this.onMetricsChanged();
}
}
}

var paintContext = new PaintContext {canvas = new CanvasImpl()};
layer.paint(paintContext);
}
public override void scheduleMicrotask(Action callback) {
this._microtaskQueue.scheduleMicrotask(callback);
}
public override void flushMicrotasks() {
this._microtaskQueue.flushMicrotasks();
}
public override Timer run(TimeSpan duration, Action callback) {
return this._timerProvider.run(duration, callback);
}
}
}

57
Assets/UIWidgets/foundation/node.cs


namespace UIWidgets.foundation {
public class AbstractNode {
public int depth {
get { return this._depth; }
}
public int _depth = 0;
public void redepthChild(AbstractNode child) {
if (child._depth <= this._depth) {
child._depth = this._depth + 1;
child.redepthChildren();
}
}
public virtual void redepthChildren() {
}
public object owner {
get { return this._owner; }
}
public object _owner;
public bool attached {
get { return this._owner != null; }
}
public virtual void attach(object owner) {
this._owner = owner;
}
public virtual void detach() {
this._owner = null;
}
public AbstractNode parent {
get { return this._parent; }
}
public AbstractNode _parent;
public virtual void adoptChild(AbstractNode child) {
child._parent = this;
if (this.attached) {
child.attach(this._owner);
}
this.redepthChild(child);
}
public virtual void dropChild(AbstractNode child) {
child._parent = null;
if (this.attached) {
child.detach();
}
}
}
}

249
Assets/UIWidgets/gestures/arena.cs


using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIWidgets.foundation;
using UIWidgets.ui;
using UnityEngine;
public enum GestureDisposition {
accepted,
rejected,
}
public interface GestureArenaMember {
void acceptGesture(int pointer);
void rejectGesture(int pointer);
}
public class GestureArenaEntry {
public GestureArenaEntry(
GestureArenaManager arena = null,
int pointer = 0,
GestureArenaMember member = null) {
this._arena = arena;
this._pointer = pointer;
this._member = member;
}
readonly GestureArenaManager _arena;
readonly int _pointer;
readonly GestureArenaMember _member;
public virtual void resolve(GestureDisposition disposition) {
this._arena._resolve(this._pointer, this._member, disposition);
}
}
class _GestureArena {
public List<GestureArenaMember> members = new List<GestureArenaMember>();
public bool isOpen = true;
public bool isHeld = false;
public bool hasPendingSweep = false;
public GestureArenaMember eagerWinner;
public void add(GestureArenaMember member) {
D.assert(this.isOpen);
this.members.Add(member);
}
public override string ToString() {
StringBuilder buffer = new StringBuilder();
if (this.members.isEmpty()) {
buffer.Append("<empty>");
} else {
buffer.Append(string.Join(", ", this.members.Select(
member => member == this.eagerWinner
? string.Format("{0} (eager winner)", member)
: member.ToString()).ToArray()));
}
if (this.isOpen) {
buffer.Append(" [open]");
}
if (this.isHeld) {
buffer.Append(" [held]");
}
if (this.hasPendingSweep) {
buffer.Append(" [hasPendingSweep]");
}
return buffer.ToString();
}
}
public class GestureArenaManager {
readonly Dictionary<int, _GestureArena> _arenas = new Dictionary<int, _GestureArena>();
readonly Window _window;
public GestureArenaManager(Window window) {
this._window = window;
}
public GestureArenaEntry add(int pointer, GestureArenaMember member) {
_GestureArena state = this._arenas.putIfAbsent(pointer, () => {
D.assert(this._debugLogDiagnostic(pointer, "★ Opening new gesture arena."));
return state = new _GestureArena();
});
state.add(member);
D.assert(this._debugLogDiagnostic(pointer, string.Format("Adding: {0}", member)));
return new GestureArenaEntry(this, pointer, member);
}
public void close(int pointer) {
_GestureArena state;
if (!this._arenas.TryGetValue(pointer, out state)) {
return;
}
state.isOpen = false;
D.assert(this._debugLogDiagnostic(pointer, "Closing", state));
this._tryToResolveArena(pointer, state);
}
public void sweep(int pointer) {
_GestureArena state;
if (!this._arenas.TryGetValue(pointer, out state)) {
return;
}
D.assert(!state.isOpen);
if (state.isHeld) {
state.hasPendingSweep = true;
D.assert(this._debugLogDiagnostic(pointer, "Delaying sweep", state));
return;
}
D.assert(this._debugLogDiagnostic(pointer, "Sweeping", state));
this._arenas.Remove(pointer);
if (state.members.isNotEmpty()) {
D.assert(this._debugLogDiagnostic(
pointer, string.Format("Winner: {0}", state.members.First())));
state.members.First().acceptGesture(pointer);
for (int i = 1; i < state.members.Count; i++) {
state.members[i].rejectGesture(pointer);
}
}
}
public void hold(int pointer) {
_GestureArena state;
if (!this._arenas.TryGetValue(pointer, out state)) {
return;
}
state.isHeld = true;
D.assert(this._debugLogDiagnostic(pointer, "Holding", state));
}
public void release(int pointer) {
_GestureArena state;
if (!this._arenas.TryGetValue(pointer, out state)) {
return;
}
state.isHeld = false;
D.assert(this._debugLogDiagnostic(pointer, "Releasing", state));
if (state.hasPendingSweep) {
this.sweep(pointer);
}
}
internal void _resolve(int pointer, GestureArenaMember member, GestureDisposition disposition) {
_GestureArena state;
if (!this._arenas.TryGetValue(pointer, out state)) {
return;
}
D.assert(this._debugLogDiagnostic(pointer,
string.Format("{0}: {1}",
disposition == GestureDisposition.accepted ? "Accepting" : "Rejecting",
member)));
D.assert(state.members.Contains(member));
if (disposition == GestureDisposition.rejected) {
state.members.Remove(member);
member.rejectGesture(pointer);
if (!state.isOpen) {
this._tryToResolveArena(pointer, state);
}
} else {
if (state.isOpen) {
state.eagerWinner = state.eagerWinner ?? member;
} else {
D.assert(this._debugLogDiagnostic(pointer,
string.Format("Self-declared winner: {0}", member)));
this._resolveInFavorOf(pointer, state, member);
}
}
}
void _tryToResolveArena(int pointer, _GestureArena state) {
D.assert(this._arenas[pointer] == state);
D.assert(!state.isOpen);
if (state.members.Count == 1) {
this._window.scheduleMicrotask(() => this._resolveByDefault(pointer, state));
} else if (state.members.isEmpty()) {
this._arenas.Remove(pointer);
D.assert(this._debugLogDiagnostic(pointer, "Arena empty."));
} else if (state.eagerWinner != null) {
D.assert(this._debugLogDiagnostic(pointer,
string.Format("Eager winner: {0}", state.eagerWinner)));
this._resolveInFavorOf(pointer, state, state.eagerWinner);
}
}
void _resolveByDefault(int pointer, _GestureArena state) {
if (!this._arenas.ContainsKey(pointer)) {
return;
}
D.assert(this._arenas[pointer] == state);
D.assert(!state.isOpen);
List<GestureArenaMember> members = state.members;
D.assert(members.Count == 1);
this._arenas.Remove(pointer);
D.assert(this._debugLogDiagnostic(pointer,
string.Format("Default winner: {0}", state.members.First())));
state.members.First().acceptGesture(pointer);
}
void _resolveInFavorOf(int pointer, _GestureArena state, GestureArenaMember member) {
D.assert(state == this._arenas[pointer]);
D.assert(state != null);
D.assert(state.eagerWinner == null || state.eagerWinner == member);
D.assert(!state.isOpen);
this._arenas.Remove(pointer);
foreach (GestureArenaMember rejectedMember in state.members) {
if (rejectedMember != member) {
rejectedMember.rejectGesture(pointer);
}
}
member.acceptGesture(pointer);
}
bool _debugLogDiagnostic(int pointer, string message, _GestureArena state = null) {
D.assert(() => {
if (D.debugPrintGestureArenaDiagnostics) {
int? count = state != null ? state.members.Count : (int?) null;
string s = count != 1 ? "s" : "";
Debug.LogFormat("Gesture arena {0} ❙ {1}{2}",
pointer.ToString().PadRight(4),
message,
count != null ? string.Format(" with {0} member{1}.", count, s) : "");
}
return true;
});
return true;
}
}
}

56
Assets/UIWidgets/rendering/binding.cs


using System;
using UIWidgets.foundation;
using UIWidgets.gestures;
public class RendererBinding {
public RendererBinding(Window window, SchedulerBinding schedulerBinding) {
this._window = window;
this._schedulerBinding = schedulerBinding;
public class RendererBinding : GestureBinding {
public RendererBinding(Window window) : base(window) {
onNeedVisualUpdate: this._schedulerBinding.ensureVisualUpdate
onNeedVisualUpdate: this.ensureVisualUpdate
window._onMetricsChanged = this.handleMetricsChanged;
window.onMetricsChanged += this.handleMetricsChanged;
this._schedulerBinding.addPersistentFrameCallback(this._handlePersistentFrameCallback);
D.assert(this.renderView != null);
this.addPersistentFrameCallback(this._handlePersistentFrameCallback);
public readonly Window _window;
public readonly SchedulerBinding _schedulerBinding;
D.assert(this.renderView == null);
this.renderView = new RenderView(configuration: this.createViewConfiguration());
this.renderView.scheduleInitialFrame();
}

}
public PipelineOwner _pipelineOwner;
readonly PipelineOwner _pipelineOwner;
public RenderView renderView {
get { return (RenderView) this._pipelineOwner.rootNode; }

public void handleMetricsChanged() {
protected virtual void handleMetricsChanged() {
this._schedulerBinding.scheduleForcedFrame();
this.scheduleForcedFrame();
public ViewConfiguration createViewConfiguration() {
var devicePixelRatio = this._window.devicePixelRatio;
protected virtual ViewConfiguration createViewConfiguration() {
var devicePixelRatio = this.window.devicePixelRatio;
size: this._window.physicalSize / devicePixelRatio,
size: this.window.physicalSize / devicePixelRatio,
public void _handlePersistentFrameCallback(TimeSpan timeStamp) {
void _handlePersistentFrameCallback(TimeSpan timeStamp) {
public void drawFrame() {
protected virtual void drawFrame() {
this.pipelineOwner.flushLayout();
this.pipelineOwner.flushCompositingBits();
this.pipelineOwner.flushPaint();

public void render(Scene scene) {
this._window.render(scene);
public override void hitTest(HitTestResult result, Offset position) {
D.assert(this.renderView != null);
this.renderView.hitTest(result, position: position);
base.hitTest(result, position);
this._window = window;
this._schedulerBinding = new SchedulerBinding(window);
this._rendererBinding = new RendererBinding(window, this._schedulerBinding);
this.window = window;
this.rendererBinding = new RendererBinding(window);
public readonly Window _window;
public readonly RendererBinding _rendererBinding;
public readonly SchedulerBinding _schedulerBinding;
public readonly Window window;
public readonly RendererBinding rendererBinding;
this._rendererBinding.renderView.child = root;
this.rendererBinding.renderView.child = root;
}
}
}

73
Assets/UIWidgets/rendering/box.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.ui;
using UnityEngine;

}
}
public class BoxHitTestEntry : HitTestEntry {
public BoxHitTestEntry(RenderBox target, Offset localPosition)
: base(target) {
D.assert(localPosition != null);
this.localPosition = localPosition;
}
public new RenderBox target {
get { return (RenderBox) base.target; }
}
public readonly Offset localPosition;
public override string ToString() {
return string.Format("{0}@{1}",
Diagnostics.describeIdentity(this.target), this.localPosition);
}
}
public class BoxParentData : ParentData {
public Offset offset = Offset.zero;
}

public override void performLayout() {
}
public virtual bool hitTest(HitTestResult result, Offset position) {
D.assert(() => {
if (!this.hasSize) {
throw new Exception("has no size during hitTest");
}
return true;
});
if (this._size.contains(position)) {
if (this.hitTestChildren(result, position: position) || this.hitTestSelf(position)) {
result.add(new BoxHitTestEntry(this, position));
return true;
}
}
return false;
}
protected virtual bool hitTestSelf(Offset position) {
return false;
}
protected bool hitTestChildren(HitTestResult result, Offset position = null) {
return false;
}
public override void applyPaintTransform(RenderObject child, ref Matrix4x4 transform) {
var childParentData = (BoxParentData) child.parentData;
var offset = childParentData.offset;

public override Rect paintBounds {
get { return Offset.zero & this.size; }
}
int _debugActivePointers = 0;
protected bool debugHandleEvent(PointerEvent evt, HitTestEntry entry) {
D.assert(() =>{
if (D.debugPaintPointersEnabled) {
if (evt is PointerDownEvent) {
this._debugActivePointers += 1;
} else if (evt is PointerUpEvent || evt is PointerCancelEvent) {
this._debugActivePointers -= 1;
}
this.markNeedsPaint();
}
return true;
});
return true;
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<Size>("size", this._size, missingIfNull: true));
}
}
public abstract class

candidate += childParentData.offset.dy;
if (result != null) {
result = Math.Min(result.Value, candidate.Value);
}
else {
} else {
result = candidate;
}
}

40
Assets/UIWidgets/rendering/object.cs


using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UIWidgets.gestures;
using UnityEditor.Rendering;
using UnityEngine.XR.WSA.Persistence;
using Canvas = UIWidgets.ui.Canvas;
using Rect = UIWidgets.ui.Rect;

}
}
public AbstractNode rootNode {
public AbstractNodeMixinDiagnosticableTree rootNode {
get { return this._rootNode; }
set {
if (this._rootNode == value) {

}
}
public AbstractNode _rootNode;
public AbstractNodeMixinDiagnosticableTree _rootNode;
public List<RenderObject> _nodesNeedingLayout = new List<RenderObject>();

ChildType nextSibling { get; set; }
}
public abstract class RenderObject : AbstractNode {
public abstract class RenderObject : AbstractNodeMixinDiagnosticableTree, HitTestTarget {
protected RenderObject() {
this._needsCompositing = this.isRepaintBoundary || this.alwaysNeedsCompositing;
}

}
}
public override void adoptChild(AbstractNode childNode) {
protected override void adoptChild(AbstractNodeMixinDiagnosticableTree childNode) {
var child = (RenderObject) childNode;
this.setupParentData(child);
base.adoptChild(child);

public override void dropChild(AbstractNode childNode) {
protected override void dropChild(AbstractNodeMixinDiagnosticableTree childNode) {
var child = (RenderObject) childNode;
child._cleanRelayoutBoundary();
child.parentData.detach();

public virtual void visitChildren(RenderObjectVisitor visitor) {
}
public object debugCreator;
public bool debugCanParentUseSize {
get { return this._debugCanParentUseSize; }
}
bool _debugCanParentUseSize;
public new PipelineOwner owner {
get { return (PipelineOwner) base.owner; }
}

}
public void _skippedPaintingOnLayer() {
AbstractNode ancestor = this.parent;
var ancestor = this.parent;
while (ancestor is RenderObject) {
var node = (RenderObject) ancestor;
if (node.isRepaintBoundary) {

public Matrix4x4 getTransformTo(RenderObject ancestor) {
if (ancestor == null) {
AbstractNode rootNode = this.owner.rootNode;
var rootNode = this.owner.rootNode;
if (rootNode is RenderObject) {
ancestor = (RenderObject) rootNode;
}

}
return transform;
}
public virtual void handleEvent(PointerEvent evt, HitTestEntry entry) {
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties.add(new DiagnosticsProperty<object>(
"creator", this.debugCreator, defaultValue: Diagnostics.kNullDefaultValue,
level: DiagnosticLevel.debug));
properties.add(new DiagnosticsProperty<ParentData>("parentData", this.parentData,
tooltip: this._debugCanParentUseSize ? "can use size" : null, missingIfNull: true));
properties.add(new DiagnosticsProperty<Constraints>("constraints", this.constraints, missingIfNull: true));
properties.add(new DiagnosticsProperty<OffsetLayer>("layer", this._layer,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
}

124
Assets/UIWidgets/rendering/proxy_box.cs


using UIWidgets.painting;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.ui;
using UnityEngine;

}
}
public enum HitTestBehavior {
deferToChild,
opaque,
translucent,
}
public abstract class RenderProxyBoxWithHitTestBehavior : RenderProxyBox {
protected RenderProxyBoxWithHitTestBehavior(
HitTestBehavior behavior = HitTestBehavior.deferToChild,
RenderBox child = null
) : base(child) {
this.behavior = behavior;
}
public HitTestBehavior behavior;
public override bool hitTest(HitTestResult result, Offset position = null) {
bool hitTarget = false;
if (this.size.contains(position)) {
hitTarget = this.hitTestChildren(result, position: position) || this.hitTestSelf(position);
if (hitTarget || this.behavior == HitTestBehavior.translucent) {
result.add(new BoxHitTestEntry(this, position));
}
}
return hitTarget;
}
protected override bool hitTestSelf(Offset position) {
return this.behavior == HitTestBehavior.opaque;
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<HitTestBehavior>(
"behavior", this.behavior, defaultValue: Diagnostics.kNullDefaultValue));
}
}
public class RenderConstrainedBox : RenderProxyBox {
public RenderConstrainedBox(
RenderBox child = null,

background,
foreground,
}
public class RenderDecoratedBox : RenderProxyBox {
public RenderDecoratedBox(
Decoration decoration,

if (this.position == DecorationPosition.foreground) {
this._painter.paint(context.canvas, offset, filledConfiguration);
}
}
}
public delegate void PointerDownEventListener(PointerDownEvent evt);
public delegate void PointerMoveEventListener(PointerMoveEvent evt);
public delegate void PointerUpEventListener(PointerUpEvent evt);
public delegate void PointerCancelEventListener(PointerCancelEvent evt);
public class RenderPointerListener : RenderProxyBoxWithHitTestBehavior {
public RenderPointerListener(
PointerDownEventListener onPointerDown = null,
PointerMoveEventListener onPointerMove = null,
PointerUpEventListener onPointerUp = null,
PointerCancelEventListener onPointerCancel = null,
HitTestBehavior behavior = HitTestBehavior.deferToChild,
RenderBox child = null
) : base(behavior: behavior, child: child) {
this.onPointerDown = onPointerDown;
this.onPointerMove = onPointerMove;
this.onPointerUp = onPointerUp;
this.onPointerCancel = onPointerCancel;
}
public PointerDownEventListener onPointerDown;
public PointerMoveEventListener onPointerMove;
public PointerUpEventListener onPointerUp;
public PointerCancelEventListener onPointerCancel;
public override void performResize() {
this.size = this.constraints.biggest;
}
public override void handleEvent(PointerEvent evt, HitTestEntry entry) {
D.assert(this.debugHandleEvent(evt, entry));
if (this.onPointerDown != null && evt is PointerDownEvent) {
this.onPointerDown((PointerDownEvent) evt);
return;
}
if (this.onPointerMove != null && evt is PointerMoveEvent) {
this.onPointerMove((PointerMoveEvent) evt);
return;
}
if (this.onPointerUp != null && evt is PointerUpEvent) {
this.onPointerUp((PointerUpEvent) evt);
return;
}
if (this.onPointerCancel != null && evt is PointerCancelEvent) {
this.onPointerCancel((PointerCancelEvent) evt);
return;
}
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
var listeners = new List<string>();
if (this.onPointerDown != null)
listeners.Add("down");
if (this.onPointerMove != null)
listeners.Add("move");
if (this.onPointerUp != null)
listeners.Add("up");
if (this.onPointerCancel != null)
listeners.Add("cancel");
if (listeners.isEmpty()) {
listeners.Add("<none>");
}
properties.add(new EnumerableProperty<string>("listeners", listeners));
}
}
}

2
Assets/UIWidgets/rendering/sliver_multi_box_adaptor.cs


public readonly Dictionary<int, RenderBox> _keepAliveBucket = new Dictionary<int, RenderBox>();
public override void adoptChild(AbstractNode childNode) {
protected override void adoptChild(AbstractNodeMixinDiagnosticableTree childNode) {
base.adoptChild(childNode);
var child = (RenderBox) childNode;
var childParentData = (SliverMultiBoxAdaptorParentData) child.parentData;

12
Assets/UIWidgets/rendering/view.cs


using System;
using UIWidgets.gestures;
using UIWidgets.ui;
using UnityEngine;
using Rect = UIWidgets.ui.Rect;

}
}
public bool hitTest(HitTestResult result, Offset position = null) {
if (this.child != null) {
this.child.hitTest(result, position: position);
}
result.add(new HitTestEntry(this));
return true;
}
public override bool isRepaintBoundary {
get { return true; }
}

var builder = new SceneBuilder();
this.layer.addToScene(builder, Offset.zero);
var scene = builder.build();
this.owner.binding.render(scene);
this.owner.binding.window.render(scene);
}
public override Rect paintBounds {

221
Assets/UIWidgets/scheduler/binding.cs


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using RSG.Promises;
using UIWidgets.foundation;
using UnityEngine;
using Debug = UnityEngine.Debug;
public class _FrameCallbackEntry {
public _FrameCallbackEntry(FrameCallback callback, bool rescheduling = false) {
class _FrameCallbackEntry {
internal _FrameCallbackEntry(FrameCallback callback, bool rescheduling = false) {
D.assert(() => {
if (rescheduling) {
D.assert(() => {
if (_FrameCallbackEntry.debugCurrentCallbackStack == null) {
throw new UIWidgetsError(
"scheduleFrameCallback called with rescheduling true, but no callback is in scope.\n" +
"The \"rescheduling\" argument should only be set to true if the " +
"callback is being reregistered from within the callback itself, " +
"and only then if the callback itself is entirely synchronous. " +
"If this is the initial registration of the callback, or if the " +
"callback is asynchronous, then do not use the \"rescheduling\" " +
"argument.");
}
return true;
});
this.debugStack = _FrameCallbackEntry.debugCurrentCallbackStack;
} else {
this.debugStack = new StackTrace(2, true);
}
return true;
});
public static StackTrace debugCurrentCallbackStack;
public StackTrace debugStack;
}
public enum SchedulerPhase {

public class SchedulerBinding {
public SchedulerBinding(Window window) {
this._window = window;
D.assert(window != null);
this.window = window;
window.onBeginFrame = this._handleBeginFrame;
window.onDrawFrame = this._handleDrawFrame;
window.onBeginFrame += this._handleBeginFrame;
window.onDrawFrame += this._handleDrawFrame;
public readonly Window _window;
public readonly Window window;
public double timeDilation {
get { return this._timeDilation; }

}
}
public double _timeDilation = 1.0;
double _timeDilation = 1.0;
public int _nextFrameCallbackId = 0;
public Dictionary<int, _FrameCallbackEntry> _transientCallbacks = new Dictionary<int, _FrameCallbackEntry>();
public HashSet<int> _removedIds = new HashSet<int>();
int _nextFrameCallbackId = 0;
Dictionary<int, _FrameCallbackEntry> _transientCallbacks = new Dictionary<int, _FrameCallbackEntry>();
readonly HashSet<int> _removedIds = new HashSet<int>();
public int transientCallbackCount {
get { return this._transientCallbacks.Count; }

}
public void cancelFrameCallbackWithId(int id) {
D.assert(id > 0);
public readonly List<FrameCallback> _persistentCallbacks = new List<FrameCallback>();
readonly List<FrameCallback> _persistentCallbacks = new List<FrameCallback>();
public readonly List<FrameCallback> _postFrameCallbacks = new List<FrameCallback>();
readonly List<FrameCallback> _postFrameCallbacks = new List<FrameCallback>();
public void addPostFrameCallback(FrameCallback callback) {
this._postFrameCallbacks.Add(callback);

get { return this._hasScheduledFrame; }
}
public bool _hasScheduledFrame = false;
bool _hasScheduledFrame = false;
public SchedulerPhase _schedulerPhase = SchedulerPhase.idle;
SchedulerPhase _schedulerPhase = SchedulerPhase.idle;
public void ensureVisualUpdate() {
switch (this.schedulerPhase) {

return;
}
this._window.scheduleFrame();
D.assert(() => {
if (D.debugPrintScheduleFrameStacks) {
Debug.LogFormat("scheduleFrame() called. Current phase is {0}.", this.schedulerPhase);
}
return true;
});
this.window.scheduleFrame();
this.scheduleFrame();
if (this._hasScheduledFrame) {
return;
}
D.assert(() => {
if (D.debugPrintScheduleFrameStacks) {
Debug.LogFormat("scheduleForcedFrame() called. Current phase is {0}.", this.schedulerPhase);
}
return true;
});
this.window.scheduleFrame();
this._hasScheduledFrame = true;
public TimeSpan? _firstRawTimeStampInEpoch;
public TimeSpan _epochStart = TimeSpan.Zero;
public TimeSpan _lastRawTimeStamp = TimeSpan.Zero;
TimeSpan? _firstRawTimeStampInEpoch;
TimeSpan _epochStart = TimeSpan.Zero;
TimeSpan _lastRawTimeStamp = TimeSpan.Zero;
public void resetEpoch() {
this._epochStart = this._adjustForEpoch(this._lastRawTimeStamp);

public TimeSpan _adjustForEpoch(TimeSpan rawTimeStamp) {
TimeSpan _adjustForEpoch(TimeSpan rawTimeStamp) {
var rawDurationSinceEpoch = this._firstRawTimeStampInEpoch == null
? TimeSpan.Zero
: rawTimeStamp - this._firstRawTimeStampInEpoch.Value;

get { return this._currentFrameTimeStamp.Value; }
}
public TimeSpan? _currentFrameTimeStamp;
TimeSpan? _currentFrameTimeStamp;
int _profileFrameNumber = 0;
string _debugBanner;
public void _handleBeginFrame(TimeSpan rawTimeStamp) {
void _handleBeginFrame(TimeSpan rawTimeStamp) {
public void _handleDrawFrame() {
void _handleDrawFrame() {
if (this._firstRawTimeStampInEpoch == null) {
this._firstRawTimeStampInEpoch = rawTimeStamp;
}
this._firstRawTimeStampInEpoch = this._firstRawTimeStampInEpoch ?? rawTimeStamp;
this._currentFrameTimeStamp = this._adjustForEpoch(rawTimeStamp ?? this._lastRawTimeStamp);
if (rawTimeStamp != null) {

D.assert(() => {
this._profileFrameNumber += 1;
return true;
});
D.assert(() => {
if (D.debugPrintBeginFrameBanner || D.debugPrintEndFrameBanner) {
var frameTimeStampDescription = new StringBuilder();
if (rawTimeStamp != null) {
SchedulerBinding._debugDescribeTimeStamp(
this._currentFrameTimeStamp.Value, frameTimeStampDescription);
} else {
frameTimeStampDescription.Append("(warm-up frame)");
}
this._debugBanner = string.Format("▄▄▄▄▄▄▄▄ Frame {0} {1} ▄▄▄▄▄▄▄▄",
this._profileFrameNumber.ToString().PadRight(7),
frameTimeStampDescription.ToString().PadLeft(18));
if (D.debugPrintBeginFrameBanner) {
Debug.Log(this._debugBanner);
}
}
return true;
});
D.assert(this._schedulerPhase == SchedulerPhase.idle);
this._hasScheduledFrame = false;
try {

foreach (var entry in callbacks) {
if (!this._removedIds.Contains(entry.Key)) {
this._invokeFrameCallback(entry.Value.callback, this._currentFrameTimeStamp.Value);
this._invokeFrameCallback(
entry.Value.callback, this._currentFrameTimeStamp.Value, entry.Value.debugStack);
}
}

}
}
public void _invokeFrameCallback(FrameCallback callback, TimeSpan timeStamp) {
try {
callback(timeStamp);
}
catch (Exception ex) {
Debug.LogError("error in frame callback: " + ex);
}
}
D.assert(this._schedulerPhase == SchedulerPhase.midFrameMicrotasks);
try {
this._schedulerPhase = SchedulerPhase.persistentCallbacks;
foreach (FrameCallback callback in this._persistentCallbacks) {

}
finally {
this._schedulerPhase = SchedulerPhase.idle;
D.assert(() => {
if (D.debugPrintEndFrameBanner) {
Debug.Log(new string('▀', this._debugBanner.Length));
}
this._debugBanner = null;
return true;
});
}
static void _debugDescribeTimeStamp(TimeSpan timeStamp, StringBuilder buffer) {
if (timeStamp.TotalDays > 0) {
buffer.AppendFormat("{0}d ", timeStamp.Days);
}
if (timeStamp.TotalHours > 0) {
buffer.AppendFormat("{0}h ", timeStamp.Hours);
}
if (timeStamp.TotalMinutes > 0) {
buffer.AppendFormat("{0}m ", timeStamp.Minutes);
}
if (timeStamp.TotalSeconds > 0) {
buffer.AppendFormat("{0}s ", timeStamp.Seconds);
}
buffer.AppendFormat("{0}", timeStamp.Milliseconds);
int microseconds = (int) (timeStamp.Ticks % 10000 / 10);
if (microseconds > 0) {
buffer.AppendFormat(".{0}", microseconds.ToString().PadLeft(3, '0'));
}
buffer.Append("ms");
}
void _invokeFrameCallback(FrameCallback callback, TimeSpan timeStamp, StackTrace callbackStack = null) {
D.assert(callback != null);
D.assert(_FrameCallbackEntry.debugCurrentCallbackStack == null);
D.assert(() => {
_FrameCallbackEntry.debugCurrentCallbackStack = callbackStack;
return true;
});
try {
callback(timeStamp);
}
catch (Exception ex) {
UIWidgetsError.reportError(new UIWidgetsErrorDetails(
exception: ex,
library: "scheduler library",
context: "during a scheduler callback",
informationCollector: callbackStack == null
? (InformationCollector) null
: information => {
information.AppendLine(
"\nThis exception was thrown in the context of a scheduler callback. " +
"When the scheduler callback was _registered_ (as opposed to when the " +
"exception was thrown), this was the stack:"
);
UIWidgetsError.defaultStackFilter(callbackStack.ToString().TrimEnd().Split('\n'))
.Each((line) => information.AppendLine(line));
}
));
}
D.assert(() => {
_FrameCallbackEntry.debugCurrentCallbackStack = null;
return true;
});
}
}
}

6
Assets/UIWidgets/ui/geometry.cs


}
public static bool operator ==(OffsetBase a, OffsetBase b) {
return a.Equals(b);
return object.Equals(a, b);
}
public static bool operator !=(OffsetBase a, OffsetBase b) {

public double longestSide {
get { return Math.Max(Math.Abs(this.width), Math.Abs(this.height)); }
}
public bool contains(Offset offset) {
return offset.dx >= 0.0 && offset.dx < this.width && offset.dy >= 0.0 && offset.dy < this.height;
}
public bool Equals(Size other) {

4
Assets/UIWidgets/ui/painting/canvas.cs


void clipRRect(RRect rrect);
void drawMesh(Mesh mesh, Material material);
void drawMesh(IMesh mesh, Material material);
}
public class RecorderCanvas : Canvas {

});
}
public void drawMesh(Mesh mesh, Material material)
public void drawMesh(IMesh mesh, Material material)
{
this._recorder.addDrawCmd(new DrawMesh() {
mesh = mesh,

5
Assets/UIWidgets/ui/painting/canvas_impl.cs


this.pushClipRRect(rect, this._transform);
}
public void drawMesh(Mesh mesh, Material material)
public void drawMesh(IMesh mesh, Material material)
Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
mesh.syncTextureUV();
Graphics.DrawMeshNow(mesh.mesh, Matrix4x4.identity);
}
private void pushClipRect(Rect clipRect, Matrix4x4 transform) {

11
Assets/UIWidgets/ui/painting/draw_cmd.cs


}
public class DrawMesh : DrawCmd {
public Mesh mesh;
public IMesh mesh;
public interface IMesh
{
void syncTextureUV();
Mesh mesh { get; }
}

4
Assets/UIWidgets/ui/painting/picture.cs


var drawClipRRect = (DrawClipRRect) drawCmd;
this.addClipRect(drawClipRRect.rrect.outerRect);
} else if (drawCmd is DrawMesh) {
var bounds = ((DrawMesh)drawCmd).mesh.bounds;
var bounds = ((DrawMesh)drawCmd).mesh.mesh.bounds;
var rect = Rect.fromLTRB(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y);
this.addPaintBounds(rect);

if (this._clipRect != null) {
throw new Exception("already a clipRec, considering using saveLayer.");
}
this._clipRect = MatrixUtils.transformRect(this._transform, rect);
}

5
Assets/UIWidgets/ui/text.cs


);
}
public TextAlign TextAlign
{
get { return textAlign ?? TextAlign.left; }
}
public readonly TextAlign? textAlign;
public readonly TextDirection? textDirection;
public readonly FontWeight? fontWeight;

29
Assets/UIWidgets/ui/txt/linebreaker.cs


private StyledRuns _runs;
public Vector2[] _characterPositions;
public float[] _characterWidth;
public Vector2d[] _characterPositions;
public double[] _characterWidth;
private float _width;
private double _width;
private Font[] _styleRunFonts;
public void setup(string text, StyledRuns runs, Font[] styleRunFonts, float width, Vector2[] characterPositions, float[] characterWidth)
public void setup(string text, StyledRuns runs, double width, Vector2d[] characterPositions, double[] characterWidth)
{
_text = text;
_runs = runs;

_styleRunFonts = styleRunFonts;
}
public List<LineInfo> getLines()

_wordStart = blockStart;
_spaceCount = 0;
float offsetX = 0.0f;
double offsetX = 0.0;
var font = _styleRunFonts[runIterator.runIndex];
var font = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize).font;
CharacterInfo charInfo;
var result = font.GetCharacterInfo(_text[charIndex], out charInfo, 0, run.style.UnityFontStyle);
var charInfo = new CharacterInfo();
if (_text[charIndex] == '\t')
{
_spaceCount++;

float tabSize = charInfo.advance * tabCount;
var newX = (float)Math.Floor(((offsetX / tabSize) + 1) * tabSize);
double tabSize = charInfo.advance * tabCount;
var newX = Math.Floor(((offsetX / tabSize) + 1) * tabSize);
if (newX > _width && _lineStart != charIndex)
{
_characterWidth[charIndex] = tabSize;

}
else if (_text[charIndex] == ' ')
{
font.GetCharacterInfo(_text[charIndex], out charInfo, style.UnityFontSize, run.style.UnityFontStyle);
_spaceCount++;
_characterPositions[charIndex].x = offsetX;
_characterWidth[charIndex] = charInfo.advance;

else
{
font.GetCharacterInfo(_text[charIndex], out charInfo, style.UnityFontSize,
run.style.UnityFontStyle);
if (_spaceCount > 0 || blockStart == charIndex)
{
_wordStart = charIndex;

{
return;
}
var offset = new Vector2(-_characterPositions[end].x, 0);
var offset = new Vector2d(-_characterPositions[end].x, 0);
_characterPositions[end].x = 0;
if (end < last)
{

226
Assets/UIWidgets/ui/txt/paragraph.cs


using System;
using System.Collections.Generic;
using System.Text;
using JetBrains.Annotations;
using UnityEngine.Assertions;
using UnityEngine.Experimental.UIElements;
public struct Vector2d
{
public double x;
public double y;
public Vector2d(double x = 0.0, double y = 0.0)
{
this.x = x;
this.y = y;
}
public static Vector2d operator +(Vector2d a, Vector2d b)
{
return new Vector2d(a.x + b.x, a.y + b.y);
}
public static Vector2d operator -(Vector2d a, Vector2d b)
{
return new Vector2d(a.x - b.x, a.y - b.y);
}
}
public class Paragraph
{
struct Range<T>: IEquatable<Range<T>>

public readonly int endIncludingNewLine;
public readonly bool hardBreak;
}
class LayoutContext
{
public int width;
public int index;
public Vector2 offset;
public TextStyle style;
public Font font;
public int wordStart;
public int lineStart;
public int prevWordEnd;
}
private static readonly Shader textShader;

private ParagraphStyle _paragraphStyle;
private List<LineRange> _lineRanges = new List<LineRange>();
private List<double> _lineWidths = new List<double>();
private Vector2[] _characterPositions;
private Vector2d[] _characterPositions;
private Font[] _styleRunFonts;
private float[] _characterWidths;
private double[] _characterWidths;
private LayoutContext context;
private bool _didExceedMaxLines;
// private double _characterWidth;

public static bool isWordSpace(char ch)
{
return ch == ' ' || ch == CHAR_NBSP;
}
// This function determines whether a character is a space that disappears at end of line.
// It is the Unicode set: [[:General_Category=Space_Separator:]-[:Line_Break=Glue:]],
// plus '\n'.
// Note: all such characters are in the BMP, so it's ok to use code units for this.
public static bool isLineEndSpace(char c) {
return c == '\n' || c == ' ' || c == 0x1680 || (0x2000 <= c && c <= 0x200A && c != 0x2007) ||
c == 0x205F || c == 0x3000;
}
public double height

public double alphabeticBaseline
{
get { return 0.0; }
get { return _alphabeticBaseline; }
get { return 0.0; }
get { return _ideographicBaseline; }
}
public bool didExceedMaxLines

var run = _runs.getRun(runIndex);
if (run.start < run.end)
{
var font = _styleRunFonts[runIndex];
var mesh = generateMesh(x, y, font, run);
canvas.drawMesh(mesh, font.material);
var fontEntry = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize);
var mesh = new TextMesh(new Vector2d(x, y), _text, _characterPositions, fontEntry, run);
canvas.drawMesh(mesh, fontEntry.font.material);
}
}

{
maxWordWidth = wordWidth;
}
});
});
if (_paragraphStyle.TextAlign == TextAlign.justify && !_lineRanges[lineNumber].hardBreak
&& lineNumber != lineLimits - 1)
{
justifyLine(lineNumber, words);
} else if (line.endExcludingWhitespace > line.start)
{
Debug.Assert(!isLineEndSpace(_text[line.endExcludingWhitespace - 1]));
var lineTotalAdvance = _characterPositions[line.endExcludingWhitespace - 1].x +
_characterWidths[line.endExcludingWhitespace - 1];
double xOffset = getLineXOffset(lineTotalAdvance);
if (xOffset > 0 || xOffset < 0)
{
offsetCharacters(new Vector2d(xOffset, 0),
_characterPositions, line.start, line.endExcludingWhitespace);
}
}
}

_text = text;
_runs = runs;
_needsLayout = true;
_styleRunFonts = null;
}
public void setParagraphStyle(ParagraphStyle style)

_styleRunFonts = null;
public static void offsetCharacters(Vector2 offset, Vector2[] characterPos, int start, int end)
public static void offsetCharacters(Vector2d offset, Vector2d[] characterPos, int start, int end)
{
if (characterPos != null)
{

private void setup()
{
_characterPositions = new Vector2[_text.Length];
if (_characterPositions == null || _characterPositions.Length < _text.Length)
{
_characterPositions = new Vector2d[_text.Length];
}
_characterWidths = new float[_text.Length];
if (_styleRunFonts == null)
_characterWidths = new double[_text.Length];
for (int i = 0; i < _runs.size; ++i)
_styleRunFonts = new Font[_runs.size];
for (int i = 0; i < _styleRunFonts.Length; ++i)
var run = _runs.getRun(i);
if (run.start < run.end)
var run = _runs.getRun(i);
if (run.start < run.end)
{
_styleRunFonts[i] = Font.CreateDynamicFontFromOSFont(run.style.safeFontFamily,
run.style.UnityFontSize);
_styleRunFonts[i].material.shader = textShader;
_styleRunFonts[i].RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start), 0,
run.style.UnityFontStyle);
}
}
var font = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize).font;
font.RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start), 0,
run.style.UnityFontStyle);
}
}
}

var run = _runs.getRun(runIndex);
if (run.start < run.end && run.start < line.end && run.end > line.start)
{
var font = _styleRunFonts[runIndex];
var font = FontManager.instance.getOrCreate(run.style.safeFontFamily, run.style.UnityFontSize).font;
var ascent = font.ascent * (run.style.height??1.0);
var descent = (font.lineHeight - font.ascent) * (run.style.height??1.0);
if (ascent > maxAscent)

_ideographicBaseline = maxAscent; // todo Properly implement ideographic_baseline
}
lastDescent = maxDescent;
yOffset += maxAscent + lastDescent;
yOffset = Utils.PixelCorrectRound(yOffset + maxAscent + lastDescent);
_characterPositions[charIndex].y = (float)yOffset;
_characterPositions[charIndex].y = yOffset;
}
_lineHeights.Add((_lineHeights.Count == 0 ? 0 : _lineHeights[_lineHeights.Count - 1]) +

}
newLinePositions.Add(_text.Length);
int runIndex = 0;
StyledRuns.Run lastRun = null;
lineBreaker.setup(_text, _runs, _styleRunFonts, (float)_width, _characterPositions, _characterWidths);
lineBreaker.setup(_text, _runs, _width, _characterPositions, _characterWidths);
for (var newlineIndex = 0; newlineIndex < newLinePositions.Count; ++newlineIndex)
{

var line = lines[i];
var end = i + 1 < lines.Count ? lines[i + 1].start : blockEnd;
var nonWhiteSpace = end - 1;
while (nonWhiteSpace >= line.start && _text[nonWhiteSpace] == ' ' || _text[nonWhiteSpace] == '\t')
var nonSpaceEnd = end;
while (nonSpaceEnd > line.start && isLineEndSpace(_text[nonSpaceEnd - 1]))
nonWhiteSpace--;
nonSpaceEnd--;
_lineRanges.Add(new LineRange(line.start, end, nonWhiteSpace, end + 1, end == blockEnd));
_lineRanges.Add(new LineRange(line.start, end, nonSpaceEnd, end + 1, end == blockEnd));
_lineWidths.Add(line.width);
}
}

var vertices = new Vector3[_text.Length * 4];
var triangles = new int[_text.Length * 6];
var uv = new Vector2[_text.Length * 4];
Vector3 offset = new Vector3((float)x, (float)y, 0);
font.RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start), run.style.UnityFontSize, run.style.UnityFontStyle);
Vector3 offset = new Vector3((float)Utils.PixelCorrectRound(x), (float)Utils.PixelCorrectRound(y), 0);
font.RequestCharactersInTexture(_text.Substring(run.start, run.end - run.start),
run.style.UnityFontSize, run.style.UnityFontStyle);
CharacterInfo charInfo;
var result = font.GetCharacterInfo(_text[charIndex], out charInfo, run.style.UnityFontSize, run.style.UnityFontStyle);
var position = _characterPositions[charIndex];
vertices[4 * charIndex + 0] = offset + new Vector3(position.x + charInfo.minX, position.y - charInfo.maxY, 0);
vertices[4 * charIndex + 1] = offset + new Vector3(position.x + charInfo.maxX, position.y - charInfo.maxY, 0);
vertices[4 * charIndex + 2] = offset + new Vector3(position.x + charInfo.maxX, position.y - charInfo.minY, 0);
vertices[4 * charIndex + 3] = offset + new Vector3(position.x + charInfo.minX, position.y - charInfo.minY, 0);
if (_text[charIndex] != ' ' && _text[charIndex] != '\t' && _text[charIndex] != '\n')
CharacterInfo charInfo = new CharacterInfo();
if (_text[charIndex] != '\n' && _text[charIndex] != '\t')
uv[4 * charIndex + 0] = charInfo.uvTopLeft;
uv[4 * charIndex + 1] = charInfo.uvTopRight;
uv[4 * charIndex + 2] = charInfo.uvBottomRight;
uv[4 * charIndex + 3] = charInfo.uvBottomLeft;
font.GetCharacterInfo(_text[charIndex], out charInfo, run.style.UnityFontSize, run.style.UnityFontStyle);
var position = _characterPositions[charIndex];
vertices[4 * charIndex + 0] = offset + new Vector3((float)(position.x + charInfo.minX),
(float)(position.y - charInfo.maxY), 0);
vertices[4 * charIndex + 1] = offset + new Vector3((float)(position.x + charInfo.maxX),
(float)(position.y - charInfo.maxY), 0);
vertices[4 * charIndex + 2] = offset + new Vector3(
(float)(position.x + charInfo.maxX), (float)(position.y - charInfo.minY), 0);
vertices[4 * charIndex + 3] = offset + new Vector3(
(float)(position.x + charInfo.minX), (float)(position.y - charInfo.minY), 0);
vertices[4 * charIndex + 0] = vertices[4 * charIndex + 1] =
vertices[4 * charIndex + 2] = vertices[4 * charIndex + 3] = offset;
}
if (isWordSpace(_text[charIndex]) || isLineEndSpace(_text[charIndex]) || _text[charIndex] == '\t')
{
} else
{
uv[4 * charIndex + 0] = charInfo.uvTopLeft;
uv[4 * charIndex + 1] = charInfo.uvTopRight;
uv[4 * charIndex + 2] = charInfo.uvBottomRight;
uv[4 * charIndex + 3] = charInfo.uvBottomLeft;
}
triangles[6 * charIndex + 0] = 4 * charIndex + 0;

triangles[6 * charIndex + 5] = 4 * charIndex + 3;
}
// for (var i = 0; i < vertices.Length; i++)
// {
// vertices[i].x = (float)Math.Round(vertices[i].x);
// vertices[i].y = (float)Math.Round(vertices[i].y);
// }
var mesh = new Mesh()
{
vertices = vertices,

return mesh;
}
private double getLineXOffset(double lineTotalAdvance) {
if (double.IsInfinity(_width))
{
return 0;
}
var align = _paragraphStyle.TextAlign;
if (align == TextAlign.right) {
return _width - lineTotalAdvance;
} else if (align == TextAlign.center) {
return Utils.PixelCorrectRound((_width - lineTotalAdvance) / 2);
} else {
return 0;
}
}
private void justifyLine(int lineNumber, List<Range<int>> words)
{
if (words.Count <= 1)
{
return;
}
var line = _lineRanges[lineNumber];
Debug.Assert(!isLineEndSpace(_text[line.endExcludingWhitespace - 1]));
var lineTotalAdvance = _characterPositions[line.endExcludingWhitespace - 1].x +
_characterWidths[line.endExcludingWhitespace - 1];
double gapWidth = (_width - lineTotalAdvance) / (words.Count - 1);
double justifyOffset = 0.0;
foreach (var word in words)
{
offsetCharacters(new Vector2d(justifyOffset),
_characterPositions, word.start, word.end);
justifyOffset += gapWidth;
justifyOffset = Utils.PixelCorrectRound(justifyOffset);
}
}
private List<Range<int>> findWords(int start, int end)
{
var inWord = false;

34
Assets/UIWidgets/ui/window.cs


using System;
using UIWidgets.rendering;
using UIWidgets.widgets;
using UIWidgets.async;
public delegate void PointerDataPacketCallback(PointerDataPacket packet);
public abstract class Window {
public double devicePixelRatio {

public double _devicePixelRatio = 1.0;
protected double _devicePixelRatio = 1.0;
public Size _physicalSize = Size.zero;
protected Size _physicalSize = Size.zero;
public VoidCallback onMetricsChanged {
get { return this._onMetricsChanged; }

public VoidCallback _onMetricsChanged;
VoidCallback _onMetricsChanged;
public FrameCallback onBeginFrame {
get { return this._onBeginFrame; }

public FrameCallback _onBeginFrame;
FrameCallback _onBeginFrame;
public VoidCallback onDrawFrame {
get { return this._onDrawFrame; }

public VoidCallback _onDrawFrame;
VoidCallback _onDrawFrame;
public PointerDataPacketCallback onPointerEvent {
get { return this._onPointerEvent; }
set { this._onPointerEvent = value; }
}
PointerDataPacketCallback _onPointerEvent;
}
public abstract void scheduleMicrotask(Action callback);
public abstract void flushMicrotasks();
public abstract Timer run(TimeSpan duration, Action callback);
public Timer run(Action callback) {
return this.run(TimeSpan.Zero, callback);
}
}
}

5
Packages/manifest.json


{
"dependencies": {
"com.unity.ads": "2.0.8",
"com.unity.analytics": "2.0.16",
"com.unity.package-manager-ui": "1.9.11",
"com.unity.analytics": "3.0.9",
"com.unity.collab-proxy": "1.2.6",
"com.unity.package-manager-ui": "2.0.0-preview.6",
"com.unity.purchasing": "2.0.3",
"com.unity.textmeshpro": "1.2.4",
"com.unity.modules.ai": "1.0.0",

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2018.2.4f1
m_EditorVersion: 2018.3.0a9

102
Assets/UIWidgets/Tests/Gestures.cs


using System;
using System.Linq;
using UIWidgets.editor;
using UIWidgets.gestures;
using UIWidgets.painting;
using UIWidgets.rendering;
using UIWidgets.ui;
using UnityEditor;
using UnityEngine;
using Color = UIWidgets.ui.Color;
namespace UIWidgets.Tests {
public class Gestures : EditorWindow {
private readonly Func<RenderBox>[] _options;
private readonly string[] _optionStrings;
private int _selected;
Gestures() {
this._options = new Func<RenderBox>[] {
this.tap,
};
this._optionStrings = this._options.Select(x => x.Method.Name).ToArray();
this._selected = 0;
this.titleContent = new GUIContent("Gestures");
}
private WindowAdapter windowAdapter;
private RendererBindings rendererBindings;
[NonSerialized] private bool hasInvoked = false;
void OnGUI() {
var selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings);
if (selected != this._selected || !this.hasInvoked) {
this._selected = selected;
this.hasInvoked = true;
var renderBox = this._options[this._selected]();
this.rendererBindings.setRoot(renderBox);
}
if (this.windowAdapter != null) {
this.windowAdapter.OnGUI();
}
}
void Update() {
if (this.windowAdapter != null) {
this.windowAdapter.Update();
}
}
private void OnEnable() {
this.windowAdapter = new WindowAdapter(this);
this.rendererBindings = new RendererBindings(this.windowAdapter);
this._tapRecognizer = new TapGestureRecognizer(this.rendererBindings.rendererBinding);
this._tapRecognizer.onTap = () => { Debug.Log("tap"); };
this._panRecognizer = new PanGestureRecognizer(this.rendererBindings.rendererBinding);
this._panRecognizer.onUpdate = (details) => { Debug.Log("onUpdate " + details); };
this._doubleTapGesture = new DoubleTapGestureRecognizer(this.rendererBindings.rendererBinding);
this._doubleTapGesture.onDoubleTap = () => { Debug.Log("onDoubleTap"); };
}
void OnDestroy() {
this.windowAdapter = null;
this.rendererBindings = null;
}
TapGestureRecognizer _tapRecognizer;
PanGestureRecognizer _panRecognizer;
DoubleTapGestureRecognizer _doubleTapGesture;
void _handlePointerDown(PointerDownEvent evt) {
this._tapRecognizer.addPointer(evt);
this._panRecognizer.addPointer(evt);
this._doubleTapGesture.addPointer(evt);
}
RenderBox tap() {
return new RenderPointerListener(
onPointerDown: this._handlePointerDown,
behavior: HitTestBehavior.opaque,
child: new RenderConstrainedBox(
additionalConstraints: BoxConstraints.tight(Size.square(100)),
child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFF00FF00)
)
))
);
}
}
}

3
Assets/UIWidgets/Tests/Gestures.cs.meta


fileFormatVersion: 2
guid: b6e93a3e08aa4ed49ebe367645f04fd9
timeCreated: 1536304600

8
Assets/UIWidgets/async.meta


fileFormatVersion: 2
guid: d164f4ad25c6f4b51b5f3e6a945a7296
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

144
Assets/UIWidgets/foundation/assertions.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Debug = UnityEngine.Debug;
namespace UIWidgets.foundation {
public delegate void UIWidgetsExceptionHandler(UIWidgetsErrorDetails details);
public delegate void InformationCollector(StringBuilder information);
public class UIWidgetsErrorDetails {
public UIWidgetsErrorDetails(
Exception exception = null,
string library = "UIWidgets framework",
string context = null,
EnumerableFilter<String> stackFilter = null,
InformationCollector informationCollector = null,
bool silent = false
) {
this.exception = exception;
this.library = library;
this.context = context;
this.stackFilter = stackFilter;
this.informationCollector = informationCollector;
this.silent = silent;
}
public readonly Exception exception;
public readonly string library;
public readonly string context;
public readonly EnumerableFilter<String> stackFilter;
public readonly InformationCollector informationCollector;
public readonly bool silent;
public string exceptionAsString() {
string longMessage = null;
if (this.exception != null) {
longMessage = this.exception.Message;
}
if (longMessage != null) {
longMessage = longMessage.TrimEnd();
}
if (longMessage.isEmpty()) {
longMessage = "<no message available>";
}
return longMessage;
}
public override string ToString() {
var buffer = new StringBuilder();
if (this.library.isNotEmpty() || this.context.isNotEmpty()) {
if (this.library.isNotEmpty()) {
buffer.AppendFormat("Error caught by {0}", this.library);
if (this.context.isNotEmpty()) {
buffer.Append(", ");
}
} else {
buffer.Append("Exception ");
}
if (this.context.isNotEmpty()) {
buffer.AppendFormat("thrown {0}", this.context);
}
buffer.Append(". ");
} else {
buffer.Append("An error was caught. ");
}
buffer.AppendLine(this.exceptionAsString());
if (this.informationCollector != null) {
this.informationCollector(buffer);
}
if (this.exception.StackTrace != null) {
IEnumerable<string> stackLines = this.exception.StackTrace.TrimEnd().Split('\n');
if (this.stackFilter != null) {
stackLines = this.stackFilter(stackLines);
} else {
stackLines = UIWidgetsError.defaultStackFilter(stackLines);
}
buffer.Append(string.Join("\n", stackLines.ToArray()));
}
return buffer.ToString().TrimEnd();
}
}
public class UIWidgetsError : AssertionError {
public UIWidgetsError(string message) : base(message) {
}
public static UIWidgetsExceptionHandler onError = dumpErrorToConsole;
static int _errorCount = 0;
public static void resetErrorCount() {
_errorCount = 0;
}
public static void dumpErrorToConsole(UIWidgetsErrorDetails details) {
dumpErrorToConsole(details, forceReport: false);
}
public static void dumpErrorToConsole(UIWidgetsErrorDetails details, bool forceReport = false) {
D.assert(details != null);
D.assert(details.exception != null);
bool reportError = !details.silent;
D.assert(() => {
reportError = true;
return true;
});
if (!reportError && !forceReport) {
return;
}
if (_errorCount == 0 || forceReport) {
Debug.Log(details.ToString());
} else {
Debug.Log("Another exception was thrown: " + details.exceptionAsString());
}
_errorCount += 1;
}
public static IEnumerable<string> defaultStackFilter(IEnumerable<string> frames) {
return frames;
}
public static void reportError(UIWidgetsErrorDetails details) {
D.assert(details != null);
D.assert(details.exception != null);
if (onError != null) {
onError(details);
}
}
}
}

3
Assets/UIWidgets/foundation/assertions.cs.meta


fileFormatVersion: 2
guid: b1c014fd2b864fe696ffb29b063921b4
timeCreated: 1536501637

52
Assets/UIWidgets/foundation/basic_types.cs


using System;
using System.Collections;
using System.Collections.Generic;
namespace UIWidgets.foundation {
public delegate IEnumerable<T> EnumerableFilter<T>(IEnumerable<T> input);
public static class CollectionUtils {
public static V putIfAbsent<K, V>(this IDictionary<K, V> it, K key, Func<V> ifAbsent) {
V value;
if (it.TryGetValue(key, out value)) {
return value;
}
value = ifAbsent();
it[key] = value;
return value;
}
public static bool isEmpty<T>(this ICollection<T> it) {
return it.Count == 0;
}
public static bool isNotEmpty<T>(this ICollection<T> it) {
return it.Count != 0;
}
public static bool isEmpty<T>(this Queue<T> it) {
return it.Count == 0;
}
public static bool isNotEmpty<T>(this Queue<T> it) {
return it.Count != 0;
}
public static bool isEmpty<TKey, TValue>(this IDictionary<TKey, TValue> it) {
return it.Count == 0;
}
public static bool isNotEmpty<TKey, TValue>(this IDictionary<TKey, TValue> it) {
return it.Count != 0;
}
public static bool isEmpty(this string it) {
return string.IsNullOrEmpty(it);
}
public static bool isNotEmpty(this string it) {
return !string.IsNullOrEmpty(it);
}
}
}

3
Assets/UIWidgets/foundation/basic_types.cs.meta


fileFormatVersion: 2
guid: 5677c530963d4d59baef909ab962ab44
timeCreated: 1535605561

38
Assets/UIWidgets/foundation/debug.cs


using System;
using System.Diagnostics;
namespace UIWidgets.foundation {
public static class D {
[Conditional("UIWidgets_DEBUG")]
public static void assert(Func<bool> result, string message = null) {
D.assert(result(), message);
}
[Conditional("UIWidgets_DEBUG")]
public static void assert(bool result, string message = null) {
if (!result) {
throw new AssertionError(message);
}
}
public static bool debugPrintGestureArenaDiagnostics = true;
public static bool debugPrintHitTestResults = true;
public static bool debugPaintPointersEnabled = false;
public static bool debugPrintRecognizerCallbacksTrace = true;
public static bool debugPrintBeginFrameBanner = true;
public static bool debugPrintEndFrameBanner = true;
public static bool debugPrintScheduleFrameStacks = true;
}
[Serializable]
public class AssertionError : Exception {
public AssertionError(string message) : base(message) {
}
}
}

3
Assets/UIWidgets/foundation/debug.cs.meta


fileFormatVersion: 2
guid: 89e39060aaba41798359de8d7e6a013e
timeCreated: 1536123374

1001
Assets/UIWidgets/foundation/diagnostics.cs
文件差异内容过多而无法显示
查看文件

3
Assets/UIWidgets/foundation/diagnostics.cs.meta


fileFormatVersion: 2
guid: 16aaa3f0f74a4188b49c27f602b4341d
timeCreated: 1536203150

163
Assets/UIWidgets/foundation/node.mixin.gen.cs


namespace UIWidgets.foundation {
public class AbstractNode {
public int depth {
get { return this._depth; }
}
int _depth = 0;
protected void redepthChild(AbstractNode child) {
D.assert(child.owner == this.owner);
if (child._depth <= this._depth) {
child._depth = this._depth + 1;
child.redepthChildren();
}
}
public virtual void redepthChildren() {
}
public object owner {
get { return this._owner; }
}
object _owner;
public bool attached {
get { return this._owner != null; }
}
public virtual void attach(object owner) {
D.assert(owner != null);
D.assert(this._owner == null);
this._owner = owner;
}
public virtual void detach() {
D.assert(this._owner != null);
this._owner = null;
}
public AbstractNode parent {
get { return this._parent; }
}
AbstractNode _parent;
protected virtual void adoptChild(AbstractNode child) {
D.assert(child != null);
D.assert(child._parent == null);
D.assert(() => {
var node = this;
while (node.parent != null)
node = node.parent;
D.assert(node != child); // indicates we are about to create a cycle
return true;
});
child._parent = this;
if (this.attached) {
child.attach(this._owner);
}
this.redepthChild(child);
}
protected virtual void dropChild(AbstractNode child) {
D.assert(child != null);
D.assert(child._parent == this);
D.assert(child.attached == this.attached);
child._parent = null;
if (this.attached) {
child.detach();
}
}
}
public class AbstractNodeMixinDiagnosticableTree : DiagnosticableTree {
public int depth {
get { return this._depth; }
}
int _depth = 0;
protected void redepthChild(AbstractNodeMixinDiagnosticableTree child) {
D.assert(child.owner == this.owner);
if (child._depth <= this._depth) {
child._depth = this._depth + 1;
child.redepthChildren();
}
}
public virtual void redepthChildren() {
}
public object owner {
get { return this._owner; }
}
object _owner;
public bool attached {
get { return this._owner != null; }
}
public virtual void attach(object owner) {
D.assert(owner != null);
D.assert(this._owner == null);
this._owner = owner;
}
public virtual void detach() {
D.assert(this._owner != null);
this._owner = null;
}
public AbstractNodeMixinDiagnosticableTree parent {
get { return this._parent; }
}
AbstractNodeMixinDiagnosticableTree _parent;
protected virtual void adoptChild(AbstractNodeMixinDiagnosticableTree child) {
D.assert(child != null);
D.assert(child._parent == null);
D.assert(() => {
var node = this;
while (node.parent != null)
node = node.parent;
D.assert(node != child); // indicates we are about to create a cycle
return true;
});
child._parent = this;
if (this.attached) {
child.attach(this._owner);
}
this.redepthChild(child);
}
protected virtual void dropChild(AbstractNodeMixinDiagnosticableTree child) {
D.assert(child != null);
D.assert(child._parent == this);
D.assert(child.attached == this.attached);
child._parent = null;
if (this.attached) {
child.detach();
}
}
}
}

11
Assets/UIWidgets/foundation/node.mixin.gen.cs.meta


fileFormatVersion: 2
guid: b7a18c2b3beb04ccba0b8585c1cdb618
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

88
Assets/UIWidgets/foundation/node.mixin.njk


namespace UIWidgets.foundation {
{% macro AbstractNodeMixin(with) %}
{% set className = 'AbstractNode' if with == '' else 'AbstractNodeMixin' + with %}
{% set extends = '' if with == '' else ' : ' + with %}
public class {{className}} {{extends}} {
public int depth {
get { return this._depth; }
}
int _depth = 0;
protected void redepthChild({{className}} child) {
D.assert(child.owner == this.owner);
if (child._depth <= this._depth) {
child._depth = this._depth + 1;
child.redepthChildren();
}
}
public virtual void redepthChildren() {
}
public object owner {
get { return this._owner; }
}
object _owner;
public bool attached {
get { return this._owner != null; }
}
public virtual void attach(object owner) {
D.assert(owner != null);
D.assert(this._owner == null);
this._owner = owner;
}
public virtual void detach() {
D.assert(this._owner != null);
this._owner = null;
}
public {{className}} parent {
get { return this._parent; }
}
{{className}} _parent;
protected virtual void adoptChild({{className}} child) {
D.assert(child != null);
D.assert(child._parent == null);
D.assert(() => {
var node = this;
while (node.parent != null)
node = node.parent;
D.assert(node != child); // indicates we are about to create a cycle
return true;
});
child._parent = this;
if (this.attached) {
child.attach(this._owner);
}
this.redepthChild(child);
}
protected virtual void dropChild({{className}} child) {
D.assert(child != null);
D.assert(child._parent == this);
D.assert(child.attached == this.attached);
child._parent = null;
if (this.attached) {
child.detach();
}
}
}
{% endmacro %}
{{ AbstractNodeMixin('') }}
{{ AbstractNodeMixin('DiagnosticableTree') }}
}

3
Assets/UIWidgets/foundation/node.mixin.njk.meta


fileFormatVersion: 2
guid: 3169ab76e1bc45cf92b23f07f2688b62
timeCreated: 1536301833

95
Assets/UIWidgets/foundation/print.cs


using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace UIWidgets.foundation {
enum _WordWrapParseMode {
inSpace,
inWord,
atBreak
}
public static class DebugPrint {
static readonly Regex _indentPattern = new Regex("^ *(?:[-+*] |[0-9]+[.):] )?");
public static IEnumerable<string> debugWordWrap(string message, int width, string wrapIndent = "") {
if (message.Length < width || message.TrimStart()[0] == '#') {
yield return message;
yield break;
}
Match prefixMatch = _indentPattern.Match(message);
string prefix = wrapIndent + new string(' ', prefixMatch.Groups[0].Value.Length);
int start = 0;
int startForLengthCalculations = 0;
bool addPrefix = false;
int index = prefix.Length;
_WordWrapParseMode mode = _WordWrapParseMode.inSpace;
int lastWordStart = 0;
int? lastWordEnd = null;
while (true) {
switch (mode) {
case _WordWrapParseMode.inSpace:
// at start of break point (or start of line); can"t break until next break
while ((index < message.Length) && (message[index] == ' ')) {
index += 1;
}
lastWordStart = index;
mode = _WordWrapParseMode.inWord;
break;
case _WordWrapParseMode.inWord: // looking for a good break point
while ((index < message.Length) && (message[index] != ' ')) {
index += 1;
}
mode = _WordWrapParseMode.atBreak;
break;
case _WordWrapParseMode.atBreak: // at start of break point
if ((index - startForLengthCalculations > width) || (index == message.Length)) {
// we are over the width line, so break
if ((index - startForLengthCalculations <= width) || (lastWordEnd == null)) {
// we should use this point, because either it doesn"t actually go over the
// end (last line), or it does, but there was no earlier break point
lastWordEnd = index;
}
if (addPrefix) {
yield return prefix + message.Substring(start, lastWordEnd.Value - start);
} else {
yield return message.Substring(start, lastWordEnd.Value - start);
addPrefix = true;
}
if (lastWordEnd >= message.Length)
yield break;
// just yield returned a line
if (lastWordEnd == index) {
// we broke at current position
// eat all the spaces, then set our start point
while ((index < message.Length) && (message[index] == ' '))
index += 1;
start = index;
mode = _WordWrapParseMode.inWord;
} else {
// we broke at the previous break point, and we"re at the start of a new one
D.assert(lastWordStart > lastWordEnd);
start = lastWordStart;
mode = _WordWrapParseMode.atBreak;
}
startForLengthCalculations = start - prefix.Length;
D.assert(addPrefix);
lastWordEnd = null;
} else {
// save this break point, we"re not yet over the line width
lastWordEnd = index;
// skip to the end of this break point
mode = _WordWrapParseMode.inSpace;
}
break;
}
}
}
}
}

3
Assets/UIWidgets/foundation/print.cs.meta


fileFormatVersion: 2
guid: 3c7a659f877d47afae10826010956757
timeCreated: 1536214859

8
Assets/UIWidgets/gestures.meta


fileFormatVersion: 2
guid: 8617cc0ea80d74e80a0579e70d4e2d2c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

11
Assets/UIWidgets/gestures/arena.cs.meta


fileFormatVersion: 2
guid: 8f1294e5215474e2d9ff98330207760e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

100
Assets/UIWidgets/gestures/binding.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.scheduler;
using UIWidgets.ui;
using UnityEngine;
namespace UIWidgets.gestures {
public class GestureBinding : SchedulerBinding, HitTestable, HitTestDispatcher, HitTestTarget {
public GestureBinding(Window window) : base(window) {
this.window.onPointerEvent += this._handlePointerDataPacket;
this.gestureArena = new GestureArenaManager(window);
}
readonly Queue<PointerEvent> _pendingPointerEvents = new Queue<PointerEvent>();
void _handlePointerDataPacket(PointerDataPacket packet) {
foreach (var pointerEvent in PointerEventConverter.expand(packet.data, this.window.devicePixelRatio)) {
this._pendingPointerEvents.Enqueue(pointerEvent);
}
this._flushPointerEventQueue();
}
public void cancelPointer(int pointer) {
if (this._pendingPointerEvents.isEmpty()) {
this.window.scheduleMicrotask(this._flushPointerEventQueue);
}
this._pendingPointerEvents.Enqueue(
new PointerCancelEvent(timeStamp: DateTime.Now, pointer: pointer));
}
void _flushPointerEventQueue() {
while (this._pendingPointerEvents.Count != 0) {
this._handlePointerEvent(this._pendingPointerEvents.Dequeue());
}
}
public readonly PointerRouter pointerRouter = new PointerRouter();
public readonly GestureArenaManager gestureArena;
public readonly Dictionary<int, HitTestResult> _hitTests = new Dictionary<int, HitTestResult>();
void _handlePointerEvent(PointerEvent evt) {
HitTestResult result;
if (evt is PointerDownEvent) {
D.assert(!this._hitTests.ContainsKey(evt.pointer));
result = new HitTestResult();
this.hitTest(result, evt.position);
this._hitTests[evt.pointer] = result;
D.assert(() => {
if (D.debugPrintHitTestResults) {
Debug.LogFormat("{0}: {1}", evt, result);
}
return true;
});
} else if (evt is PointerUpEvent || evt is PointerCancelEvent) {
result = this._hitTests[evt.pointer];
this._hitTests.Remove(evt.pointer);
} else if (evt.down) {
result = this._hitTests[evt.pointer];
} else {
return;
}
if (result != null) {
this.dispatchEvent(evt, result);
}
}
public virtual void hitTest(HitTestResult result, Offset position) {
result.add(new HitTestEntry(this));
}
public void dispatchEvent(PointerEvent evt, HitTestResult result) {
foreach (HitTestEntry entry in result.path) {
try {
entry.target.handleEvent(evt, entry);
}
catch (Exception ex) {
Debug.LogError("Error while dispatching a pointer event: " + ex);
}
}
}
public void handleEvent(PointerEvent evt, HitTestEntry entry) {
this.pointerRouter.route(evt);
if (evt is PointerDownEvent) {
this.gestureArena.close(evt.pointer);
} else if (evt is PointerUpEvent) {
this.gestureArena.sweep(evt.pointer);
}
}
}
}

3
Assets/UIWidgets/gestures/binding.cs.meta


fileFormatVersion: 2
guid: 4cdb394be98c414fb19a438686b949c1
timeCreated: 1535609218

21
Assets/UIWidgets/gestures/constants.cs


using System;
namespace UIWidgets.gestures {
public static class Constants {
public const double kTouchSlop = 18.0;
public const double kDoubleTapTouchSlop = kTouchSlop;
public const double kDoubleTapSlop = 100.0;
public const double kPanSlop = kTouchSlop * 2.0;
public static readonly TimeSpan kPressTimeout = new TimeSpan(0, 0, 0, 0, 100);
public static readonly TimeSpan kDoubleTapTimeout = new TimeSpan(0, 0, 0, 0, 300);
public const double kMinFlingVelocity = 50.0;
public const double kMaxFlingVelocity = 8000.0;
}
}

3
Assets/UIWidgets/gestures/constants.cs.meta


fileFormatVersion: 2
guid: fe1823eee58c44999e824c526724caa3
timeCreated: 1535608065

142
Assets/UIWidgets/gestures/converter.cs


using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.gestures {
class _PointerState {
public _PointerState(Offset lastPosition) {
this.lastPosition = lastPosition ?? Offset.zero;
}
public int pointer {
get { return this._pointer; }
}
int _pointer;
static int _pointerCount = 0;
public void startNewPointer() {
_PointerState._pointerCount += 1;
this._pointer = _PointerState._pointerCount;
}
public bool down {
get { return this._down; }
}
bool _down = false;
public void setDown() {
D.assert(!this._down);
this._down = true;
}
public void setUp() {
D.assert(this._down);
this._down = false;
}
public Offset lastPosition;
public override string ToString() {
return string.Format("_PointerState(pointer: {0}, down: {1}, lastPosition: {2})",
this.pointer, this.down, this.lastPosition);
}
}
public static class PointerEventConverter {
static readonly Dictionary<int, _PointerState> _pointers = new Dictionary<int, _PointerState>();
static _PointerState _ensureStateForPointer(PointerData datum, Offset position) {
return _pointers.putIfAbsent(
datum.device,
() => new _PointerState(position));
}
public static IEnumerable<PointerEvent> expand(IEnumerable<PointerData> data, double devicePixelRatio) {
foreach (PointerData datum in data) {
var position = new Offset(datum.physicalX, datum.physicalY) / devicePixelRatio;
var timeStamp = datum.timeStamp;
var kind = datum.kind;
switch (datum.change) {
case PointerChange.down: {
_PointerState state = _ensureStateForPointer(datum, position);
D.assert(!state.down);
if (state.lastPosition != position) {
// a hover event to be here.
state.lastPosition = position;
}
state.startNewPointer();
state.setDown();
yield return new PointerDownEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position
);
}
break;
case PointerChange.move: {
D.assert(_pointers.ContainsKey(datum.device));
_PointerState state = _pointers[datum.device];
D.assert(state.down);
Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield return new PointerMoveEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position,
delta: offset
);
}
break;
case PointerChange.up:
case PointerChange.cancel: {
D.assert(_pointers.ContainsKey(datum.device));
_PointerState state = _pointers[datum.device];
D.assert(state.down);
if (position != state.lastPosition) {
Offset offset = position - state.lastPosition;
state.lastPosition = position;
yield return new PointerMoveEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position,
delta: offset,
synthesized: true
);
}
D.assert(position == state.lastPosition);
state.setUp();
if (datum.change == PointerChange.up) {
yield return new PointerUpEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position
);
} else {
yield return new PointerCancelEvent(
timeStamp: timeStamp,
pointer: state.pointer,
kind: kind,
device: datum.device,
position: position
);
}
}
break;
}
}
}
}
}

3
Assets/UIWidgets/gestures/converter.cs.meta


fileFormatVersion: 2
guid: 929719430a6b48a4b9639a1bb8b37e88
timeCreated: 1536051892

90
Assets/UIWidgets/gestures/drag_details.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.gestures {
public class DragDownDetails {
public DragDownDetails(
Offset globalPosition = null
) {
this.globalPosition = globalPosition ?? Offset.zero;
}
public readonly Offset globalPosition;
public override string ToString() {
return this.GetType() + "(" + this.globalPosition + ")";
}
}
public delegate void GestureDragDownCallback(DragDownDetails details);
public class DragStartDetails {
public DragStartDetails(DateTime sourceTimeStamp, Offset globalPosition = null) {
this.sourceTimeStamp = sourceTimeStamp;
this.globalPosition = globalPosition ?? Offset.zero;
}
public readonly DateTime sourceTimeStamp;
public readonly Offset globalPosition;
public override string ToString() {
return this.GetType() + "(" + this.globalPosition + ")";
}
}
public delegate void GestureDragStartCallback(DragStartDetails details);
public class DragUpdateDetails {
public DragUpdateDetails(
DateTime sourceTimeStamp,
Offset delta = null,
double? primaryDelta = null,
Offset globalPosition = null) {
this.sourceTimeStamp = sourceTimeStamp;
this.delta = delta ?? Offset.zero;
this.primaryDelta = primaryDelta;
this.globalPosition = globalPosition ?? Offset.zero;
D.assert(primaryDelta == null
|| primaryDelta == this.delta.dx && this.delta.dy == 0.0
|| primaryDelta == this.delta.dy && this.delta.dx == 0.0);
}
public readonly DateTime sourceTimeStamp;
public readonly Offset delta;
public readonly double? primaryDelta;
public readonly Offset globalPosition;
public override string ToString() {
return this.GetType() + "(" + this.delta + ")";
}
}
public delegate void GestureDragUpdateCallback(DragUpdateDetails details);
public class DragEndDetails {
public DragEndDetails(
Velocity velocity = null,
double? primaryVelocity = null
) {
this.velocity = velocity ?? Velocity.zero;
this.primaryVelocity = primaryVelocity;
D.assert(primaryVelocity == null
|| primaryVelocity == this.velocity.pixelsPerSecond.dx
|| primaryVelocity == this.velocity.pixelsPerSecond.dy);
}
public readonly Velocity velocity;
public readonly double? primaryVelocity;
public override string ToString() {
return this.GetType() + "(" + this.velocity + ")";
}
}
}

3
Assets/UIWidgets/gestures/drag_details.cs.meta


fileFormatVersion: 2
guid: 4283bd1f6f7945578b47e7ad21999e7c
timeCreated: 1536330559

142
Assets/UIWidgets/gestures/events.cs


using System;
using UIWidgets.ui;
namespace UIWidgets.gestures {
public abstract class PointerEvent {
public PointerEvent(
DateTime timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null,
Offset delta = null,
bool down = false,
bool synthesized = false
) {
this.timeStamp = timeStamp;
this.pointer = pointer;
this.kind = kind;
this.device = device;
this.position = position ?? Offset.zero;
this.delta = delta ?? Offset.zero;
this.down = down;
this.synthesized = synthesized;
}
public readonly DateTime timeStamp;
public readonly int pointer;
public PointerDeviceKind kind;
public int device;
public readonly Offset position;
public readonly Offset delta;
public readonly bool down;
public readonly bool synthesized;
}
public class PointerAddedEvent : PointerEvent {
public PointerAddedEvent(
DateTime timeStamp,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0,
Offset position = null
) : base(
timeStamp: timeStamp,
kind: kind,
device: device,
position: position
) {
}
}
public class PointerRemovedEvent : PointerEvent {
public PointerRemovedEvent(
DateTime timeStamp,
PointerDeviceKind kind = PointerDeviceKind.touch,
int device = 0
) : base(
timeStamp: timeStamp,
kind: kind,
device: device
) {
}
}
public class PointerDownEvent : PointerEvent {
public PointerDownEvent(
DateTime timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: true) {
}
}
public class PointerMoveEvent : PointerEvent {
public PointerMoveEvent(
DateTime timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null,
Offset delta = null,
bool synthesized = false)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
delta: delta,
down: true,
synthesized: synthesized) {
}
}
public class PointerUpEvent : PointerEvent {
public PointerUpEvent(
DateTime timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: false) {
}
}
public class PointerCancelEvent : PointerEvent {
public PointerCancelEvent(
DateTime timeStamp,
int pointer = 0,
PointerDeviceKind kind = PointerDeviceKind.mouse,
int device = 0,
Offset position = null)
: base(
timeStamp,
pointer: pointer,
kind: kind,
device: device,
position: position,
down: false) {
}
}
}

3
Assets/UIWidgets/gestures/events.cs.meta


fileFormatVersion: 2
guid: 85b73f18462c41199d2bd67c8f012ba6
timeCreated: 1535595953

57
Assets/UIWidgets/gestures/hit_test.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.gestures {
public interface HitTestable {
void hitTest(HitTestResult result, Offset position);
}
public interface HitTestDispatcher {
void dispatchEvent(PointerEvent evt, HitTestResult result);
}
public interface HitTestTarget {
void handleEvent(PointerEvent evt, HitTestEntry entry);
}
public class HitTestEntry {
public HitTestEntry(HitTestTarget target) {
this._target = target;
}
public virtual HitTestTarget target {
get { return this._target; }
}
readonly HitTestTarget _target;
public override string ToString() {
return this._target.ToString();
}
}
public class HitTestResult {
public HitTestResult(List<HitTestEntry> path = null) {
this._path = path ?? new List<HitTestEntry>();
}
public IList<HitTestEntry> path {
get { return this._path.AsReadOnly(); }
}
readonly List<HitTestEntry> _path;
public void add(HitTestEntry entry) {
this._path.Add(entry);
}
public override string ToString() {
return string.Format("HitTestResult({0})",
this._path.isEmpty()
? "<empty path>"
: string.Join(", ", this._path.Select(x => x.ToString()).ToArray()));
}
}
}

3
Assets/UIWidgets/gestures/hit_test.cs.meta


fileFormatVersion: 2
guid: 8e54d41203874208ad368d1a42e611f8
timeCreated: 1535595576

186
Assets/UIWidgets/gestures/lsq_resolver.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
namespace UIWidgets.gestures {
class _Vector {
internal _Vector(int size) {
this._offset = 0;
this._length = size;
this._elements = Enumerable.Repeat(0.0, size).ToList();
}
private _Vector(List<double> values, int offset, int length) {
this._offset = offset;
this._length = length;
this._elements = values;
}
internal static _Vector fromVOL(List<double> values, int offset, int length) {
return new _Vector(values, offset, length);
}
readonly int _offset;
readonly int _length;
readonly List<double> _elements;
public double this[int i] {
get { return this._elements[i + this._offset]; }
set { this._elements[i + this._offset] = value; }
}
public static double operator *(_Vector a, _Vector b) {
double result = 0.0;
for (int i = 0; i < a._length; i += 1)
result += a[i] * b[i];
return result;
}
public double norm() {
return Math.Sqrt(this * this);
}
}
class _Matrix {
internal _Matrix(int rows, int cols) {
this._columns = cols;
this._elements = Enumerable.Repeat(0.0, rows * cols).ToList();
}
readonly int _columns;
readonly List<double> _elements;
public double this[int row, int col] {
get { return this._elements[row * this._columns + col]; }
set { this._elements[row * this._columns + col] = value; }
}
public _Vector getRow(int row) {
return _Vector.fromVOL(
this._elements,
row * this._columns,
this._columns
);
}
}
public class PolynomialFit {
public PolynomialFit(int degree) {
this.coefficients = Enumerable.Repeat(0.0, degree + 1).ToList();
}
public readonly List<double> coefficients;
public double confidence;
}
public class LeastSquaresSolver {
public LeastSquaresSolver(List<double> x, List<double> y, List<double> w) {
D.assert(x != null && y != null && w != null);
D.assert(x.Count == y.Count);
D.assert(y.Count == w.Count);
this.x = x;
this.y = y;
this.w = w;
}
public readonly List<double> x;
public readonly List<double> y;
public readonly List<double> w;
/// Fits a polynomial of the given degree to the data points.
public PolynomialFit solve(int degree) {
if (degree > this.x.Count) {
// Not enough data to fit a curve.
return null;
}
PolynomialFit result = new PolynomialFit(degree);
// Shorthands for the purpose of notation equivalence to original C++ code.
int m = x.Count;
int n = degree + 1;
// Expand the X vector to a matrix A, pre-multiplied by the weights.
_Matrix a = new _Matrix(n, m);
for (int h = 0; h < m; h += 1) {
a[0, h] = this.w[h];
for (int i = 1; i < n; i += 1)
a[i, h] = a[i - 1, h] * this.x[h];
}
// Apply the Gram-Schmidt process to A to obtain its QR decomposition.
// Orthonormal basis, column-major ordVectorer.
_Matrix q = new _Matrix(n, m);
// Upper triangular matrix, row-major order.
_Matrix r = new _Matrix(n, n);
for (int j = 0; j < n; j += 1) {
for (int h = 0; h < m; h += 1)
q[j, h] = a[j, h];
for (int i = 0; i < j; i += 1) {
double dot = q.getRow(j) * q.getRow(i);
for (int h = 0; h < m; h += 1)
q[j, h] = q[j, h] - dot * q[i, h];
}
double norm = q.getRow(j).norm();
if (norm < 0.000001) {
// Vectors are linearly dependent or zero so no solution.
return null;
}
double inverseNorm = 1.0 / norm;
for (int h = 0; h < m; h += 1)
q[j, h] = q[j, h] * inverseNorm;
for (int i = 0; i < n; i += 1)
r[j, i] = i < j ? 0.0 : q.getRow(j) * a.getRow(i);
}
// Solve R B = Qt W Y to find B. This is easy because R is upper triangular.
// We just work from bottom-right to top-left calculating B's coefficients.
_Vector wy = new _Vector(m);
for (int h = 0; h < m; h += 1)
wy[h] = y[h] * w[h];
for (int i = n - 1; i >= 0; i -= 1) {
result.coefficients[i] = q.getRow(i) * wy;
for (int j = n - 1; j > i; j -= 1)
result.coefficients[i] -= r[i, j] * result.coefficients[j];
result.coefficients[i] /= r[i, i];
}
// Calculate the coefficient of determination (confidence) as:
// 1 - (sumSquaredError / sumSquaredTotal)
// ...where sumSquaredError is the residual sum of squares (variance of the
// error), and sumSquaredTotal is the total sum of squares (variance of the
// data) where each has been weighted.
double yMean = 0.0;
for (int h = 0; h < m; h += 1)
yMean += y[h];
yMean /= m;
double sumSquaredError = 0.0;
double sumSquaredTotal = 0.0;
for (int h = 0; h < m; h += 1) {
double term = 1.0;
double err = y[h] - result.coefficients[0];
for (int i = 1; i < n; i += 1) {
term *= x[h];
err -= term * result.coefficients[i];
}
sumSquaredError += w[h] * w[h] * err * err;
double v = y[h] - yMean;
sumSquaredTotal += w[h] * w[h] * v * v;
}
result.confidence = sumSquaredTotal <= 0.000001 ? 1.0 : 1.0 - (sumSquaredError / sumSquaredTotal);
return result;
}
}
}

3
Assets/UIWidgets/gestures/lsq_resolver.cs.meta


fileFormatVersion: 2
guid: 575547b88e714c13b02cc94a7fac6bb2
timeCreated: 1536333643

281
Assets/UIWidgets/gestures/monodrag.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.gestures {
enum _DragState {
ready,
possible,
accepted,
}
public delegate void GestureDragEndCallback(DragEndDetails details);
public delegate void GestureDragCancelCallback();
public abstract class DragGestureRecognizer : OneSequenceGestureRecognizer {
public DragGestureRecognizer(GestureBinding binding, object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
}
public GestureDragDownCallback onDown;
public GestureDragStartCallback onStart;
public GestureDragUpdateCallback onUpdate;
public GestureDragEndCallback onEnd;
public GestureDragCancelCallback onCancel;
public double? minFlingDistance;
public double? minFlingVelocity;
public double? maxFlingVelocity;
_DragState _state = _DragState.ready;
Offset _initialPosition;
protected Offset _pendingDragOffset;
DateTime _lastPendingEventTimestamp;
protected abstract bool _isFlingGesture(VelocityEstimate estimate);
protected abstract Offset _getDeltaForDetails(Offset delta);
protected abstract double? _getPrimaryValueFromOffset(Offset value);
protected abstract bool _hasSufficientPendingDragDeltaToAccept { get; }
readonly Dictionary<int, VelocityTracker> _velocityTrackers = new Dictionary<int, VelocityTracker>();
public override void addPointer(PointerDownEvent evt) {
this.startTrackingPointer(evt.pointer);
this._velocityTrackers[evt.pointer] = new VelocityTracker();
if (this._state == _DragState.ready) {
this._state = _DragState.possible;
this._initialPosition = evt.position;
this._pendingDragOffset = Offset.zero;
this._lastPendingEventTimestamp = evt.timeStamp;
if (this.onDown != null) {
this.invokeCallback<object>("onDown",
() => {
this.onDown(new DragDownDetails(globalPosition: this._initialPosition));
return null;
});
}
} else if (this._state == _DragState.accepted) {
this.resolve(GestureDisposition.accepted);
}
}
protected override void handleEvent(PointerEvent evt) {
D.assert(this._state != _DragState.ready);
if (!evt.synthesized
&& (evt is PointerDownEvent || evt is PointerMoveEvent)) {
var tracker = this._velocityTrackers[evt.pointer];
D.assert(tracker != null);
tracker.addPosition(evt.timeStamp, evt.position);
}
if (evt is PointerMoveEvent) {
Offset delta = evt.delta;
if (this._state == _DragState.accepted) {
if (this.onUpdate != null) {
this.invokeCallback<object>("onUpdate", () => {
this.onUpdate(new DragUpdateDetails(
sourceTimeStamp: evt.timeStamp,
delta: this._getDeltaForDetails(delta),
primaryDelta: this._getPrimaryValueFromOffset(delta),
globalPosition: evt.position
));
return null;
});
}
} else {
this._pendingDragOffset += delta;
this._lastPendingEventTimestamp = evt.timeStamp;
if (this._hasSufficientPendingDragDeltaToAccept) {
this.resolve(GestureDisposition.accepted);
}
}
}
this.stopTrackingIfPointerNoLongerDown(evt);
}
public override void acceptGesture(int pointer) {
if (this._state != _DragState.accepted) {
this._state = _DragState.accepted;
Offset delta = this._pendingDragOffset;
var timestamp = this._lastPendingEventTimestamp;
this._pendingDragOffset = Offset.zero;
this._lastPendingEventTimestamp = default(DateTime);
if (this.onStart != null) {
this.invokeCallback<object>("onStart", () => {
this.onStart(new DragStartDetails(
sourceTimeStamp: timestamp,
globalPosition: this._initialPosition
));
return null;
});
}
if (delta != Offset.zero && this.onUpdate != null) {
this.invokeCallback<object>("onUpdate", () => {
this.onUpdate(new DragUpdateDetails(
sourceTimeStamp: timestamp,
delta: this._getDeltaForDetails(delta),
primaryDelta: this._getPrimaryValueFromOffset(delta),
globalPosition: this._initialPosition
));
return null;
});
}
}
}
public override void rejectGesture(int pointer) {
this.stopTrackingPointer(pointer);
}
protected override void didStopTrackingLastPointer(int pointer) {
if (this._state == _DragState.possible) {
this.resolve(GestureDisposition.rejected);
this._state = _DragState.ready;
if (this.onCancel != null) {
this.invokeCallback<object>("onCancel", () => {
this.onCancel();
return null;
});
}
return;
}
bool wasAccepted = this._state == _DragState.accepted;
this._state = _DragState.ready;
if (wasAccepted && this.onEnd != null) {
var tracker = this._velocityTrackers[pointer];
D.assert(tracker != null);
var estimate = tracker.getVelocityEstimate();
if (estimate != null && this._isFlingGesture(estimate)) {
Velocity velocity = new Velocity(pixelsPerSecond: estimate.pixelsPerSecond)
.clampMagnitude(this.minFlingVelocity ?? Constants.kMinFlingVelocity,
this.maxFlingVelocity ?? Constants.kMaxFlingVelocity);
this.invokeCallback<object>("onEnd", () => {
this.onEnd(new DragEndDetails(
velocity: velocity,
primaryVelocity: this._getPrimaryValueFromOffset(velocity.pixelsPerSecond)
));
return null;
}, debugReport: () =>
string.Format("{0}; fling at {1}.", estimate, velocity));
} else {
this.invokeCallback<object>("onEnd", () => {
this.onEnd(new DragEndDetails(
velocity: Velocity.zero,
primaryVelocity: 0.0
));
return null;
}, debugReport: () =>
estimate == null
? "Could not estimate velocity."
: estimate + "; judged to not be a fling."
);
}
}
this._velocityTrackers.Clear();
}
public override void dispose() {
this._velocityTrackers.Clear();
base.dispose();
}
}
public class VerticalDragGestureRecognizer : DragGestureRecognizer {
public VerticalDragGestureRecognizer(GestureBinding binding, Object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
}
protected override bool _isFlingGesture(VelocityEstimate estimate) {
double minVelocity = this.minFlingVelocity ?? Constants.kMinFlingVelocity;
double minDistance = this.minFlingDistance ?? Constants.kTouchSlop;
return Math.Abs(estimate.pixelsPerSecond.dy) > minVelocity && Math.Abs(estimate.offset.dy) > minDistance;
}
protected override bool _hasSufficientPendingDragDeltaToAccept {
get { return Math.Abs(this._pendingDragOffset.dy) > Constants.kTouchSlop; }
}
protected override Offset _getDeltaForDetails(Offset delta) {
return new Offset(0.0, delta.dy);
}
protected override double? _getPrimaryValueFromOffset(Offset value) {
return value.dy;
}
public override string debugDescription {
get { return "vertical drag"; }
}
}
public class HorizontalDragGestureRecognizer : DragGestureRecognizer {
public HorizontalDragGestureRecognizer(GestureBinding binding, Object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
}
protected override bool _isFlingGesture(VelocityEstimate estimate) {
double minVelocity = this.minFlingVelocity ?? Constants.kMinFlingVelocity;
double minDistance = this.minFlingDistance ?? Constants.kTouchSlop;
return Math.Abs(estimate.pixelsPerSecond.dx) > minVelocity && Math.Abs(estimate.offset.dx) > minDistance;
}
protected override bool _hasSufficientPendingDragDeltaToAccept {
get { return Math.Abs(this._pendingDragOffset.dx) > Constants.kTouchSlop; }
}
protected override Offset _getDeltaForDetails(Offset delta) {
return new Offset(delta.dx, 0.0);
}
protected override double? _getPrimaryValueFromOffset(Offset value) {
return value.dx;
}
public override string debugDescription {
get { return "horizontal drag"; }
}
}
public class PanGestureRecognizer : DragGestureRecognizer {
public PanGestureRecognizer(GestureBinding binding, Object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
}
protected override bool _isFlingGesture(VelocityEstimate estimate) {
double minVelocity = this.minFlingVelocity ?? Constants.kMinFlingVelocity;
double minDistance = this.minFlingDistance ?? Constants.kTouchSlop;
return estimate.pixelsPerSecond.distanceSquared > minVelocity * minVelocity
&& estimate.offset.distanceSquared > minDistance * minDistance;
}
protected override bool _hasSufficientPendingDragDeltaToAccept {
get { return this._pendingDragOffset.distance > Constants.kPanSlop; }
}
protected override Offset _getDeltaForDetails(Offset delta) {
return delta;
}
protected override double? _getPrimaryValueFromOffset(Offset value) {
return null;
}
public override string debugDescription {
get { return "pan"; }
}
}
}

3
Assets/UIWidgets/gestures/monodrag.cs.meta


fileFormatVersion: 2
guid: 145abf9020044c79bf9227730292796d
timeCreated: 1536328579

190
Assets/UIWidgets/gestures/multitap.cs


using System.Collections.Generic;
using System.Linq;
using RSG.Promises;
using UIWidgets.async;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.gestures {
public delegate void GestureDoubleTapCallback();
class _TapTracker {
internal _TapTracker(
GestureBinding binding = null,
PointerDownEvent evt = null,
GestureArenaEntry entry = null) {
this._binding = binding;
this.pointer = evt.pointer;
this._initialPosition = evt.position;
this.entry = entry;
}
public readonly int pointer;
public readonly GestureArenaEntry entry;
readonly Offset _initialPosition;
readonly GestureBinding _binding;
bool _isTrackingPointer = false;
public void startTrackingPointer(PointerRoute route) {
if (!this._isTrackingPointer) {
this._isTrackingPointer = true;
this._binding.pointerRouter.addRoute(this.pointer, route);
}
}
public void stopTrackingPointer(PointerRoute route) {
if (this._isTrackingPointer) {
this._isTrackingPointer = false;
this._binding.pointerRouter.removeRoute(this.pointer, route);
}
}
public bool isWithinTolerance(PointerEvent evt, double tolerance) {
Offset offset = evt.position - this._initialPosition;
return offset.distance <= tolerance;
}
}
public class DoubleTapGestureRecognizer : GestureRecognizer {
public DoubleTapGestureRecognizer(
GestureBinding binding = null, object debugOwner = null)
: base(binding: binding, debugOwner: debugOwner) {
}
public GestureDoubleTapCallback onDoubleTap;
Timer _doubleTapTimer;
_TapTracker _firstTap;
readonly Dictionary<int, _TapTracker> _trackers = new Dictionary<int, _TapTracker>();
public override void addPointer(PointerDownEvent evt) {
if (this._firstTap != null &&
!this._firstTap.isWithinTolerance(evt, Constants.kDoubleTapSlop)) {
return;
}
this._stopDoubleTapTimer();
_TapTracker tracker = new _TapTracker(
binding: this._binding,
evt: evt,
entry: this._binding.gestureArena.add(evt.pointer, this)
);
this._trackers[evt.pointer] = tracker;
tracker.startTrackingPointer(this._handleEvent);
}
void _handleEvent(PointerEvent evt) {
_TapTracker tracker = this._trackers[evt.pointer];
D.assert(tracker != null);
if (evt is PointerUpEvent) {
if (this._firstTap == null) {
this._registerFirstTap(tracker);
} else {
this._registerSecondTap(tracker);
}
} else if (evt is PointerMoveEvent) {
if (!tracker.isWithinTolerance(evt, Constants.kDoubleTapTouchSlop)) {
this._reject(tracker);
}
} else if (evt is PointerCancelEvent) {
this._reject(tracker);
}
}
public override void acceptGesture(int pointer) {
}
public override void rejectGesture(int pointer) {
_TapTracker tracker;
this._trackers.TryGetValue(pointer, out tracker);
if (tracker == null &&
this._firstTap != null &&
this._firstTap.pointer == pointer) {
tracker = this._firstTap;
}
if (tracker != null) {
this._reject(tracker);
}
}
void _reject(_TapTracker tracker) {
this._trackers.Remove(tracker.pointer);
tracker.entry.resolve(GestureDisposition.rejected);
this._freezeTracker(tracker);
if (this._firstTap != null &&
(this._trackers.isEmpty() || tracker == this._firstTap)) {
this._reset();
}
}
public override void dispose() {
this._reset();
base.dispose();
}
void _reset() {
this._stopDoubleTapTimer();
if (this._firstTap != null) {
_TapTracker tracker = this._firstTap;
this._firstTap = null;
this._reject(tracker);
this._binding.gestureArena.release(tracker.pointer);
}
this._clearTrackers();
}
void _registerFirstTap(_TapTracker tracker) {
this._startDoubleTapTimer();
this._binding.gestureArena.hold(tracker.pointer);
this._freezeTracker(tracker);
this._trackers.Remove(tracker.pointer);
this._clearTrackers();
this._firstTap = tracker;
}
void _registerSecondTap(_TapTracker tracker) {
this._firstTap.entry.resolve(GestureDisposition.accepted);
tracker.entry.resolve(GestureDisposition.accepted);
this._freezeTracker(tracker);
this._trackers.Remove(tracker.pointer);
if (this.onDoubleTap != null) {
this.invokeCallback<object>("onDoubleTap", () => {
this.onDoubleTap();
return null;
});
}
this._reset();
}
void _clearTrackers() {
this._trackers.Values.ToList().Each(this._reject);
D.assert(this._trackers.isEmpty());
}
void _freezeTracker(_TapTracker tracker) {
tracker.stopTrackingPointer(this._handleEvent);
}
void _startDoubleTapTimer() {
this._doubleTapTimer =
this._doubleTapTimer
?? this._binding.window.run(Constants.kDoubleTapTimeout, this._reset);
}
void _stopDoubleTapTimer() {
if (this._doubleTapTimer != null) {
this._doubleTapTimer.cancel();
this._doubleTapTimer = null;
}
}
public override string debugDescription {
get { return "double tap"; }
}
}
}

3
Assets/UIWidgets/gestures/multitap.cs.meta


fileFormatVersion: 2
guid: 4b4742c47601461f8e406425d1cd5172
timeCreated: 1536418722

66
Assets/UIWidgets/gestures/pointer_router.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UnityEngine;
namespace UIWidgets.gestures {
public delegate void PointerRoute(PointerEvent evt);
public class PointerRouter {
readonly Dictionary<int, HashSet<PointerRoute>> _routeMap = new Dictionary<int, HashSet<PointerRoute>>();
readonly HashSet<PointerRoute> _globalRoutes = new HashSet<PointerRoute>();
public void addRoute(int pointer, PointerRoute route) {
var routes = this._routeMap.putIfAbsent(pointer, () => new HashSet<PointerRoute>());
D.assert(!routes.Contains(route));
routes.Add(route);
}
public void removeRoute(int pointer, PointerRoute route) {
D.assert(this._routeMap.ContainsKey(pointer));
var routes = this._routeMap[pointer];
routes.Remove(route);
if (routes.isEmpty()) {
this._routeMap.Remove(pointer);
}
}
public void addGlobalRoute(PointerRoute route) {
D.assert(!this._globalRoutes.Contains(route));
this._globalRoutes.Add(route);
}
public void removeGlobalRoute(PointerRoute route) {
D.assert(this._globalRoutes.Contains(route));
this._globalRoutes.Remove(route);
}
void _dispatch(PointerEvent evt, PointerRoute route) {
try {
route(evt);
}
catch (Exception ex) {
Debug.LogError("Error while routing a pointer event: " + ex);
}
}
public void route(PointerEvent evt) {
HashSet<PointerRoute> routes;
this._routeMap.TryGetValue(evt.pointer, out routes);
if (routes != null) {
foreach (PointerRoute route in new List<PointerRoute>(routes)) {
if (routes.Contains(route)) {
this._dispatch(evt, route);
}
}
}
foreach (PointerRoute route in new List<PointerRoute>(this._globalRoutes)) {
if (this._globalRoutes.Contains(route)) {
this._dispatch(evt, route);
}
}
}
}
}

3
Assets/UIWidgets/gestures/pointer_router.cs.meta


fileFormatVersion: 2
guid: 37ff4ce5ebb74851a0bf2e62f12d9c50
timeCreated: 1535604768

239
Assets/UIWidgets/gestures/recognizer.cs


using System;
using System.Collections.Generic;
using UIWidgets.async;
using UIWidgets.foundation;
using UIWidgets.ui;
using UnityEngine;
namespace UIWidgets.gestures {
public delegate T RecognizerCallback<T>();
public abstract class GestureRecognizer : DiagnosticableTree, GestureArenaMember {
protected GestureRecognizer(GestureBinding binding = null, object debugOwner = null) {
this._binding = binding;
this.debugOwner = debugOwner;
}
protected readonly GestureBinding _binding;
public readonly object debugOwner;
public abstract void addPointer(PointerDownEvent evt);
public virtual void dispose() {
}
public abstract string debugDescription { get; }
protected T invokeCallback<T>(string name, RecognizerCallback<T> callback, Func<string> debugReport = null) {
D.assert(callback != null);
T result = default(T);
try {
D.assert(() => {
if (D.debugPrintRecognizerCallbacksTrace) {
var report = debugReport != null ? debugReport() : null;
// The 19 in the line below is the width of the prefix used by
// _debugLogDiagnostic in arena.dart.
var prefix = D.debugPrintGestureArenaDiagnostics ? new string(' ', 19) + "❙ " : "";
Debug.LogFormat("{0}this calling {1} callback.{2}",
prefix, name, report.isNotEmpty() ? " " + report : "");
}
return true;
});
result = callback();
}
catch (Exception ex) {
Debug.LogError("Error while handling a gesture [" + name + "]: " + ex);
}
return result;
}
public abstract void acceptGesture(int pointer);
public abstract void rejectGesture(int pointer);
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<object>("debugOwner", this.debugOwner,
defaultValue: Diagnostics.kNullDefaultValue));
}
}
public abstract class OneSequenceGestureRecognizer : GestureRecognizer {
protected OneSequenceGestureRecognizer(
GestureBinding binding = null, object debugOwner = null) : base(binding, debugOwner) {
}
readonly Dictionary<int, GestureArenaEntry> _entries = new Dictionary<int, GestureArenaEntry>();
readonly HashSet<int> _trackedPointers = new HashSet<int>();
protected abstract void handleEvent(PointerEvent evt);
public override void acceptGesture(int pointer) {
}
public override void rejectGesture(int pointer) {
}
protected abstract void didStopTrackingLastPointer(int pointer);
protected virtual void resolve(GestureDisposition disposition) {
var localEntries = new List<GestureArenaEntry>(this._entries.Values);
this._entries.Clear();
foreach (GestureArenaEntry entry in localEntries) {
entry.resolve(disposition);
}
}
public override void dispose() {
this.resolve(GestureDisposition.rejected);
foreach (int pointer in this._trackedPointers) {
this._binding.pointerRouter.removeRoute(pointer, this.handleEvent);
}
this._trackedPointers.Clear();
D.assert(this._entries.isEmpty());
base.dispose();
}
public GestureArenaTeam team {
get { return this._team; }
set {
D.assert(value != null);
D.assert(this._entries.isEmpty());
D.assert(this._trackedPointers.isEmpty());
D.assert(this._team == null);
this._team = value;
}
}
GestureArenaTeam _team;
GestureArenaEntry _addPointerToArena(int pointer) {
if (this._team != null) {
return this._team.add(pointer, this);
}
return this._binding.gestureArena.add(pointer, this);
}
protected void startTrackingPointer(int pointer) {
this._binding.pointerRouter.addRoute(pointer, this.handleEvent);
this._trackedPointers.Add(pointer);
D.assert(!this._entries.ContainsKey(pointer));
this._entries[pointer] = this._addPointerToArena(pointer);
}
protected void stopTrackingPointer(int pointer) {
if (this._trackedPointers.Contains(pointer)) {
this._binding.pointerRouter.removeRoute(pointer, this.handleEvent);
this._trackedPointers.Remove(pointer);
if (this._trackedPointers.isEmpty()) {
this.didStopTrackingLastPointer(pointer);
}
}
}
protected void stopTrackingIfPointerNoLongerDown(PointerEvent evt) {
if (evt is PointerUpEvent || evt is PointerCancelEvent) {
this.stopTrackingPointer(evt.pointer);
}
}
}
public enum GestureRecognizerState {
ready,
possible,
defunct,
}
public abstract class PrimaryPointerGestureRecognizer : OneSequenceGestureRecognizer {
protected PrimaryPointerGestureRecognizer(
TimeSpan? deadline = null,
GestureBinding binding = null,
object debugOwner = null
) : base(binding: binding, debugOwner: debugOwner) {
this.deadline = deadline;
}
public readonly TimeSpan? deadline;
public GestureRecognizerState state = GestureRecognizerState.ready;
public int primaryPointer;
public Offset initialPosition;
Timer _timer;
public override void addPointer(PointerDownEvent evt) {
this.startTrackingPointer(evt.pointer);
if (this.state == GestureRecognizerState.ready) {
this.state = GestureRecognizerState.possible;
this.primaryPointer = evt.pointer;
this.initialPosition = evt.position;
if (this.deadline != null) {
this._timer = this._binding.window.run(this.deadline.Value, this.didExceedDeadline);
}
}
}
protected override void handleEvent(PointerEvent evt) {
D.assert(this.state != GestureRecognizerState.ready);
if (this.state == GestureRecognizerState.possible && evt.pointer == this.primaryPointer) {
if (evt is PointerMoveEvent && this._getDistance(evt) > Constants.kTouchSlop) {
this.resolve(GestureDisposition.rejected);
this.stopTrackingPointer(this.primaryPointer);
} else {
this.handlePrimaryPointer(evt);
}
}
this.stopTrackingIfPointerNoLongerDown(evt);
}
protected abstract void handlePrimaryPointer(PointerEvent evt);
protected virtual void didExceedDeadline() {
D.assert(this.deadline == null);
}
public override void rejectGesture(int pointer) {
if (pointer == this.primaryPointer && this.state == GestureRecognizerState.possible) {
this._stopTimer();
this.state = GestureRecognizerState.defunct;
}
}
protected override void didStopTrackingLastPointer(int pointer) {
this._stopTimer();
this.state = GestureRecognizerState.ready;
}
public override void dispose() {
this._stopTimer();
base.dispose();
}
void _stopTimer() {
if (this._timer != null) {
this._timer.cancel();
this._timer = null;
}
}
double _getDistance(PointerEvent evt) {
Offset offset = evt.position - this.initialPosition;
return offset.distance;
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new EnumProperty<GestureRecognizerState>("state", this.state));
}
}
}

3
Assets/UIWidgets/gestures/recognizer.cs.meta


fileFormatVersion: 2
guid: d4c72baa549e450abe95d694fbad1a7b
timeCreated: 1535606392

154
Assets/UIWidgets/gestures/tap.cs


using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.gestures {
public class TapDownDetails {
public TapDownDetails(Offset globalPosition = null) {
this.globalPosition = globalPosition ?? Offset.zero;
}
public readonly Offset globalPosition;
}
public delegate void GestureTapDownCallback(TapDownDetails details);
public class TapUpDetails {
public TapUpDetails(Offset globalPosition = null) {
this.globalPosition = globalPosition ?? Offset.zero;
}
public readonly Offset globalPosition;
}
public delegate void GestureTapUpCallback(TapUpDetails details);
public delegate void GestureTapCallback();
public delegate void GestureTapCancelCallback();
public class TapGestureRecognizer : PrimaryPointerGestureRecognizer {
public TapGestureRecognizer(GestureBinding binding, object debugOwner = null)
: base(deadline: Constants.kPressTimeout, binding: binding, debugOwner: debugOwner) {
}
public GestureTapDownCallback onTapDown;
public GestureTapUpCallback onTapUp;
public GestureTapCallback onTap;
public GestureTapCancelCallback onTapCancel;
bool _sentTapDown = false;
bool _wonArenaForPrimaryPointer = false;
Offset _finalPosition;
protected override void handlePrimaryPointer(PointerEvent evt) {
if (evt is PointerUpEvent) {
this._finalPosition = evt.position;
this._checkUp();
} else if (evt is PointerCancelEvent) {
this._reset();
}
}
protected override void resolve(GestureDisposition disposition) {
if (this._wonArenaForPrimaryPointer && disposition == GestureDisposition.rejected) {
if (this.onTapCancel != null) {
this.invokeCallback<object>("spontaneous onTapCancel", () => {
this.onTapCancel();
return null;
});
}
this._reset();
}
base.resolve(disposition);
}
protected override void didExceedDeadline() {
this._checkDown();
}
public override void acceptGesture(int pointer) {
base.acceptGesture(pointer);
if (pointer == this.primaryPointer) {
this._checkDown();
this._wonArenaForPrimaryPointer = true;
this._checkUp();
}
}
public override void rejectGesture(int pointer) {
base.rejectGesture(pointer);
if (pointer == this.primaryPointer) {
if (this.onTapCancel != null) {
this.invokeCallback<object>("forced onTapCancel", () => {
this.onTapCancel();
return null;
});
}
this._reset();
}
}
void _checkDown() {
if (!this._sentTapDown) {
if (this.onTapDown != null)
this.invokeCallback<object>("onTapDown", () => {
this.onTapDown(new TapDownDetails(globalPosition: this.initialPosition));
return null;
});
this._sentTapDown = true;
}
}
void _checkUp() {
if (this._wonArenaForPrimaryPointer && this._finalPosition != null) {
this.resolve(GestureDisposition.accepted);
if (!this._wonArenaForPrimaryPointer || this._finalPosition == null) {
return;
}
if (this.onTapUp != null)
this.invokeCallback<object>("onTapUp", () => {
this.onTapUp(new TapUpDetails(globalPosition: this._finalPosition));
return null;
});
if (this.onTap != null) {
this.invokeCallback<object>("onTap", () => {
this.onTap();
return null;
});
}
this._reset();
}
}
void _reset() {
this._sentTapDown = false;
this._wonArenaForPrimaryPointer = false;
this._finalPosition = null;
}
public override string debugDescription {
get { return "tap"; }
}
protected internal override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new FlagProperty("wonArenaForPrimaryPointer",
value: this._wonArenaForPrimaryPointer,
ifTrue: "won arena"));
properties.add(new DiagnosticsProperty<Offset>("finalPosition",
this._finalPosition, defaultValue: Diagnostics.kNullDefaultValue));
properties.add(new FlagProperty("sentTapDown",
value: this._sentTapDown, ifTrue: "sent tap down"));
}
}
}

3
Assets/UIWidgets/gestures/tap.cs.meta


fileFormatVersion: 2
guid: f6283d6471a24256ad84c37472dfe262
timeCreated: 1535608354

118
Assets/UIWidgets/gestures/team.cs


using System.Collections.Generic;
using UIWidgets.foundation;
namespace UIWidgets.gestures {
class _CombiningGestureArenaEntry : GestureArenaEntry {
public _CombiningGestureArenaEntry(_CombiningGestureArenaMember _combiner, GestureArenaMember _member) {
this._combiner = _combiner;
this._member = _member;
}
readonly _CombiningGestureArenaMember _combiner;
readonly GestureArenaMember _member;
public override void resolve(GestureDisposition disposition) {
this._combiner._resolve(this._member, disposition);
}
}
class _CombiningGestureArenaMember : GestureArenaMember {
public _CombiningGestureArenaMember(GestureArenaTeam _owner, int _pointer) {
this._owner = _owner;
this._pointer = _pointer;
}
readonly GestureArenaTeam _owner;
readonly List<GestureArenaMember> _members = new List<GestureArenaMember>();
readonly int _pointer;
bool _resolved = false;
GestureArenaMember _winner;
GestureArenaEntry _entry;
public void acceptGesture(int pointer) {
D.assert(this._pointer == pointer);
D.assert(this._winner != null || this._members.isNotEmpty());
this._close();
this._winner = this._winner ?? this._owner.captain ?? this._members[0];
foreach (GestureArenaMember member in this._members) {
if (member != this._winner) {
member.rejectGesture(pointer);
}
}
this._winner.acceptGesture(pointer);
}
public void rejectGesture(int pointer) {
D.assert(this._pointer == pointer);
this._close();
foreach (GestureArenaMember member in this._members) {
member.rejectGesture(pointer);
}
}
void _close() {
D.assert(!this._resolved);
this._resolved = true;
var combiner = this._owner._combiners[this._pointer];
D.assert(combiner == this);
this._owner._combiners.Remove(this._pointer);
}
internal GestureArenaEntry _add(int pointer, GestureArenaMember member) {
D.assert(!this._resolved);
D.assert(this._pointer == pointer);
this._members.Add(member);
this._entry = this._entry ?? this._owner._gestureArena.add(pointer, this);
return new _CombiningGestureArenaEntry(this, member);
}
internal void _resolve(GestureArenaMember member, GestureDisposition disposition) {
if (this._resolved) {
return;
}
if (disposition == GestureDisposition.rejected) {
this._members.Remove(member);
member.rejectGesture(this._pointer);
if (this._members.isEmpty()) {
this._entry.resolve(disposition);
}
} else {
this._winner = this._winner ?? this._owner.captain ?? member;
this._entry.resolve(disposition);
}
}
}
public class GestureArenaTeam {
public GestureArenaTeam(GestureArenaManager gestureArena) {
this._gestureArena = gestureArena;
}
internal readonly GestureArenaManager _gestureArena;
internal readonly Dictionary<int, _CombiningGestureArenaMember> _combiners =
new Dictionary<int, _CombiningGestureArenaMember>();
public GestureArenaMember captain;
public GestureArenaEntry add(int pointer, GestureArenaMember member) {
_CombiningGestureArenaMember combiner;
if (!this._combiners.TryGetValue(pointer, out combiner)) {
combiner = new _CombiningGestureArenaMember(this, pointer);
this._combiners[pointer] = combiner;
}
return combiner._add(pointer, member);
}
}
}

3
Assets/UIWidgets/gestures/team.cs.meta


fileFormatVersion: 2
guid: 7f4c3bdaf7be471ea5c3eeb4d7656d27
timeCreated: 1535593919

214
Assets/UIWidgets/gestures/velocity_tracker.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UIWidgets.ui;
namespace UIWidgets.gestures {
public class Velocity : IEquatable<Velocity> {
public Velocity(
Offset pixelsPerSecond = null
) {
this.pixelsPerSecond = pixelsPerSecond ?? Offset.zero;
}
public static readonly Velocity zero = new Velocity();
public readonly Offset pixelsPerSecond;
public static Velocity operator -(Velocity a) {
return new Velocity(pixelsPerSecond: -a.pixelsPerSecond);
}
public static Velocity operator -(Velocity a, Velocity b) {
return new Velocity(
pixelsPerSecond: a.pixelsPerSecond - b.pixelsPerSecond);
}
public static Velocity operator +(Velocity a, Velocity b) {
return new Velocity(
pixelsPerSecond: a.pixelsPerSecond + b.pixelsPerSecond);
}
public Velocity clampMagnitude(double minValue, double maxValue) {
D.assert(minValue >= 0.0);
D.assert(maxValue >= 0.0 && maxValue >= minValue);
double valueSquared = this.pixelsPerSecond.distanceSquared;
if (valueSquared > maxValue * maxValue) {
return new Velocity(pixelsPerSecond: (this.pixelsPerSecond / this.pixelsPerSecond.distance) * maxValue);
}
if (valueSquared < minValue * minValue) {
return new Velocity(pixelsPerSecond: (this.pixelsPerSecond / this.pixelsPerSecond.distance) * minValue);
}
return this;
}
public bool Equals(Velocity other) {
if (object.ReferenceEquals(null, other)) return false;
if (object.ReferenceEquals(this, other)) return true;
return object.Equals(this.pixelsPerSecond, other.pixelsPerSecond);
}
public override bool Equals(object obj) {
if (object.ReferenceEquals(null, obj)) return false;
if (object.ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return this.Equals((Velocity) obj);
}
public override int GetHashCode() {
return (this.pixelsPerSecond != null ? this.pixelsPerSecond.GetHashCode() : 0);
}
public static bool operator ==(Velocity left, Velocity right) {
return object.Equals(left, right);
}
public static bool operator !=(Velocity left, Velocity right) {
return !object.Equals(left, right);
}
public override string ToString() {
return string.Format("Velocity({0:F1}, {1:F1})", this.pixelsPerSecond.dx, this.pixelsPerSecond.dy);
}
}
public class VelocityEstimate {
public VelocityEstimate(
Offset pixelsPerSecond,
double confidence,
TimeSpan duration,
Offset offset
) {
D.assert(pixelsPerSecond != null);
D.assert(offset != null);
this.pixelsPerSecond = pixelsPerSecond;
this.confidence = confidence;
this.duration = duration;
this.offset = offset;
}
public readonly Offset pixelsPerSecond;
public readonly double confidence;
public readonly TimeSpan duration;
public readonly Offset offset;
public override string ToString() {
return string.Format("VelocityEstimate({0:F1}, {1:F1}; offset: {2}, duration: {3}, confidence: {4:F1})",
this.pixelsPerSecond.dx, this.pixelsPerSecond.dy, this.offset, this.duration, this.confidence);
}
}
class _PointAtTime {
internal _PointAtTime(Offset point, DateTime time) {
D.assert(point != null);
this.point = point;
this.time = time;
}
public readonly Offset point;
public readonly DateTime time;
public override string ToString() {
return string.Format("_PointAtTime({0} at {1})", this.point, this.time);
}
}
public class VelocityTracker {
const int _assumePointerMoveStoppedMilliseconds = 40;
const int _historySize = 20;
const int _horizonMilliseconds = 100;
const int _minSampleSize = 3;
readonly List<_PointAtTime> _samples = Enumerable.Repeat<_PointAtTime>(null, _historySize).ToList();
int _index = 0;
public void addPosition(DateTime time, Offset position) {
this._index += 1;
if (this._index == _historySize) {
this._index = 0;
}
this._samples[this._index] = new _PointAtTime(position, time);
}
public VelocityEstimate getVelocityEstimate() {
List<double> x = new List<double>();
List<double> y = new List<double>();
List<double> w = new List<double>();
List<double> time = new List<double>();
int sampleCount = 0;
int index = this._index;
_PointAtTime newestSample = this._samples[index];
if (newestSample == null) {
return null;
}
_PointAtTime previousSample = newestSample;
_PointAtTime oldestSample = newestSample;
do {
_PointAtTime sample = this._samples[index];
if (sample == null)
break;
double age = (newestSample.time - sample.time).TotalMilliseconds;
double delta = Math.Abs((sample.time - previousSample.time).TotalMilliseconds);
previousSample = sample;
if (age > _horizonMilliseconds || delta > _assumePointerMoveStoppedMilliseconds) {
break;
}
oldestSample = sample;
Offset position = sample.point;
x.Add(position.dx);
y.Add(position.dy);
w.Add(1.0);
time.Add(-age);
index = (index == 0 ? _historySize : index) - 1;
sampleCount += 1;
} while (sampleCount < _historySize);
if (sampleCount >= _minSampleSize) {
LeastSquaresSolver xSolver = new LeastSquaresSolver(time, x, w);
PolynomialFit xFit = xSolver.solve(2);
if (xFit != null) {
LeastSquaresSolver ySolver = new LeastSquaresSolver(time, y, w);
PolynomialFit yFit = ySolver.solve(2);
if (yFit != null) {
return new VelocityEstimate(
pixelsPerSecond: new Offset(xFit.coefficients[1] * 1000, yFit.coefficients[1] * 1000),
confidence: xFit.confidence * yFit.confidence,
duration: newestSample.time - oldestSample.time,
offset: newestSample.point - oldestSample.point
);
}
}
}
return new VelocityEstimate(
pixelsPerSecond: Offset.zero,
confidence: 1.0,
duration: newestSample.time - oldestSample.time,
offset: newestSample.point - oldestSample.point
);
}
public Velocity getVelocity() {
VelocityEstimate estimate = this.getVelocityEstimate();
if (estimate == null || estimate.pixelsPerSecond == Offset.zero) {
return Velocity.zero;
}
return new Velocity(pixelsPerSecond: estimate.pixelsPerSecond);
}
}
}

3
Assets/UIWidgets/gestures/velocity_tracker.cs.meta


fileFormatVersion: 2
guid: d01877db8a7341e491a67f84ed3ab604
timeCreated: 1536331325

51
Assets/UIWidgets/ui/pointer.cs


using System;
using System.Collections.Generic;
namespace UIWidgets.ui {
public enum PointerChange {
cancel,
add,
remove,
hover,
down,
move,
up,
}
public enum PointerDeviceKind {
touch,
mouse,
}
public class PointerData {
public PointerData(
DateTime timeStamp,
PointerChange change,
PointerDeviceKind kind,
int device,
double physicalX,
double physicalY) {
this.timeStamp = timeStamp;
this.change = change;
this.kind = kind;
this.device = device;
this.physicalX = physicalX;
this.physicalY = physicalY;
}
public readonly DateTime timeStamp;
public PointerChange change;
public PointerDeviceKind kind;
public int device;
public double physicalX;
public double physicalY;
}
public class PointerDataPacket {
public PointerDataPacket(List<PointerData> data) {
this.data = data;
}
public readonly List<PointerData> data;
}
}

3
Assets/UIWidgets/ui/pointer.cs.meta


fileFormatVersion: 2
guid: b5409a8bf1ca47a187b9a230dbcdcd98
timeCreated: 1536048980

73
Assets/UIWidgets/ui/txt/font_manager.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UIWidgets.ui
{
public class FontEntry
{
public readonly Font font;
private int _textureBuildVersion = 0;
public FontEntry(Font font)
{
this.font = font;
}
public int textureBuildVersion
{
get { return _textureBuildVersion; }
}
internal void onFontTextureRebuild()
{
_textureBuildVersion++;
}
}
public class FontManager
{
private List<FontEntry> _fonts = new List<FontEntry>();
public static readonly FontManager instance = new FontManager();
private FontManager()
{
Font.textureRebuilt += this.onFontTextureRebuilt;
}
public FontEntry getOrCreate(string[] names, int fontSize)
{
var founded = _fonts.Find((font) =>
(
font.font.fontSize == fontSize &&
(names == font.font.fontNames || (names != null && names.SequenceEqual(font.font.fontNames)))));
if (founded != null)
{
return founded;
}
Debug.Log(string.Format("Create new Font names={0}, size={1}", names, fontSize));
var newFont = new FontEntry(Font.CreateDynamicFontFromOSFont(names,
fontSize));
_fonts.Add(newFont);
return newFont;
}
public FontEntry getOrCreate(string name, int fontSize)
{
return getOrCreate(new []{name}, fontSize);
}
private void onFontTextureRebuilt(Font font)
{
var entry = _fonts.Find((f) => f.font == font);
if (entry != null)
{
entry.onFontTextureRebuild();
}
}
}
}

3
Assets/UIWidgets/ui/txt/font_manager.cs.meta


fileFormatVersion: 2
guid: b643b1d2b3f14560bfa4b97bfdb7422a
timeCreated: 1536220942

119
Assets/UIWidgets/ui/txt/mesh.cs


using UnityEngine;
namespace UIWidgets.ui
{
public class TextMesh: IMesh
{
private Mesh _mesh;
private FontEntry _fontEntry;
private string _text;
private StyledRuns.Run _run;
private int _textureVersion;
public TextMesh(Vector2d pos, string text, Vector2d[] _characterPositions, FontEntry fontEntry, StyledRuns.Run run)
{
_fontEntry = fontEntry;
_text = text;
this._run = run;
var vertices = new Vector3[_text.Length * 4];
var triangles = new int[_text.Length * 6];
var font = fontEntry.font;
var offset = new Vector3((float)Utils.PixelCorrectRound(pos.x), (float)Utils.PixelCorrectRound(pos.y), 0);
font.RequestCharactersInTexture(_text.Substring(_run.start, _run.end - _run.start),
_run.style.UnityFontSize, _run.style.UnityFontStyle);
for (int charIndex = _run.start; charIndex < _run.end; ++charIndex)
{
CharacterInfo charInfo = new CharacterInfo();
if (_text[charIndex] != '\n' && _text[charIndex] != '\t')
{
Debug.Assert(font.GetCharacterInfo(_text[charIndex], out charInfo, _run.style.UnityFontSize, _run.style.UnityFontStyle));
var position = _characterPositions[charIndex];
vertices[4 * charIndex + 0] = offset + new Vector3((float)(position.x + charInfo.minX),
(float)(position.y - charInfo.maxY), 0);
vertices[4 * charIndex + 1] = offset + new Vector3((float)(position.x + charInfo.maxX),
(float)(position.y - charInfo.maxY), 0);
vertices[4 * charIndex + 2] = offset + new Vector3(
(float)(position.x + charInfo.maxX), (float)(position.y - charInfo.minY), 0);
vertices[4 * charIndex + 3] = offset + new Vector3(
(float)(position.x + charInfo.minX), (float)(position.y - charInfo.minY), 0);
}
else
{
vertices[4 * charIndex + 0] = vertices[4 * charIndex + 1] =
vertices[4 * charIndex + 2] = vertices[4 * charIndex + 3] = offset;
}
triangles[6 * charIndex + 0] = 4 * charIndex + 0;
triangles[6 * charIndex + 1] = 4 * charIndex + 1;
triangles[6 * charIndex + 2] = 4 * charIndex + 2;
triangles[6 * charIndex + 3] = 4 * charIndex + 0;
triangles[6 * charIndex + 4] = 4 * charIndex + 2;
triangles[6 * charIndex + 5] = 4 * charIndex + 3;
}
var uv = getTextureUV();
var mesh = new Mesh()
{
vertices = vertices,
triangles = triangles,
uv = uv
};
var colors = new UnityEngine.Color[vertices.Length];
for (var i = 0; i < colors.Length; i++)
{
colors[i] = _run.style.UnityColor;
}
mesh.colors = colors;
_textureVersion = _fontEntry.textureBuildVersion;
_mesh = mesh;
}
public void syncTextureUV()
{
if (_fontEntry.textureBuildVersion != _textureVersion) // texture has been rebuilt, update the texture uv
{
_mesh.uv = getTextureUV();
}
}
public Mesh mesh
{
get { return _mesh; }
}
private Vector2[] getTextureUV()
{
var font = _fontEntry.font;
var uv = _mesh == null ? new Vector2[_text.Length * 4] : _mesh.uv;
for (int charIndex = _run.start; charIndex < _run.end; ++charIndex)
{
CharacterInfo charInfo = new CharacterInfo();
if (_text[charIndex] != '\n' && _text[charIndex] != '\t')
{
font.GetCharacterInfo(_text[charIndex], out charInfo, _run.style.UnityFontSize,
_run.style.UnityFontStyle);
}
if (Paragraph.isWordSpace(_text[charIndex]) || Paragraph.isLineEndSpace(_text[charIndex]) || _text[charIndex] == '\t')
{
uv[4 * charIndex + 0] = Vector2.zero;
uv[4 * charIndex + 1] = Vector2.zero;
uv[4 * charIndex + 2] = Vector2.zero;
uv[4 * charIndex + 3] = Vector2.zero;
} else
{
uv[4 * charIndex + 0] = charInfo.uvTopLeft;
uv[4 * charIndex + 1] = charInfo.uvTopRight;
uv[4 * charIndex + 2] = charInfo.uvBottomRight;
uv[4 * charIndex + 3] = charInfo.uvBottomLeft;
}
}
return uv;
}
}
}

3
Assets/UIWidgets/ui/txt/mesh.cs.meta


fileFormatVersion: 2
guid: 96ec1d4b2b7d4bf59d4b2db221323ae9
timeCreated: 1536283931

13
Assets/UIWidgets/ui/txt/utils.cs


using System;
using UnityEditor;
namespace UIWidgets.ui
{
internal class Utils
{
public static double PixelCorrectRound(double v)
{
return Math.Round(v * EditorGUIUtility.pixelsPerPoint) / EditorGUIUtility.pixelsPerPoint;
}
}
}

3
Assets/UIWidgets/ui/txt/utils.cs.meta


fileFormatVersion: 2
guid: cd4e5380cbc9438a8d2c8a060b110ea1
timeCreated: 1536199372

26
Assets/UIWidgets/async/microtask_queue.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UnityEngine;
namespace UIWidgets.async {
public class MicrotaskQueue {
private Queue<Action> _queue = new Queue<Action>();
public void scheduleMicrotask(Action action) {
this._queue.Enqueue(action);
}
public void flushMicrotasks() {
while (this._queue.isNotEmpty()) {
var action = this._queue.Dequeue();
try {
action();
}
catch (Exception ex) {
Debug.LogError("Error to execute microtask: " + ex);
}
}
}
}
}

3
Assets/UIWidgets/async/microtask_queue.cs.meta


fileFormatVersion: 2
guid: 6d95e65550134a478f8f77093fc6d6f1
timeCreated: 1535723558

105
Assets/UIWidgets/async/priority_queue.cs


using System;
using System.Collections.Generic;
namespace UIWidgets.async {
public class PriorityQueue<T> where T : IComparable<T> {
private readonly List<T> _data;
public PriorityQueue() {
this._data = new List<T>();
}
public void enqueue(T item) {
this._data.Add(item);
int ci = this._data.Count - 1; // child index; start at end
while (ci > 0) {
int pi = (ci - 1) / 2; // parent index
if (this._data[ci].CompareTo(this._data[pi]) >= 0) {
break; // child item is larger than (or equal) parent so we're done
}
T tmp = this._data[ci];
this._data[ci] = this._data[pi];
this._data[pi] = tmp;
ci = pi;
}
}
public T dequeue() {
// assumes pq is not empty; up to calling code
int li = this._data.Count - 1; // last index (before removal)
T frontItem = this._data[0]; // fetch the front
this._data[0] = this._data[li];
this._data.RemoveAt(li);
--li; // last index (after removal)
int pi = 0; // parent index. start at front of pq
while (true) {
int ci = pi * 2 + 1; // left child index of parent
if (ci > li) {
break; // no children so done
}
int rc = ci + 1; // right child
if (rc <= li && this._data[rc].CompareTo(this._data[ci]) < 0) {
// if there is a rc (ci + 1), and it is smaller than left child, use the rc instead
ci = rc;
}
if (this._data[pi].CompareTo(this._data[ci]) <= 0) {
break; // parent is smaller than (or equal to) smallest child so done
}
T tmp = this._data[pi];
this._data[pi] = this._data[ci];
this._data[ci] = tmp; // swap parent and child
pi = ci;
}
return frontItem;
}
public T peek() {
T frontItem = this._data[0];
return frontItem;
}
public int count {
get { return this._data.Count; }
}
public override string ToString() {
string s = "";
for (int i = 0; i < this._data.Count; ++i) {
s += this._data[i] + " ";
}
s += "count = " + this._data.Count;
return s;
}
public bool isConsistent() {
// is the heap property true for all data?
if (this._data.Count == 0) {
return true;
}
int li = this._data.Count - 1; // last index
for (int pi = 0; pi < this._data.Count; ++pi) {
// each parent index
int lci = 2 * pi + 1; // left child index
int rci = 2 * pi + 2; // right child index
if (lci <= li && this._data[pi].CompareTo(this._data[lci]) > 0) {
return false; // if lc exists and it's greater than parent then bad.
}
if (rci <= li && this._data[pi].CompareTo(this._data[rci]) > 0) {
return false; // check the right child too.
}
}
return true; // passed all checks
}
}
}

3
Assets/UIWidgets/async/priority_queue.cs.meta


fileFormatVersion: 2
guid: 2d77ab33460640ddb5e3abbb2a11da34
timeCreated: 1536040675

67
Assets/UIWidgets/async/timer.cs


using System;
using UnityEngine;
namespace UIWidgets.async {
public abstract class Timer {
public abstract void cancel();
}
public class TimerProvider {
private readonly PriorityQueue<TimerImpl> _queue;
public TimerProvider() {
this._queue = new PriorityQueue<TimerImpl>();
}
public Timer run(TimeSpan duration, Action callback) {
var timer = new TimerImpl(DateTime.Now + duration, callback);
this._queue.enqueue(timer);
return timer;
}
public void update() {
var now = DateTime.Now;
while (this._queue.count > 0 && this._queue.peek().deadline <= now) {
var timer = this._queue.dequeue();
timer.invoke();
}
}
private class TimerImpl : Timer, IComparable<TimerImpl> {
public readonly DateTime deadline;
private readonly Action _callback;
private bool _done;
public TimerImpl(DateTime deadline, Action callback) {
this.deadline = deadline;
this._callback = callback;
this._done = false;
}
public override void cancel() {
this._done = true;
}
public void invoke() {
if (this._done) {
return;
}
this._done = true;
try {
this._callback();
}
catch (Exception ex) {
Debug.LogError("Error to execute timer callback: " + ex);
}
}
public int CompareTo(TimerImpl other) {
return this.deadline.CompareTo(other.deadline);
}
}
}
}

11
Assets/UIWidgets/async/timer.cs.meta


fileFormatVersion: 2
guid: 22e7b4cca5d354a4e9aa008cafcfdfe8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存