浏览代码

image prototype

/main
gewentao 6 年前
当前提交
389e013b
共有 43 个文件被更改,包括 4031 次插入24 次删除
  1. 71
      Assets/UIWidgets/Tests/CanvasAndLayers.cs
  2. 25
      Assets/UIWidgets/painting/binding.cs
  3. 18
      Assets/UIWidgets/painting/box_border.cs
  4. 147
      Assets/UIWidgets/painting/decoration_image.cs
  5. 23
      Assets/UIWidgets/rendering/box.cs
  6. 8
      Assets/UIWidgets/ui/geometry.cs
  7. 12
      Assets/UIWidgets/ui/painting/canvas.cs
  8. 10
      Assets/UIWidgets/ui/painting/canvas_impl.cs
  9. 8
      Assets/UIWidgets/ui/painting/draw_cmd.cs
  10. 89
      Assets/UIWidgets/ui/painting/painting.cs
  11. 4
      Assets/UIWidgets/ui/painting/picture.cs
  12. 182
      Assets/UIWidgets/painting/alignment.cs
  13. 3
      Assets/UIWidgets/painting/alignment.cs.meta
  14. 130
      Assets/UIWidgets/painting/box_fit.cs
  15. 3
      Assets/UIWidgets/painting/box_fit.cs.meta
  16. 168
      Assets/UIWidgets/painting/image_cache.cs
  17. 3
      Assets/UIWidgets/painting/image_cache.cs.meta
  18. 109
      Assets/UIWidgets/painting/image_provider.cs
  19. 3
      Assets/UIWidgets/painting/image_provider.cs.meta
  20. 135
      Assets/UIWidgets/painting/image_stream.cs
  21. 3
      Assets/UIWidgets/painting/image_stream.cs.meta
  22. 8
      Assets/UIWidgets/promise.meta
  23. 281
      Assets/UIWidgets/rendering/image.cs
  24. 3
      Assets/UIWidgets/rendering/image.cs.meta
  25. 21
      Assets/UIWidgets/ui/painting/image.cs
  26. 3
      Assets/UIWidgets/ui/painting/image.cs.meta
  27. 41
      Assets/UIWidgets/promise/EnumerableExt.cs
  28. 3
      Assets/UIWidgets/promise/EnumerableExt.cs.meta
  29. 1001
      Assets/UIWidgets/promise/Promise.cs
  30. 3
      Assets/UIWidgets/promise/Promise.cs.meta
  31. 19
      Assets/UIWidgets/promise/PromiseException.cs
  32. 3
      Assets/UIWidgets/promise/PromiseException.cs.meta
  33. 82
      Assets/UIWidgets/promise/PromiseHelpers.cs
  34. 3
      Assets/UIWidgets/promise/PromiseHelpers.cs.meta
  35. 22
      Assets/UIWidgets/promise/PromiseStateException.cs
  36. 3
      Assets/UIWidgets/promise/PromiseStateException.cs.meta
  37. 247
      Assets/UIWidgets/promise/PromiseTimer.cs
  38. 3
      Assets/UIWidgets/promise/PromiseTimer.cs.meta
  39. 1001
      Assets/UIWidgets/promise/Promise_NonGeneric.cs
  40. 3
      Assets/UIWidgets/promise/Promise_NonGeneric.cs.meta
  41. 148
      Assets/UIWidgets/promise/Tuple.cs
  42. 3
      Assets/UIWidgets/promise/Tuple.cs.meta

71
Assets/UIWidgets/Tests/CanvasAndLayers.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.painting;
using UIWidgets.ui;

private readonly string[] _optionStrings;
private int _selected;
private PaintingBinding paintingBinding;
private ImageStream _stream;
this.drawImageRect,
this.drawPicture,
this.clipRect,
this.clipRRect,

void OnGUI() {
this._selected = EditorGUILayout.Popup("test case", this._selected, this._optionStrings);
if (_selected == 3)
{
if (GUI.Button(new UnityEngine.Rect(20, 50, 100, 20), "Image 1"))
{
_stream =
LoadImage(
"http://a.hiphotos.baidu.com/image/h%3D300/sign=10b374237f0e0cf3bff748fb3a47f23d/adaf2edda3cc7cd90df1ede83401213fb80e9127.jpg");
}
if (GUI.Button(new UnityEngine.Rect(20, 150, 100, 20), "Image 2"))
{
_stream =
LoadImage(
"http://a.hiphotos.baidu.com/image/pic/item/cf1b9d16fdfaaf519b4aa960875494eef11f7a47.jpg");
}
if (GUI.Button(new UnityEngine.Rect(20, 250, 100, 20), "Image 3"))
{
_stream =
LoadImage(
"http://a.hiphotos.baidu.com/image/pic/item/2f738bd4b31c8701c1e721dd2a7f9e2f0708ffbc.jpg");
}
}
Debug.Log("currentSize: " + PaintingBinding.instance.imageCache.currentSize);
Debug.Log("currentSizeBytes: " + PaintingBinding.instance.imageCache.currentSizeBytes);
Debug.Log("maxSizeBytes: " + PaintingBinding.instance.imageCache.maximumSizeBytes);
}
private void OnEnable() {
this.paintingBinding = new PaintingBinding();
paintingBinding.initInstances();
}
private ImageStream LoadImage(string url)
{
Dictionary<string, string> headers = new Dictionary<string, string>();
NetworkImage networkImage = new NetworkImage(url, headers);
ImageConfiguration imageConfig = new ImageConfiguration();
var stream = networkImage.resolve(imageConfig);
return stream;
}
void drawPloygon4() {

editorCanvas.drawPicture(picture);
}
void clipRect() {
void drawImageRect()
{
if (_stream == null)
{
return;
}
var canvas = new CanvasImpl();
var paint = new Paint
{
color = new Color(0xFFFF0000),
};
canvas.drawImageRect(
Rect.fromLTWH(150, 50, 250, 250),
Rect.fromLTWH(150, 50, 250, 250),
paint,
_stream
);
}
void clipRect()
{
var pictureRecorder = new PictureRecorder();
var canvas = new RecorderCanvas(pictureRecorder);

25
Assets/UIWidgets/painting/binding.cs


namespace UIWidgets.painting {
public abstract class PaintingBinding {
public class PaintingBinding
{
private static PaintingBinding _instance;
public static PaintingBinding instance
{
get { return _instance; }
}
private ImageCache _imageCache;
public ImageCache imageCache
{
get { return _imageCache; }
}
public ImageCache createImageCache()
{
return new ImageCache();
}
public void initInstances() {
_instance = this;
_imageCache = createImageCache();
}
}
}

18
Assets/UIWidgets/painting/box_border.cs


}
}
}
public class ImageConfiguration {
public ImageConfiguration(Size size = null) {
this.size = size;
}
public static readonly ImageConfiguration empty = new ImageConfiguration();
public ImageConfiguration copyWith(
Size size = null) {
return new ImageConfiguration(
size: size ?? this.size
);
}
public readonly Size size;
}
}

147
Assets/UIWidgets/painting/decoration_image.cs


using System;
using UIWidgets.ui;
using System.Collections.Generic;
namespace UIWidgets.painting
{
/// How to paint any portions of a box not covered by an image.
public enum ImageRepeat
{
/// Repeat the image in both the x and y directions until the box is filled.
repeat,
namespace UIWidgets.painting {
public class DecorationImage {
/// Repeat the image in the x direction until the box is filled horizontally.
repeatX,
/// Repeat the image in the y direction until the box is filled vertically.
repeatY,
/// Leave uncovered portions of the box transparent.
noRepeat,
}
public class DecorationImage
{
public DecorationImage()
{
}
}
public static class DecorationImageUtil
{
public static void paintImage(Canvas canvas, Rect rect, ui.Image image, BoxFit fit, Rect centerSlice, Alignment alignment = null,
ImageRepeat repeat = ImageRepeat.noRepeat, bool flipHorizontally = false) // todo more parameters
{
if (rect.isEmpty)
return;
alignment = alignment ?? Alignment.center;
Size outputSize = rect.size;
Size inputSize = new Size(image.width, image.height);
Offset sliceBorder = null;
if (centerSlice != null)
{
sliceBorder = new Offset(
centerSlice.left + inputSize.width - centerSlice.right,
centerSlice.top + inputSize.height - centerSlice.bottom
);
outputSize -= sliceBorder;
inputSize -= sliceBorder;
}
fit = centerSlice == null ? BoxFit.scaleDown : BoxFit.fill;
FittedSizes fittedSizes = FittedSizes.applyBoxFit(fit, inputSize, outputSize);
Size sourceSize = fittedSizes.source;
Size destinationSize = fittedSizes.destination;
if (centerSlice != null)
{
outputSize += sliceBorder;
destinationSize += sliceBorder;
}
if (repeat != ImageRepeat.noRepeat && destinationSize == outputSize) {
repeat = ImageRepeat.noRepeat;
}
Paint paint = new Paint(); // ..isAntiAlias = false;
// if (colorFilter != null)
// paint.colorFilter = colorFilter;
if (sourceSize != destinationSize) {
// Use the "low" quality setting to scale the image, which corresponds to
// bilinear interpolation, rather than the default "none" which corresponds
// to nearest-neighbor.
// paint.filterQuality = FilterQuality.low;
}
double halfWidthDelta = (outputSize.width - destinationSize.width) / 2.0;
double halfHeightDelta = (outputSize.height - destinationSize.height) / 2.0;
double dx = halfWidthDelta + (flipHorizontally ? - alignment.x : alignment.x) * halfWidthDelta;
double dy = halfHeightDelta + alignment.y * halfHeightDelta;
Offset destinationPosition = rect.topLeft.translate(dx, dy);
Rect destinationRect = destinationPosition & destinationSize;
// todo repeat and flip
// bool needSave = repeat != ImageRepeat.noRepeat || flipHorizontally;
// if (needSave)
// canvas.save();
// if (repeat != ImageRepeat.noRepeat)
// canvas.clipRect(rect);
// if (flipHorizontally) {
// dx = -(rect.left + rect.width / 2.0);
// canvas.translate(-dx, 0.0);
// canvas.scale(-1.0, 1.0);
// canvas.translate(dx, 0.0);
// }
if (centerSlice == null) {
Rect sourceRect = alignment.inscribe(
fittedSizes.source, Offset.zero & inputSize
);
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) {
// canvas.drawImageRect(sourceRect, tileRect, paint, image);
}
} else {
// todo
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat))
{
// canvas.drawImageNine(image, centerSlice, tileRect, paint);
}
}
// if (needSave)
// canvas.restore();
}
public static List<Rect> _generateImageTileRects(Rect outputRect, Rect fundamentalRect,
ImageRepeat repeat)
{
List<Rect> tileRects = new List<Rect>();
if (repeat == ImageRepeat.noRepeat)
{
tileRects.Add(fundamentalRect);
return tileRects;
}
int startX = 0;
int startY = 0;
int stopX = 0;
int stopY = 0;
double strideX = fundamentalRect.width;
double strideY = fundamentalRect.height;
if (repeat == ImageRepeat.repeat || repeat == ImageRepeat.repeatX)
{
startX = (int) Math.Floor((outputRect.left - fundamentalRect.left) / strideX);
stopX = (int) Math.Ceiling((outputRect.right - fundamentalRect.right) / strideX);
}
if (repeat == ImageRepeat.repeat || repeat == ImageRepeat.repeatY)
{
startY = (int) Math.Floor((outputRect.top - fundamentalRect.top) / strideY);
stopY = (int) Math.Ceiling((outputRect.bottom - fundamentalRect.bottom) / strideY);
}
for (int i = startX; i <= stopX; ++i)
{
for (int j = startY; j <= stopY; ++j)
tileRects.Add(fundamentalRect.shift(new Offset(i * strideX, j * strideY)));
// yield return fundamentalRect.shift(new Offset(i * strideX, j * strideY));
}
return tileRects;
}
}
}

23
Assets/UIWidgets/rendering/box.cs


);
}
public BoxConstraints widthConstraints() {
public static BoxConstraints tightFor(double width, double height)
{
return new BoxConstraints(
width,
width,
height,
height
);
}
public BoxConstraints enforce(BoxConstraints constraints) {
return new BoxConstraints(
// may lose precision here
Mathf.Clamp((float)this.minWidth, (float)constraints.minWidth, (float)constraints.maxWidth),
Mathf.Clamp((float)this.minWidth, (float)constraints.minWidth, (float)constraints.maxWidth),
Mathf.Clamp((float)this.minHeight, (float)constraints.minWidth, (float)constraints.maxWidth),
Mathf.Clamp((float)this.maxHeight, (float)constraints.minHeight, (float)constraints.maxHeight)
);
}
public BoxConstraints widthConstraints()
{
return new BoxConstraints(minWidth: this.minWidth, maxWidth: this.maxWidth);
}

8
Assets/UIWidgets/ui/geometry.cs


public bool isEmpty {
get { return this.width <= 0.0 || this.height <= 0.0; }
}
public static Size operator -(Size a, Offset b) {
return new Size(a.width - b.dx, a.height - b.dy);
}
public static Size operator +(Size a, Offset b) {
return new Size(a.width + b.dx, a.height + b.dy);
}
public static Size operator *(Size a, double operand) {
return new Size(a.width * operand, a.height * operand);

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


void drawPicture(Picture picture);
void drawImageRect(Rect src, Rect dst, Paint paint, ImageStream stream);
void concat(Matrix4x4 transform);
void save();

public void drawPicture(Picture picture) {
this._recorder.addDrawCmd(new DrawPicture {
picture = picture,
});
}
public void drawImageRect(Rect src, Rect dst, Paint paint, ImageStream stream)
{
this._recorder.addDrawCmd(new DrawImageRect
{
stream = stream,
src = src,
dst = dst,
});
}

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


this.restore();
}
public void drawImageRect(Rect src, Rect dst, Paint paint, ImageStream stream)
{
if (stream.completer._currentImgae != null)
{
Texture2D _texture = new Texture2D(0, 0);
_texture.LoadImage(stream.completer._currentImgae.image.rawData);
Graphics.DrawTexture(dst.toRect(), _texture);
}
}
public void concat(Matrix4x4 transform) {
this._transform = transform * this._transform;
}

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


using UIWidgets.painting;
using UnityEngine;
using UnityEngine.UI;
namespace UIWidgets.ui {
public interface DrawCmd {

public class DrawPicture : DrawCmd {
public Picture picture;
}
public class DrawImageRect : DrawCmd
{
public ImageStream stream;
public Rect src;
public Rect dst;
}
public class DrawConcat : DrawCmd {

89
Assets/UIWidgets/ui/painting/painting.cs


};
}
}
// public class GUICanvas : Canvas {
// static GUICanvas() {
// GUICanvas.shadowMat = Resources.Load<Material>("UIWidgets_ShadowMat");
// if (GUICanvas.shadowMat == null) {
// throw new Exception("UIWidgets_ShadowShader not found");
// }
// }
//
// public static readonly Material shadowMat;
//
// public override void drawPloygon4(Paint paint, params Offset[] points) {
// Vector3[] vectors = new Vector3 [points.Length];
// for (int i = 0; i < points.Length; i++) {
// vectors[i] = points[i].toVector();
// }
//
// Handles.DrawSolidRectangleWithOutline(vectors, paint.color.toColor(),
// new UnityEngine.Color(0f, 0f, 0f, 0f));
// }
//
// public override void drawRect(Paint paint, Rect rect, BorderWidth borderWidth, BorderRadius borderRadius) {
// GUI.DrawTexture(rect.toRect(), EditorGUIUtility.whiteTexture, ScaleMode.StretchToFill, true, 0,
// paint.color.toColor(), borderWidth.toVector(), borderRadius.toVector());
// }
//
// public override void drawRectShadow(Paint paint, Rect rect) {
// GUICanvas.shadowMat.SetFloatArray("_Rect", new float[] {
// (float) rect.left, (float) rect.top, (float) rect.width, (float) rect.height,
// });
// GUICanvas.shadowMat.SetFloat("_sigma", (float) paint.blurSigma);
//
// Graphics.DrawTexture(rect.toRect(), EditorGUIUtility.whiteTexture,
// new UnityEngine.Rect(0.0f, 0.0f, 1f, 1f), 0, 0, 0, 0, paint.color.toColor(), GUICanvas.shadowMat);
// }
// }
public class ColorFilter
{
public ColorFilter(Color color, BlendMode blendMode)
{
_color = color;
_blendMode = blendMode;
}
Color _color;
BlendMode _blendMode;
// public static bool operator ==(ColorFilter a, dynamic other) {
// if (other is! ColorFilter)
// return false;
// ColorFilter typedOther = other;
// return a._color == typedOther._color &&
// a._blendMode == typedOther._blendMode;
// }
}
public enum BlendMode
{
None = 0, // explicitly assign zero to make it more clear
clear,
src,
dst,
dstOver,
srcIn,
dstIn,
srcOut,
dstOut,
srcATop,
dstATop,
xor,
plus,
modulate,
screen, // The last coeff mode.
overlay,
darken,
lighten,
colorDodge,
colorBurn,
hardLight,
softLight,
difference,
exclusion,
multiply, // The last separable mode.
hue,
saturation,
color,
luminosity,
}
}

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


} else if (drawCmd is DrawPicture) {
var drawPicture = (DrawPicture) drawCmd;
this.addPaintBounds(drawPicture.picture.paintBounds);
} else if (drawCmd is DrawImageRect)
{
var drawImageRect = (DrawImageRect) drawCmd;
// todo
} else if (drawCmd is DrawConcat) {
this._transform = ((DrawConcat) drawCmd).transform * this._transform;
} else if (drawCmd is DrawSave) {

182
Assets/UIWidgets/painting/alignment.cs


using UIWidgets.ui;
namespace UIWidgets.painting
{
// todo should be in text.cs
public enum TextDirection
{
/// The text flows from right to left (e.g. Arabic, Hebrew).
rtl,
/// The text flows from left to right (e.g., English, French).
ltr,
}
public abstract class AlignmentGeometry
{
public AlignmentGeometry()
{
}
public abstract double x { get; }
public abstract double start { get; }
public abstract double y { get; }
AlignmentGeometry add(AlignmentGeometry other)
{
return new _MixedAlignment(
x + other.x,
start + other.start,
y + other.y
);
}
public virtual Alignment resolve(TextDirection direction)
{
return null;
}
}
public class Alignment : AlignmentGeometry
{
public Alignment(double x, double y)
{
this._x = x;
this._y = y;
}
private readonly double _x;
public override double x
{
get { return _x; }
}
private readonly double _y;
public override double y
{
get { return _y; }
}
public override double start
{
get { return 0.0; }
}
public static readonly Alignment topLeft = new Alignment(-1.0, -1.0);
public static readonly Alignment topCenter = new Alignment(0.0, -1.0);
public static readonly Alignment topRight = new Alignment(1.0, -1.0);
public static readonly Alignment centerLeft = new Alignment(-1.0, 0.0);
public static readonly Alignment center = new Alignment(0.0, 0.0);
public static readonly Alignment centerRight = new Alignment(1.0, 0.0);
public static readonly Alignment bottomLeft = new Alignment(-1.0, 1.0);
public static readonly Alignment bottomCenter = new Alignment(0.0, 1.0);
public static readonly Alignment bottomRight = new Alignment(1.0, 1.0);
public static Alignment operator -(Alignment a, Alignment b)
{
return new Alignment(a._x - b._x, a._y - b._y);
}
// todo more operators
public override Alignment resolve(TextDirection direction)
{
return this;
}
public Rect inscribe(Size size, Rect rect)
{
double halfWidthDelta = (rect.width - size.width) / 2.0;
double halfHeightDelta = (rect.height - size.height) / 2.0;
return Rect.fromLTWH(
rect.left + halfWidthDelta + _x * halfWidthDelta,
rect.top + halfHeightDelta + _y * halfHeightDelta,
size.width,
size.height
);
}
}
public class _MixedAlignment : AlignmentGeometry
{
public _MixedAlignment(double x, double start, double y)
{
this._x = x;
this._start = start;
this._y = y;
}
private readonly double _x;
public override double x
{
get { return _x; }
}
private readonly double _start;
public override double start
{
get { return _start; }
}
private readonly double _y;
public override double y
{
get { return _y; }
}
public static _MixedAlignment operator -(_MixedAlignment a)
{
return new _MixedAlignment(
-a._x,
-a._start,
-a._y
);
}
public static _MixedAlignment operator *(_MixedAlignment a, double other)
{
return new _MixedAlignment(
a._x * other,
a._start * other,
a._y * other
);
}
public static _MixedAlignment operator /(_MixedAlignment a, double other)
{
return new _MixedAlignment(
a._x / other,
a._start / other,
a._y / other
);
}
public static _MixedAlignment operator %(_MixedAlignment a, double other)
{
return new _MixedAlignment(
a._x % other,
a._start % other,
a._y % other
);
}
public override Alignment resolve(TextDirection direction)
{
switch (direction)
{
case TextDirection.rtl:
return new Alignment(_x - _start, _y);
case TextDirection.ltr:
return new Alignment(_x + _start, _y);
}
return null;
}
}
}

3
Assets/UIWidgets/painting/alignment.cs.meta


fileFormatVersion: 2
guid: 52b90656e86c4a39af38d0518a67f68b
timeCreated: 1534820611

130
Assets/UIWidgets/painting/box_fit.cs


using UIWidgets.ui;
using System;
namespace UIWidgets.painting
{
public enum BoxFit
{
/// Fill the target box by distorting the source's aspect ratio.
///
/// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_fill.png)
fill,
/// As large as possible while still containing the source entirely within the
/// target box.
///
/// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_contain.png)
contain,
/// As small as possible while still covering the entire target box.
///
/// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_cover.png)
cover,
/// Make sure the full width of the source is shown, regardless of
/// whether this means the source overflows the target box vertically.
///
/// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_fitWidth.png)
fitWidth,
/// Make sure the full height of the source is shown, regardless of
/// whether this means the source overflows the target box horizontally.
///
/// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_fitHeight.png)
fitHeight,
/// Align the source within the target box (by default, centering) and discard
/// any portions of the source that lie outside the box.
///
/// The source image is not resized.
///
/// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_none.png)
none,
/// Align the source within the target box (by default, centering) and, if
/// necessary, scale the source down to ensure that the source fits within the
/// box.
///
/// This is the same as `contain` if that would shrink the image, otherwise it
/// is the same as `none`.
///
/// ![](https://flutter.github.io/assets-for-api-docs/assets/painting/box_fit_scaleDown.png)
scaleDown,
}
public class FittedSizes
{
public FittedSizes(Size source, Size destination)
{
//todo wrong
this.source = source;
this.destination = destination;
}
public Size source;
public Size destination;
public static FittedSizes applyBoxFit(BoxFit fit, Size inputSize, Size outputSize)
{
if (inputSize.height <= 0.0 || inputSize.width <= 0.0 || outputSize.height <= 0.0 ||
outputSize.width <= 0.0)
return new FittedSizes(Size.zero, Size.zero);
Size sourceSize = null;
Size destinationSize = null;
switch (fit)
{
case BoxFit.fill:
sourceSize = inputSize;
destinationSize = outputSize;
break;
case BoxFit.contain:
sourceSize = inputSize;
if (outputSize.width / outputSize.height > sourceSize.width / sourceSize.height)
destinationSize = new Size(sourceSize.width * outputSize.height / sourceSize.height,
outputSize.height);
else
destinationSize = new Size(outputSize.width,
sourceSize.height * outputSize.width / sourceSize.width);
break;
case BoxFit.cover:
if (outputSize.width / outputSize.height > inputSize.width / inputSize.height)
{
sourceSize = new Size(inputSize.width, inputSize.width * outputSize.height / outputSize.width);
}
else
{
sourceSize = new Size(inputSize.height * outputSize.width / outputSize.height,
inputSize.height);
}
destinationSize = outputSize;
break;
case BoxFit.fitWidth:
sourceSize = new Size(inputSize.width, inputSize.width * outputSize.height / outputSize.width);
destinationSize = new Size(outputSize.width,
sourceSize.height * outputSize.width / sourceSize.width);
break;
case BoxFit.fitHeight:
sourceSize = new Size(inputSize.height * outputSize.width / outputSize.height, inputSize.height);
destinationSize = new Size(sourceSize.width * outputSize.height / sourceSize.height,
outputSize.height);
break;
case BoxFit.none:
sourceSize = new Size(Math.Min(inputSize.width, outputSize.width),
Math.Min(inputSize.height, outputSize.height));
destinationSize = sourceSize;
break;
case BoxFit.scaleDown:
sourceSize = inputSize;
destinationSize = inputSize;
double aspectRatio = inputSize.width / inputSize.height;
if (destinationSize.height > outputSize.height)
destinationSize = new Size(outputSize.height * aspectRatio, outputSize.height);
if (destinationSize.width > outputSize.width)
destinationSize = new Size(outputSize.width, outputSize.width / aspectRatio);
break;
}
return new FittedSizes(sourceSize, destinationSize);
}
}
}

3
Assets/UIWidgets/painting/box_fit.cs.meta


fileFormatVersion: 2
guid: 4d75ec15a75b4a7baca1968978b1eec9
timeCreated: 1534820694

168
Assets/UIWidgets/painting/image_cache.cs


using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using Object = System.Object;
namespace UIWidgets.painting
{
public class ImageCache
{
private const int _kDefaultSize = 1000;
private const int _kDefaultSizeBytes = 20 << 20; // 20 MiB
public Dictionary<Object, ImageStreamCompleter> _pendingImages =
new Dictionary<Object, ImageStreamCompleter>();
public Dictionary<Object, _CachedImage> _cache = new Dictionary<Object, _CachedImage>();
public LinkedList<Object> _lruKeys = new LinkedList<Object>();
private int _maximumSize = _kDefaultSize;
public int maximumSize
{
get { return _maximumSize; }
set
{
if (value == maximumSize)
{
return;
}
_maximumSize = value;
if (maximumSize == 0)
{
_cache.Clear();
_lruKeys.Clear();
_currentSizeBytes = 0;
}
else
{
_checkCacheSize();
}
}
}
public int currentSize
{
get { return _cache.Count; }
}
private int _maximumSizeBytes = _kDefaultSizeBytes;
public int maximumSizeBytes
{
get { return _maximumSizeBytes; }
set
{
if (value == _maximumSizeBytes)
{
return;
}
_maximumSizeBytes = value;
if (_maximumSizeBytes == 0)
{
_cache.Clear();
_lruKeys.Clear();
_currentSizeBytes = 0;
}
else
{
_checkCacheSize();
}
}
}
private int _currentSizeBytes;
public int currentSizeBytes
{
get { return _currentSizeBytes; }
}
public void clear()
{
_cache.Clear();
_lruKeys.Clear();
_currentSizeBytes = 0;
}
public delegate ImageStreamCompleter Loader();
[MethodImpl(MethodImplOptions.Synchronized)]
public ImageStreamCompleter putIfAbsent(Object key, Loader loader)
{
ImageStreamCompleter result;
if (_pendingImages.TryGetValue(key, out result))
{
return result;
}
_CachedImage image;
if (_cache.TryGetValue(key, out image))
{
// put to the MRU position
_lruKeys.Remove(key);
_lruKeys.AddLast(key);
}
if (image != null)
{
return image.completer;
}
result = loader();
if (maximumSize > 0 && maximumSizeBytes > 0)
{
_pendingImages[key] = result;
result.addListener((info, syncCall) =>
{
// int imageSize = info.image == null ? 0 : info.image.height * info.image.width * 4;
// now we use length or raw bytes array as image size
int imageSize = info.image == null ? 0 : info.image.rawData.Length;
_CachedImage cachedImage = new _CachedImage(result, imageSize);
if (maximumSizeBytes > 0 && imageSize > maximumSizeBytes)
{
_maximumSize = imageSize + 1000;
}
_currentSizeBytes += imageSize;
_pendingImages.Remove(key);
_cache[key] = cachedImage;
_lruKeys.AddLast(key);
this._checkCacheSize();
}, null);
}
return result;
}
void _checkCacheSize()
{
while (_currentSizeBytes > _maximumSizeBytes || _cache.Count > _maximumSize)
{
Object key = _lruKeys.First.Value; // get the LRU item
_CachedImage image = _cache[key];
bool removed = _cache.Remove(key);
if (image != null && removed)
{
_currentSizeBytes -= image.sizeBytes;
_lruKeys.Remove(key);
}
}
}
}
public class _CachedImage
{
public _CachedImage(ImageStreamCompleter completer, int sizeBytes)
{
this.completer = completer;
this.sizeBytes = sizeBytes;
}
public ImageStreamCompleter completer;
public int sizeBytes;
}
}

3
Assets/UIWidgets/painting/image_cache.cs.meta


fileFormatVersion: 2
guid: 80732e4248ce48ec92e1463ddc59451d
timeCreated: 1534833891

109
Assets/UIWidgets/painting/image_provider.cs


using System.Collections.Generic;
using RSG;
using System.Net;
using System;
using System.IO;
using UIWidgets.ui;
using UnityEngine;
namespace UIWidgets.painting
{
public abstract class ImageProvider<T>
{
// ImageStream resolve(ImageConfiguration configuration) {
public ImageStream resolve(ImageConfiguration configuration)
{
ImageStream stream = new ImageStream();
T obtainedKey;
obtainedKey = obtainKey(configuration);
stream.setCompleter(PaintingBinding.instance.imageCache.putIfAbsent(obtainedKey, () => load(obtainedKey)));
return stream;
}
public abstract ImageStreamCompleter load(T key);
public abstract T obtainKey(ImageConfiguration configuration);
}
public class NetworkImage : ImageProvider<NetworkImage>
{
public NetworkImage(string url, Dictionary<string, string> headers, double scale = 1.0)
{
this.url = url;
this.headers = headers;
this.scale = scale;
}
/// The URL from which the image will be fetched.
string url;
/// The scale to place in the [ImageInfo] object of the image.
double scale;
/// The HTTP headers that will be used with [HttpClient.get] to fetch image from network.
Dictionary<string, string> headers;
public override NetworkImage obtainKey(ImageConfiguration configuration)
{
// return new SynchronousFuture<NetworkImage> (this);
return this;
}
public override ImageStreamCompleter load(NetworkImage key)
{
return new OneFrameImageStreamCompleter(_loadAsync(key));
}
public static IPromise<ImageInfo> _loadAsync(NetworkImage key)
{
var promise = new Promise<ImageInfo>(); // Create promise.
using (var client = new WebClient())
{
client.DownloadDataCompleted += // Monitor event for download completed.
(s, ev) =>
{
if (ev.Error != null)
{
promise.Reject(ev.Error); // Error during download, reject the promise.
}
else
{
var bytes = ev.Result;
var imageInfo = new ImageInfo(new ui.Image(
bytes
));
promise.Resolve(imageInfo); // Downloaded completed successfully, resolve the promise.
}
};
client.DownloadDataAsync(new Uri(key.url)); // Initiate async op.
}
return promise; // Return the promise so the caller can await resolution (or error).
}
public override string ToString()
{
return "NetworkImage with Url: " + this.url;
}
}
public class ImageConfiguration
{
public ImageConfiguration(Size size = null)
{
this.size = size;
}
public static readonly ImageConfiguration empty = new ImageConfiguration();
public ImageConfiguration copyWith(Size size = null)
{
return new ImageConfiguration(
size: size ?? this.size
);
}
public readonly Size size;
}
}

3
Assets/UIWidgets/painting/image_provider.cs.meta


fileFormatVersion: 2
guid: 858587f8fb5d435e8a07a0ff46e5bc95
timeCreated: 1534820746

135
Assets/UIWidgets/painting/image_stream.cs


using RSG;
using UIWidgets.ui;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace UIWidgets.painting
{
public delegate void ImageListener(ImageInfo image, bool synchronousCall);
public delegate void ImageErrorListerner(System.Object exception, string stackTrack);
public class ImageInfo
{
public ImageInfo(Image image, double scale = 1.0)
{
this.image = image;
this.scale = scale;
}
public Image image;
public double scale;
}
public class ImageStream
{
public ImageStream()
{
}
private ImageStreamCompleter _completer;
private List<_ImageListenerPair> _listeners;
public ImageStreamCompleter completer
{
get { return _completer; }
}
public void setCompleter(ImageStreamCompleter value)
{
_completer = value;
if (_listeners != null)
{
List<_ImageListenerPair> initialListeners = _listeners;
_listeners = null;
foreach (_ImageListenerPair listenerPair in initialListeners)
{
_completer.addListener(
listenerPair.listener,
listenerPair.errorListener
);
}
}
}
}
public abstract class ImageStreamCompleter
{
public List<_ImageListenerPair> _listeners = new List<_ImageListenerPair>();
public ImageInfo _currentImgae;
public void addListener(ImageListener listener, ImageErrorListerner onError)
{
this._listeners.Add(new _ImageListenerPair(listener, onError));
if (_currentImgae != null)
{
// todo refine
try
{
listener(_currentImgae, true);
this.removeListener(listener);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
}
// todo call onError
}
public void removeListener(ImageListener listener)
{
var pairToRemove = this._listeners.Single(lp => lp.listener == listener);
this._listeners.Remove(pairToRemove);
}
public void setImage(ImageInfo image)
{
_currentImgae = image;
if (_listeners.Count == 0)
{
return;
}
foreach (var lp in _listeners.ToList())
{
// todo refine
var listener = lp.listener;
try
{
listener(image, false);
this.removeListener(listener);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
// todo call onError
}
}
}
public class OneFrameImageStreamCompleter : ImageStreamCompleter
{
public OneFrameImageStreamCompleter(IPromise<ImageInfo> image)
{
image.Then(result => { setImage(result); }).Catch(err => { Debug.Log(err); });
}
}
public class _ImageListenerPair
{
public _ImageListenerPair(ImageListener listener, ImageErrorListerner errorListener)
{
this.listener = listener;
this.errorListener = errorListener;
}
public ImageListener listener;
public ImageErrorListerner errorListener;
}
}

3
Assets/UIWidgets/painting/image_stream.cs.meta


fileFormatVersion: 2
guid: 462d84cff25d484895d1a81e7ebd2a24
timeCreated: 1534820764

8
Assets/UIWidgets/promise.meta


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

281
Assets/UIWidgets/rendering/image.cs


using UIWidgets.ui;
using UIWidgets.painting;
using UnityEngine.Rendering;
using BlendMode = UIWidgets.ui.BlendMode;
namespace UIWidgets.rendering
{
class RenderImage : RenderBox
{
public RenderImage(ui.Image image,
double width,
double height,
Color color,
ui.BlendMode colorBlendMode,
BoxFit fit,
ImageRepeat repeat,
Rect centerSlice,
// TextDirection textDirection,
bool matchTextDirection = false,
AlignmentGeometry alignment = null,
double scale = 1.0
)
{
this._image = image;
this._width = width;
this._height = height;
this._scale = scale;
this._color = color;
this._colorBlendMode = colorBlendMode;
this._fit = fit;
this._repeat = repeat;
this._centerSlice = centerSlice;
// this._matchTextDirection = matchTextDirection;
// this._textDir
this._alignment = alignment ?? Alignment.center;
this._textDirection = textDirection;
_updateColorFilter();
}
Alignment _resolvedAlignment;
bool _flipHorizontally;
void _resolve()
{
if (_resolvedAlignment != null)
return;
_resolvedAlignment = alignment.resolve(textDirection);
_flipHorizontally = matchTextDirection && textDirection == TextDirection.rtl;
}
void _markNeedsResolution()
{
_resolvedAlignment = null;
_flipHorizontally = false;
markNeedsPaint();
}
private ui.Image _image;
public ui.Image image
{
get { return this._image; }
set
{
if (value == _image)
return;
_image = value;
markNeedsPaint();
if (_width == null || _height == null)
markNeedsLayout();
}
}
private double _width;
public double width
{
get { return _width; }
set
{
if (value == _width)
return;
_width = value;
markNeedsLayout();
}
}
private double _height;
public double height
{
get { return _height; }
set
{
if (value == _height)
return;
_height = value;
markNeedsLayout();
}
}
private double _scale;
public double scale
{
get { return _scale; }
set
{
if (value == _scale)
return;
_scale = value;
markNeedsLayout();
}
}
ColorFilter _colorFilter;
void _updateColorFilter()
{
if (_color == null)
_colorFilter = null;
else
{
_colorFilter = new ColorFilter(_color,
_colorBlendMode == BlendMode.None ? BlendMode.srcIn : _colorBlendMode);
}
}
private Color _color;
public Color color
{
get { return _color; }
set
{
if (value == _color)
return;
_color = value;
_updateColorFilter();
markNeedsPaint();
}
}
// todo more parameters
private ui.BlendMode _colorBlendMode;
public ui.BlendMode colorBlendMode
{
get { return _colorBlendMode; }
set
{
if (value == _colorBlendMode)
return;
_colorBlendMode = value;
_updateColorFilter();
markNeedsPaint();
}
}
private BoxFit _fit;
public BoxFit fit
{
get { return _fit; }
set
{
if (value == _fit)
return;
_fit = value;
markNeedsPaint();
}
}
private AlignmentGeometry _alignment;
public AlignmentGeometry alignment
{
get { return _alignment; }
set
{
if (value == _alignment)
return;
_alignment = value;
_markNeedsResolution();
}
}
private ImageRepeat _repeat;
public ImageRepeat repeat
{
get { return _repeat; }
set
{
if (value == _repeat)
return;
_repeat = value;
markNeedsPaint();
}
}
private Rect _centerSlice;
public Rect centerSlice
{
get { return _centerSlice; }
set
{
if (value == _centerSlice)
return;
_centerSlice = value;
markNeedsPaint();
}
}
private bool _matchTextDirection;
public bool matchTextDirection
{
get { return _matchTextDirection; }
set
{
if (value == _matchTextDirection)
return;
_matchTextDirection = value;
_markNeedsResolution();
}
}
private TextDirection _textDirection;
public TextDirection textDirection
{
get { return _textDirection; }
set
{
if (_textDirection == value)
return;
_textDirection = value;
_markNeedsResolution();
}
}
Size _sizeForConstraints(BoxConstraints constraints)
{
// Folds the given |width| and |height| into |constraints| so they can all
// be treated uniformly.
constraints = BoxConstraints.tightFor(
_width,
_height
);
constraints = constraints.enforce(constraints);
if (_image == null)
return constraints.smallest;
return constraints.constrainSizeAndAttemptToPreserveAspectRatio(new Size(
_image.width / _scale,
_image.height / _scale
));
}
public override void paint(PaintingContext context, Offset offset)
{
if (_image == null)
return;
_resolve();
DecorationImageUtil.paintImage(
context.canvas,
offset & size,
_image,
_fit,
_centerSlice,
_resolvedAlignment,
_repeat,
_flipHorizontally
// todo
);
}
}
}

3
Assets/UIWidgets/rendering/image.cs.meta


fileFormatVersion: 2
guid: d0413272d07e4c958f45f9c7597fe2b7
timeCreated: 1534820838

21
Assets/UIWidgets/ui/painting/image.cs


using System;
using System.Collections.Generic;
using UIWidgets.painting;
using UnityEngine;
namespace UIWidgets.ui
{
public class Image
{
public Image(byte[] raw, int height = 100, int width = 100)
{
this.rawData = raw;
this.height = height;
this.width = width;
}
public byte[] rawData; // todo temp hack
public int height; //有别的用吗
public int width;
}
}

3
Assets/UIWidgets/ui/painting/image.cs.meta


fileFormatVersion: 2
guid: bfd6fdb0d13948d6acbc528589ebef33
timeCreated: 1534821698

41
Assets/UIWidgets/promise/EnumerableExt.cs


using System;
using System.Collections.Generic;
namespace RSG.Promises
{
/// <summary>
/// General extensions to LINQ.
/// </summary>
public static class EnumerableExt
{
public static void Each<T>(this IEnumerable<T> source, Action<T> fn)
{
foreach (var item in source)
{
fn.Invoke(item);
}
}
public static void Each<T>(this IEnumerable<T> source, Action<T, int> fn)
{
int index = 0;
foreach (T item in source)
{
fn.Invoke(item, index);
index++;
}
}
/// <summary>
/// Convert a variable length argument list of items to an enumerable.
/// </summary>
public static IEnumerable<T> FromItems<T>(params T[] items)
{
foreach (var item in items)
{
yield return item;
}
}
}
}

3
Assets/UIWidgets/promise/EnumerableExt.cs.meta


fileFormatVersion: 2
guid: bb9a3c5b387541cb800b11c84121f7f3
timeCreated: 1534828260

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

3
Assets/UIWidgets/promise/Promise.cs.meta


fileFormatVersion: 2
guid: ffdd174fa01b47d99dae6b8b38945413
timeCreated: 1534828022

19
Assets/UIWidgets/promise/PromiseException.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RSG.Exceptions
{
/// <summary>
/// Base class for promise exceptions.
/// </summary>
public class PromiseException : Exception
{
public PromiseException() { }
public PromiseException(string message) : base(message) { }
public PromiseException(string message, Exception inner) : base(message, inner) { }
}
}

3
Assets/UIWidgets/promise/PromiseException.cs.meta


fileFormatVersion: 2
guid: ef24fa8abd794ec9ad904f149ade425b
timeCreated: 1534828173

82
Assets/UIWidgets/promise/PromiseHelpers.cs


namespace RSG
{
public static class PromiseHelpers
{
/// <summary>
/// Returns a promise that resolves with all of the specified promises have resolved.
/// Returns a promise of a tuple of the resolved results.
/// </summary>
public static IPromise<Tuple<T1, T2>> All<T1, T2>(IPromise<T1> p1, IPromise<T2> p2)
{
var val1 = default(T1);
var val2 = default(T2);
var numUnresolved = 2;
var alreadyRejected = false;
var promise = new Promise<Tuple<T1, T2>>();
p1
.Then(val =>
{
val1 = val;
numUnresolved--;
if (numUnresolved <= 0)
{
promise.Resolve(Tuple.Create(val1, val2));
}
})
.Catch(e =>
{
if (!alreadyRejected)
{
promise.Reject(e);
}
alreadyRejected = true;
})
.Done();
p2
.Then(val =>
{
val2 = val;
numUnresolved--;
if (numUnresolved <= 0)
{
promise.Resolve(Tuple.Create(val1, val2));
}
})
.Catch(e =>
{
if (!alreadyRejected)
{
promise.Reject(e);
}
alreadyRejected = true;
})
.Done();
return promise;
}
/// <summary>
/// Returns a promise that resolves with all of the specified promises have resolved.
/// Returns a promise of a tuple of the resolved results.
/// </summary>
public static IPromise<Tuple<T1, T2, T3>> All<T1, T2, T3>(IPromise<T1> p1, IPromise<T2> p2, IPromise<T3> p3)
{
return All(All(p1, p2), p3)
.Then(vals => Tuple.Create(vals.Item1.Item1, vals.Item1.Item2, vals.Item2));
}
/// <summary>
/// Returns a promise that resolves with all of the specified promises have resolved.
/// Returns a promise of a tuple of the resolved results.
/// </summary>
public static IPromise<Tuple<T1, T2, T3, T4>> All<T1, T2, T3, T4>(IPromise<T1> p1, IPromise<T2> p2, IPromise<T3> p3, IPromise<T4> p4)
{
return All(All(p1, p2), All(p3, p4))
.Then(vals => Tuple.Create(vals.Item1.Item1, vals.Item1.Item2, vals.Item2.Item1, vals.Item2.Item2));
}
}
}

3
Assets/UIWidgets/promise/PromiseHelpers.cs.meta


fileFormatVersion: 2
guid: 07f0b3c08d53427992f828dd9c4f0f15
timeCreated: 1534828078

22
Assets/UIWidgets/promise/PromiseStateException.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RSG.Exceptions
{
/// <summary>
/// Exception thrown when an operation is performed on a promise that is in an invalid
/// state for it to handle.
/// </summary>
public class PromiseStateException : PromiseException
{
public PromiseStateException() { }
public PromiseStateException(string message) : base(message) { }
public PromiseStateException(string message, Exception inner)
: base(message, inner)
{ }
}
}

3
Assets/UIWidgets/promise/PromiseStateException.cs.meta


fileFormatVersion: 2
guid: d922956f02bc4ff2a82f9404787380b0
timeCreated: 1534828191

247
Assets/UIWidgets/promise/PromiseTimer.cs


using System;
using System.Collections.Generic;
namespace RSG
{
public class PromiseCancelledException : Exception
{
/// <summary>
/// Just create the exception
/// </summary>
public PromiseCancelledException()
{
}
/// <summary>
/// Create the exception with description
/// </summary>
/// <param name="message">Exception description</param>
public PromiseCancelledException(String message) : base(message)
{
}
}
/// <summary>
/// A class that wraps a pending promise with it's predicate and time data
/// </summary>
internal class PredicateWait
{
/// <summary>
/// Predicate for resolving the promise
/// </summary>
public Func<TimeData, bool> predicate;
/// <summary>
/// The time the promise was started
/// </summary>
public float timeStarted;
/// <summary>
/// The pending promise which is an interface for a promise that can be rejected or resolved.
/// </summary>
public IPendingPromise pendingPromise;
/// <summary>
/// The time data specific to this pending promise. Includes elapsed time and delta time.
/// </summary>
public TimeData timeData;
/// <summary>
/// The frame the promise was started
/// </summary>
public int frameStarted;
}
/// <summary>
/// Time data specific to a particular pending promise.
/// </summary>
public struct TimeData
{
/// <summary>
/// The amount of time that has elapsed since the pending promise started running
/// </summary>
public float elapsedTime;
/// <summary>
/// The amount of time since the last time the pending promise was updated.
/// </summary>
public float deltaTime;
/// <summary>
/// The amount of times that update has been called since the pending promise started running
/// </summary>
public int elapsedUpdates;
}
public interface IPromiseTimer
{
/// <summary>
/// Resolve the returned promise once the time has elapsed
/// </summary>
IPromise WaitFor(float seconds);
/// <summary>
/// Resolve the returned promise once the predicate evaluates to true
/// </summary>
IPromise WaitUntil(Func<TimeData, bool> predicate);
/// <summary>
/// Resolve the returned promise once the predicate evaluates to false
/// </summary>
IPromise WaitWhile(Func<TimeData, bool> predicate);
/// <summary>
/// Update all pending promises. Must be called for the promises to progress and resolve at all.
/// </summary>
void Update(float deltaTime);
/// <summary>
/// Cancel a waiting promise and reject it immediately.
/// </summary>
bool Cancel(IPromise promise);
}
public class PromiseTimer : IPromiseTimer
{
/// <summary>
/// The current running total for time that this PromiseTimer has run for
/// </summary>
private float curTime;
/// <summary>
/// The current running total for the amount of frames the PromiseTimer has run for
/// </summary>
private int curFrame;
/// <summary>
/// Currently pending promises
/// </summary>
private readonly LinkedList<PredicateWait> waiting = new LinkedList<PredicateWait>();
/// <summary>
/// Resolve the returned promise once the time has elapsed
/// </summary>
public IPromise WaitFor(float seconds)
{
return WaitUntil(t => t.elapsedTime >= seconds);
}
/// <summary>
/// Resolve the returned promise once the predicate evaluates to false
/// </summary>
public IPromise WaitWhile(Func<TimeData, bool> predicate)
{
return WaitUntil(t => !predicate(t));
}
/// <summary>
/// Resolve the returned promise once the predicate evalutes to true
/// </summary>
public IPromise WaitUntil(Func<TimeData, bool> predicate)
{
var promise = new Promise();
var wait = new PredicateWait()
{
timeStarted = curTime,
pendingPromise = promise,
timeData = new TimeData(),
predicate = predicate,
frameStarted = curFrame
};
waiting.AddLast(wait);
return promise;
}
public bool Cancel(IPromise promise)
{
var node = FindInWaiting(promise);
if (node == null)
{
return false;
}
node.Value.pendingPromise.Reject(new PromiseCancelledException("Promise was cancelled by user."));
waiting.Remove(node);
return true;
}
LinkedListNode<PredicateWait> FindInWaiting(IPromise promise)
{
for (var node = waiting.First; node != null; node = node.Next)
{
if (node.Value.pendingPromise.Id.Equals(promise.Id))
{
return node;
}
}
return null;
}
/// <summary>
/// Update all pending promises. Must be called for the promises to progress and resolve at all.
/// </summary>
public void Update(float deltaTime)
{
curTime += deltaTime;
curFrame += 1;
var node = waiting.First;
while (node != null)
{
var wait = node.Value;
var newElapsedTime = curTime - wait.timeStarted;
wait.timeData.deltaTime = newElapsedTime - wait.timeData.elapsedTime;
wait.timeData.elapsedTime = newElapsedTime;
var newElapsedUpdates = curFrame - wait.frameStarted;
wait.timeData.elapsedUpdates = newElapsedUpdates;
bool result;
try
{
result = wait.predicate(wait.timeData);
}
catch (Exception ex)
{
wait.pendingPromise.Reject(ex);
node = RemoveNode(node);
continue;
}
if (result)
{
wait.pendingPromise.Resolve();
node = RemoveNode(node);
}
else
{
node = node.Next;
}
}
}
/// <summary>
/// Removes the provided node and returns the next node in the list.
/// </summary>
private LinkedListNode<PredicateWait> RemoveNode(LinkedListNode<PredicateWait> node)
{
var currentNode = node;
node = node.Next;
waiting.Remove(currentNode);
return node;
}
}
}

3
Assets/UIWidgets/promise/PromiseTimer.cs.meta


fileFormatVersion: 2
guid: e47ddf579a9a45f48fd9203faf93b52f
timeCreated: 1534828095

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

3
Assets/UIWidgets/promise/Promise_NonGeneric.cs.meta


fileFormatVersion: 2
guid: fad6eb2d15b84c7cb92f115245ac09f8
timeCreated: 1534828106

148
Assets/UIWidgets/promise/Tuple.cs


namespace RSG
{
/// <summary>
/// Provides static methods for creating tuple objects.
///
/// Tuple implementation for .NET 3.5
/// </summary>
public class Tuple
{
/// <summary>
/// Create a new 2-tuple, or pair.
/// </summary>
/// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
/// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
/// <param name="item1">The value of the first component of the tuple.</param>
/// <param name="item2">The value of the second component of the tuple.</param>
/// <returns>A 2-tuple whose value is (item1, item2)</returns>
public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2)
{
return new Tuple<T1, T2>(item1, item2);
}
/// <summary>
/// Create a new 3-tuple, or triple.
/// </summary>
/// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
/// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
/// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
/// <param name="item1">The value of the first component of the tuple.</param>
/// <param name="item2">The value of the second component of the tuple.</param>
/// <param name="item3">The value of the third component of the tuple.</param>
/// <returns>A 3-tuple whose value is (item1, item2, item3)</returns>
public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)
{
return new Tuple<T1, T2, T3>(item1, item2, item3);
}
/// <summary>
/// Create a new 4-tuple, or quadruple.
/// </summary>
/// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
/// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
/// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
/// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
/// <param name="item1">The value of the first component of the tuple.</param>
/// <param name="item2">The value of the second component of the tuple.</param>
/// <param name="item3">The value of the third component of the tuple.</param>
/// <param name="item4">The value of the fourth component of the tuple.</param>
/// <returns>A 3-tuple whose value is (item1, item2, item3, item4)</returns>
public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4)
{
return new Tuple<T1, T2, T3, T4>(item1, item2, item3, item4);
}
}
/// <summary>
/// Represents a 2-tuple, or pair.
/// </summary>
/// <typeparam name="T1">The type of the tuple's first component.</typeparam>
/// <typeparam name="T2">The type of the tuple's second component.</typeparam>
public class Tuple<T1, T2>
{
internal Tuple(T1 item1, T2 item2)
{
Item1 = item1;
Item2 = item2;
}
/// <summary>
/// Gets the value of the current tuple's first component.
/// </summary>
public T1 Item1 { get; private set; }
/// <summary>
/// Gets the value of the current tuple's second component.
/// </summary>
public T2 Item2 { get; private set; }
}
/// <summary>
/// Represents a 3-tuple, or triple.
/// </summary>
/// <typeparam name="T1">The type of the tuple's first component.</typeparam>
/// <typeparam name="T2">The type of the tuple's second component.</typeparam>
/// <typeparam name="T3">The type of the tuple's third component.</typeparam>
public class Tuple<T1, T2, T3>
{
internal Tuple(T1 item1, T2 item2, T3 item3)
{
Item1 = item1;
Item2 = item2;
Item3 = item3;
}
/// <summary>
/// Gets the value of the current tuple's first component.
/// </summary>
public T1 Item1 { get; private set; }
/// <summary>
/// Gets the value of the current tuple's second component.
/// </summary>
public T2 Item2 { get; private set; }
/// <summary>
/// Gets the value of the current tuple's third component.
/// </summary>
public T3 Item3 { get; private set; }
}
/// <summary>
/// Represents a 4-tuple, or quadruple.
/// </summary>
/// <typeparam name="T1">The type of the tuple's first component.</typeparam>
/// <typeparam name="T2">The type of the tuple's second component.</typeparam>
/// <typeparam name="T3">The type of the tuple's third component.</typeparam>
/// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
public class Tuple<T1, T2, T3, T4>
{
internal Tuple(T1 item1, T2 item2, T3 item3, T4 item4)
{
Item1 = item1;
Item2 = item2;
Item3 = item3;
Item4 = item4;
}
/// <summary>
/// Gets the value of the current tuple's first component.
/// </summary>
public T1 Item1 { get; private set; }
/// <summary>
/// Gets the value of the current tuple's second component.
/// </summary>
public T2 Item2 { get; private set; }
/// <summary>
/// Gets the value of the current tuple's third component.
/// </summary>
public T3 Item3 { get; private set; }
/// <summary>
/// Gets the value of the current tuple's fourth component.
/// </summary>
public T4 Item4 { get; private set; }
}
}

3
Assets/UIWidgets/promise/Tuple.cs.meta


fileFormatVersion: 2
guid: 2e1ff13e974447a080559101999e17d9
timeCreated: 1534828127
正在加载...
取消
保存