mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-24 10:02:08 -05:00
Rewrite code to avoid usage of Dictionary
This commit is contained in:
parent
7303e8c2e4
commit
db4275f571
25 changed files with 300 additions and 361 deletions
|
@ -1,79 +0,0 @@
|
||||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
|
||||||
#if ANDROID
|
|
||||||
using System;
|
|
||||||
using ClassicalSharp.GraphicsAPI;
|
|
||||||
using Android.Graphics;
|
|
||||||
using Android.Graphics.Drawables;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
|
||||||
|
|
||||||
public sealed partial class CanvasDrawer2D {
|
|
||||||
|
|
||||||
Bitmap measuringBmp;
|
|
||||||
Canvas measuringC;
|
|
||||||
|
|
||||||
public CanvasDrawer2D(IGraphicsApi graphics) {
|
|
||||||
this.graphics = graphics;
|
|
||||||
measuringBmp = Bitmap.CreateBitmap(1, 1, Bitmap.Config.Argb8888);
|
|
||||||
measuringC = new Canvas(measuringBmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void DrawSysText(ref DrawTextArgs args, int x, int y) {
|
|
||||||
if (!args.SkipPartsCheck)
|
|
||||||
GetTextParts(args.Text);
|
|
||||||
|
|
||||||
float textX = x;
|
|
||||||
Paint backBrush = GetOrCreateBrush(FastColour.Black);
|
|
||||||
for (int i = 0; i < parts.Count; i++) {
|
|
||||||
TextPart part = parts[i];
|
|
||||||
Paint foreBrush = GetOrCreateBrush(part.Col);
|
|
||||||
if (args.UseShadow)
|
|
||||||
c.DrawText(part.Text, textX + Offset, y + Offset, backBrush);
|
|
||||||
|
|
||||||
c.DrawText(part.Text, textX, y, foreBrush);
|
|
||||||
textX += foreBrush.MeasureText(part.Text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void DrawClippedText(ref DrawTextArgs args, int x, int y, float maxWidth, float maxHeight) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
FastBitmap bitmapWrapper = new FastBitmap();
|
|
||||||
protected override void DrawBitmappedText(ref DrawTextArgs args, int x, int y) {
|
|
||||||
using (bitmapWrapper) {
|
|
||||||
bitmapWrapper.SetData(curBmp, true, false);
|
|
||||||
DrawBitmapTextImpl(bitmapWrapper, ref args, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Size MeasureSysSize(ref DrawTextArgs args) {
|
|
||||||
GetTextParts(args.Text);
|
|
||||||
if (parts.Count == 0)
|
|
||||||
return Size.Empty;
|
|
||||||
|
|
||||||
SizeF total = SizeF.Empty;
|
|
||||||
for (int i = 0; i < parts.Count; i++) {
|
|
||||||
TextPart part = parts[i];
|
|
||||||
Paint textBrush = GetOrCreateBrush(part.Col);
|
|
||||||
total.Width += textBrush.MeasureText(part.Text);
|
|
||||||
}
|
|
||||||
total.Height = PtToPx(args.Font.Size);
|
|
||||||
if (args.UseShadow) {
|
|
||||||
total.Width += Offset; total.Height += Offset;
|
|
||||||
}
|
|
||||||
return Size.Ceiling(total);
|
|
||||||
}
|
|
||||||
|
|
||||||
int PtToPx(int point) {
|
|
||||||
return (int)Math.Ceiling((float)point / 72 * 96); // TODO: not sure if even right, non 96 dpi?
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisposeText() {
|
|
||||||
measuringC.Dispose();
|
|
||||||
measuringBmp.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -2,16 +2,24 @@
|
||||||
#if ANDROID
|
#if ANDROID
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
using System.Drawing;
|
||||||
using Android.Graphics;
|
using Android.Graphics;
|
||||||
using Android.Graphics.Drawables;
|
using Android.Graphics.Drawables;
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
public sealed partial class CanvasDrawer2D : IDrawer2D {
|
public sealed class CanvasDrawer2D : IDrawer2D {
|
||||||
|
|
||||||
Dictionary<int, Paint> brushCache = new Dictionary<int, Paint>(16);
|
Dictionary<int, Paint> brushCache = new Dictionary<int, Paint>(16);
|
||||||
Bitmap curBmp;
|
Bitmap curBmp, measuringBmp;
|
||||||
Canvas c;
|
Canvas c, measuringC;
|
||||||
|
|
||||||
|
public CanvasDrawer2D(IGraphicsApi graphics) {
|
||||||
|
this.graphics = graphics;
|
||||||
|
measuringBmp = Bitmap.CreateBitmap(1, 1, Bitmap.Config.Argb8888);
|
||||||
|
measuringC = new Canvas(measuringBmp);
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetBitmap(Bitmap bmp) {
|
public override void SetBitmap(Bitmap bmp) {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
|
@ -78,6 +86,62 @@ namespace ClassicalSharp {
|
||||||
brushCache[key] = brush;
|
brushCache[key] = brush;
|
||||||
return brush;
|
return brush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void DrawSysText(ref DrawTextArgs args, int x, int y) {
|
||||||
|
if (!args.SkipPartsCheck)
|
||||||
|
GetTextParts(args.Text);
|
||||||
|
|
||||||
|
float textX = x;
|
||||||
|
Paint backBrush = GetOrCreateBrush(FastColour.Black);
|
||||||
|
for (int i = 0; i < parts.Count; i++) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
Paint foreBrush = GetOrCreateBrush(part.Col);
|
||||||
|
if (args.UseShadow)
|
||||||
|
c.DrawText(part.Text, textX + Offset, y + Offset, backBrush);
|
||||||
|
|
||||||
|
c.DrawText(part.Text, textX, y, foreBrush);
|
||||||
|
textX += foreBrush.MeasureText(part.Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawClippedText(ref DrawTextArgs args, int x, int y, float maxWidth, float maxHeight) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
FastBitmap bitmapWrapper = new FastBitmap();
|
||||||
|
protected override void DrawBitmappedText(ref DrawTextArgs args, int x, int y) {
|
||||||
|
using (bitmapWrapper) {
|
||||||
|
bitmapWrapper.SetData(curBmp, true, false);
|
||||||
|
DrawBitmapTextImpl(bitmapWrapper, ref args, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size MeasureSysSize(ref DrawTextArgs args) {
|
||||||
|
GetTextParts(args.Text);
|
||||||
|
if (parts.Count == 0)
|
||||||
|
return Size.Empty;
|
||||||
|
|
||||||
|
SizeF total = SizeF.Empty;
|
||||||
|
for (int i = 0; i < parts.Count; i++) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
Paint textBrush = GetOrCreateBrush(part.Col);
|
||||||
|
total.Width += textBrush.MeasureText(part.Text);
|
||||||
|
}
|
||||||
|
total.Height = PtToPx(args.Font.Size);
|
||||||
|
if (args.UseShadow) {
|
||||||
|
total.Width += Offset; total.Height += Offset;
|
||||||
|
}
|
||||||
|
return Size.Ceiling(total);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PtToPx(int point) {
|
||||||
|
return (int)Math.Ceiling((float)point / 72 * 96); // TODO: not sure if even right, non 96 dpi?
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisposeText() {
|
||||||
|
measuringC.Dispose();
|
||||||
|
measuringBmp.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -1,22 +0,0 @@
|
||||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
|
||||||
|
|
||||||
/// <summary> Contains arguments for measuring or drawing text. </summary>
|
|
||||||
public struct DrawTextArgs {
|
|
||||||
|
|
||||||
public string Text;
|
|
||||||
public Font Font;
|
|
||||||
public bool UseShadow;
|
|
||||||
public bool SkipPartsCheck;
|
|
||||||
|
|
||||||
public DrawTextArgs(string text, Font font, bool useShadow) {
|
|
||||||
Text = text;
|
|
||||||
Font = font;
|
|
||||||
UseShadow = useShadow;
|
|
||||||
SkipPartsCheck = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
|
||||||
#if !ANDROID
|
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Text;
|
|
||||||
#if !LAUNCHER
|
|
||||||
using ClassicalSharp.GraphicsAPI;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
|
||||||
|
|
||||||
public sealed partial class GdiPlusDrawer2D {
|
|
||||||
|
|
||||||
StringFormat format;
|
|
||||||
Bitmap measuringBmp;
|
|
||||||
Graphics measuringGraphics;
|
|
||||||
|
|
||||||
#if !LAUNCHER
|
|
||||||
public GdiPlusDrawer2D(IGraphicsApi graphics) {
|
|
||||||
this.graphics = graphics;
|
|
||||||
#else
|
|
||||||
public GdiPlusDrawer2D() {
|
|
||||||
#endif
|
|
||||||
format = StringFormat.GenericTypographic;
|
|
||||||
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
|
|
||||||
format.Trimming = StringTrimming.None;
|
|
||||||
//format.FormatFlags |= StringFormatFlags.NoWrap;
|
|
||||||
//format.FormatFlags |= StringFormatFlags.NoClip;
|
|
||||||
|
|
||||||
measuringBmp = new Bitmap(1, 1);
|
|
||||||
measuringGraphics = Graphics.FromImage(measuringBmp);
|
|
||||||
measuringGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void DrawSysText(ref DrawTextArgs args, int x, int y) {
|
|
||||||
if (!args.SkipPartsCheck)
|
|
||||||
GetTextParts(args.Text);
|
|
||||||
|
|
||||||
float textX = x;
|
|
||||||
Brush backBrush = GetOrCreateBrush(FastColour.Black);
|
|
||||||
for (int i = 0; i < parts.Count; i++) {
|
|
||||||
TextPart part = parts[i];
|
|
||||||
Brush foreBrush = GetOrCreateBrush(part.Col);
|
|
||||||
if (args.UseShadow)
|
|
||||||
g.DrawString(part.Text, args.Font, backBrush, textX + Offset, y + Offset, format);
|
|
||||||
|
|
||||||
g.DrawString(part.Text, args.Font, foreBrush, textX, y, format);
|
|
||||||
textX += g.MeasureString(part.Text, args.Font, Int32.MaxValue, format).Width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void DrawClippedText(ref DrawTextArgs args, int x, int y, float maxWidth, float maxHeight) {
|
|
||||||
if (!args.SkipPartsCheck)
|
|
||||||
GetTextParts(args.Text);
|
|
||||||
|
|
||||||
Brush shadowBrush = GetOrCreateBrush(FastColour.Black);
|
|
||||||
StringFormatFlags flags = format.FormatFlags;
|
|
||||||
format.FormatFlags |= StringFormatFlags.NoWrap;
|
|
||||||
format.Trimming = StringTrimming.EllipsisCharacter;
|
|
||||||
float textX = x;
|
|
||||||
|
|
||||||
for (int i = 0; i < parts.Count; i++) {
|
|
||||||
TextPart part = parts[i];
|
|
||||||
Brush textBrush = GetOrCreateBrush(part.Col);
|
|
||||||
RectangleF rect = new RectangleF(textX + Offset, y + Offset, maxWidth, maxHeight);
|
|
||||||
if (args.UseShadow)
|
|
||||||
g.DrawString(part.Text, args.Font, shadowBrush, rect, format);
|
|
||||||
|
|
||||||
rect = new RectangleF(textX, y, maxWidth, maxHeight);
|
|
||||||
g.DrawString(part.Text, args.Font, textBrush, rect, format);
|
|
||||||
textX += g.MeasureString(part.Text, args.Font, Int32.MaxValue, format).Width;
|
|
||||||
}
|
|
||||||
format.Trimming = StringTrimming.None;
|
|
||||||
format.FormatFlags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
FastBitmap bitmapWrapper = new FastBitmap();
|
|
||||||
protected override void DrawBitmappedText(ref DrawTextArgs args, int x, int y) {
|
|
||||||
using (bitmapWrapper) {
|
|
||||||
bitmapWrapper.SetData(curBmp, true, false);
|
|
||||||
DrawBitmapTextImpl(bitmapWrapper, ref args, x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Size MeasureSysSize(ref DrawTextArgs args) {
|
|
||||||
GetTextParts(args.Text);
|
|
||||||
int count = parts.Count;
|
|
||||||
if (count == 0) return Size.Empty;
|
|
||||||
|
|
||||||
float width = 0, height = 0;
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
SizeF size = measuringGraphics.MeasureString(parts[i].Text, args.Font, Int32.MaxValue, format);
|
|
||||||
height = Math.Max(height, size.Height);
|
|
||||||
width += size.Width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.UseShadow) { width += Offset; height += Offset; }
|
|
||||||
return new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisposeText() {
|
|
||||||
measuringGraphics.Dispose();
|
|
||||||
measuringBmp.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -5,14 +5,36 @@ using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Drawing2D;
|
using System.Drawing.Drawing2D;
|
||||||
using System.Drawing.Text;
|
using System.Drawing.Text;
|
||||||
|
#if !LAUNCHER
|
||||||
|
using ClassicalSharp.GraphicsAPI;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
public sealed partial class GdiPlusDrawer2D : IDrawer2D {
|
public sealed class GdiPlusDrawer2D : IDrawer2D {
|
||||||
|
|
||||||
Dictionary<int, SolidBrush> brushCache = new Dictionary<int, SolidBrush>(16);
|
struct CachedBrush { public int ARGB; public SolidBrush Brush; }
|
||||||
Graphics g;
|
List<CachedBrush> brushes = new List<CachedBrush>(16);
|
||||||
Bitmap curBmp;
|
Graphics g, measuringGraphics;
|
||||||
|
Bitmap curBmp, measuringBmp;
|
||||||
|
StringFormat format;
|
||||||
|
|
||||||
|
#if !LAUNCHER
|
||||||
|
public GdiPlusDrawer2D(IGraphicsApi graphics) {
|
||||||
|
this.graphics = graphics;
|
||||||
|
#else
|
||||||
|
public GdiPlusDrawer2D() {
|
||||||
|
#endif
|
||||||
|
format = StringFormat.GenericTypographic;
|
||||||
|
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
|
||||||
|
format.Trimming = StringTrimming.None;
|
||||||
|
//format.FormatFlags |= StringFormatFlags.NoWrap;
|
||||||
|
//format.FormatFlags |= StringFormatFlags.NoClip;
|
||||||
|
|
||||||
|
measuringBmp = new Bitmap(1, 1);
|
||||||
|
measuringGraphics = Graphics.FromImage(measuringBmp);
|
||||||
|
measuringGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetBitmap(Bitmap bmp) {
|
public override void SetBitmap(Bitmap bmp) {
|
||||||
if (g != null) {
|
if (g != null) {
|
||||||
|
@ -64,8 +86,8 @@ namespace ClassicalSharp {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DisposeInstance() {
|
public override void DisposeInstance() {
|
||||||
foreach (KeyValuePair<int, SolidBrush> pair in brushCache) {
|
for (int i = 0; i < brushes.Count; i++) {
|
||||||
pair.Value.Dispose();
|
brushes[i].Brush.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
DisposeText();
|
DisposeText();
|
||||||
|
@ -73,14 +95,85 @@ namespace ClassicalSharp {
|
||||||
}
|
}
|
||||||
|
|
||||||
SolidBrush GetOrCreateBrush(FastColour col) {
|
SolidBrush GetOrCreateBrush(FastColour col) {
|
||||||
int key = col.ToArgb();
|
int argb = col.ToArgb();
|
||||||
SolidBrush brush;
|
for (int i = 0; i < brushes.Count; i++) {
|
||||||
if (brushCache.TryGetValue(key, out brush))
|
if (brushes[i].ARGB == argb) return brushes[i].Brush;
|
||||||
return brush;
|
}
|
||||||
|
|
||||||
brush = new SolidBrush(col);
|
CachedBrush b; b.ARGB = argb; b.Brush = new SolidBrush(col);
|
||||||
brushCache[key] = brush;
|
brushes.Add(b);
|
||||||
return brush;
|
return b.Brush;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void DrawSysText(ref DrawTextArgs args, int x, int y) {
|
||||||
|
if (!args.SkipPartsCheck)
|
||||||
|
GetTextParts(args.Text);
|
||||||
|
|
||||||
|
float textX = x;
|
||||||
|
Brush backBrush = GetOrCreateBrush(FastColour.Black);
|
||||||
|
for (int i = 0; i < parts.Count; i++) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
Brush foreBrush = GetOrCreateBrush(part.Col);
|
||||||
|
if (args.UseShadow)
|
||||||
|
g.DrawString(part.Text, args.Font, backBrush, textX + Offset, y + Offset, format);
|
||||||
|
|
||||||
|
g.DrawString(part.Text, args.Font, foreBrush, textX, y, format);
|
||||||
|
textX += g.MeasureString(part.Text, args.Font, Int32.MaxValue, format).Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawClippedText(ref DrawTextArgs args, int x, int y, float maxWidth, float maxHeight) {
|
||||||
|
if (!args.SkipPartsCheck)
|
||||||
|
GetTextParts(args.Text);
|
||||||
|
|
||||||
|
Brush shadowBrush = GetOrCreateBrush(FastColour.Black);
|
||||||
|
StringFormatFlags flags = format.FormatFlags;
|
||||||
|
format.FormatFlags |= StringFormatFlags.NoWrap;
|
||||||
|
format.Trimming = StringTrimming.EllipsisCharacter;
|
||||||
|
float textX = x;
|
||||||
|
|
||||||
|
for (int i = 0; i < parts.Count; i++) {
|
||||||
|
TextPart part = parts[i];
|
||||||
|
Brush textBrush = GetOrCreateBrush(part.Col);
|
||||||
|
RectangleF rect = new RectangleF(textX + Offset, y + Offset, maxWidth, maxHeight);
|
||||||
|
if (args.UseShadow)
|
||||||
|
g.DrawString(part.Text, args.Font, shadowBrush, rect, format);
|
||||||
|
|
||||||
|
rect = new RectangleF(textX, y, maxWidth, maxHeight);
|
||||||
|
g.DrawString(part.Text, args.Font, textBrush, rect, format);
|
||||||
|
textX += g.MeasureString(part.Text, args.Font, Int32.MaxValue, format).Width;
|
||||||
|
}
|
||||||
|
format.Trimming = StringTrimming.None;
|
||||||
|
format.FormatFlags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
FastBitmap bitmapWrapper = new FastBitmap();
|
||||||
|
protected override void DrawBitmappedText(ref DrawTextArgs args, int x, int y) {
|
||||||
|
using (bitmapWrapper) {
|
||||||
|
bitmapWrapper.SetData(curBmp, true, false);
|
||||||
|
DrawBitmapTextImpl(bitmapWrapper, ref args, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size MeasureSysSize(ref DrawTextArgs args) {
|
||||||
|
GetTextParts(args.Text);
|
||||||
|
int count = parts.Count;
|
||||||
|
if (count == 0) return Size.Empty;
|
||||||
|
|
||||||
|
float width = 0, height = 0;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
SizeF size = measuringGraphics.MeasureString(parts[i].Text, args.Font, Int32.MaxValue, format);
|
||||||
|
height = Math.Max(height, size.Height);
|
||||||
|
width += size.Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.UseShadow) { width += Offset; height += Offset; }
|
||||||
|
return new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisposeText() {
|
||||||
|
measuringGraphics.Dispose();
|
||||||
|
measuringBmp.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,20 @@ using Android.Graphics;
|
||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
/// <summary> Contains arguments for measuring or drawing text. </summary>
|
||||||
|
public struct DrawTextArgs {
|
||||||
|
public string Text;
|
||||||
|
public Font Font;
|
||||||
|
public bool UseShadow, SkipPartsCheck;
|
||||||
|
|
||||||
|
public DrawTextArgs(string text, Font font, bool useShadow) {
|
||||||
|
Text = text;
|
||||||
|
Font = font;
|
||||||
|
UseShadow = useShadow;
|
||||||
|
SkipPartsCheck = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Class responsible for performing drawing operations on bitmaps
|
/// <summary> Class responsible for performing drawing operations on bitmaps
|
||||||
/// and for converting bitmaps into graphics api textures. </summary>
|
/// and for converting bitmaps into graphics api textures. </summary>
|
||||||
/// <remarks> Uses GDI+ on Windows, uses Cairo on Mono. </remarks>
|
/// <remarks> Uses GDI+ on Windows, uses Cairo on Mono. </remarks>
|
||||||
|
|
|
@ -142,13 +142,20 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBlockTo(BlockID block) {
|
public void SetBlockTo(BlockID block) {
|
||||||
selIndex = Array.IndexOf<BlockID>(blocksTable, block);
|
selIndex = IndexOfBlock(block);
|
||||||
scrollY = (selIndex / blocksPerRow) - (maxRows - 1);
|
scrollY = (selIndex / blocksPerRow) - (maxRows - 1);
|
||||||
ClampScrollY();
|
ClampScrollY();
|
||||||
MoveCursorToSelected();
|
MoveCursorToSelected();
|
||||||
RecreateBlockInfoTexture();
|
RecreateBlockInfoTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int IndexOfBlock(BlockID block) {
|
||||||
|
for (int i = 0; i < blocksTable.Length; i++) {
|
||||||
|
if (blocksTable[i] == block) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void MoveCursorToSelected() {
|
void MoveCursorToSelected() {
|
||||||
if (selIndex == -1) return;
|
if (selIndex == -1) return;
|
||||||
game.DesktopCursorPos = GetMouseCoords(selIndex);
|
game.DesktopCursorPos = GetMouseCoords(selIndex);
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
|
|
||||||
void DefaultButtonClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
void DefaultButtonClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
||||||
if (btn != MouseButton.Left) return;
|
if (btn != MouseButton.Left) return;
|
||||||
int index = Array.IndexOf<Widget>(widgets, targetWidget);
|
int index = IndexOfWidget(targetWidget);
|
||||||
string defValue = defaultValues[index];
|
string defValue = defaultValues[index];
|
||||||
|
|
||||||
input.Clear();
|
input.Clear();
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleFontChange() {
|
void HandleFontChange() {
|
||||||
int selIndex = Array.IndexOf<Widget>(widgets, selectedWidget);
|
int selIndex = IndexOfWidget(selectedWidget);
|
||||||
game.Events.RaiseChatFontChanged();
|
game.Events.RaiseChatFontChanged();
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
base.Init();
|
base.Init();
|
||||||
|
|
|
@ -168,7 +168,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
|
|
||||||
void DefaultButtonClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
void DefaultButtonClick(Game game, Widget widget, MouseButton btn, int x, int y) {
|
||||||
if (btn != MouseButton.Left) return;
|
if (btn != MouseButton.Left) return;
|
||||||
int index = Array.IndexOf<Widget>(widgets, targetWidget);
|
int index = IndexOfWidget(targetWidget);
|
||||||
string defValue = defaultValues[index];
|
string defValue = defaultValues[index];
|
||||||
|
|
||||||
input.Clear();
|
input.Clear();
|
||||||
|
|
|
@ -90,19 +90,19 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (btn == MouseButton.Right && (curWidget == null || curWidget == widget)) {
|
if (btn == MouseButton.Right && (curWidget == null || curWidget == widget)) {
|
||||||
curWidget = (ButtonWidget)widget;
|
curWidget = (ButtonWidget)widget;
|
||||||
index = Array.IndexOf<Widget>(widgets, curWidget) - 2;
|
index = IndexOfWidget(curWidget) - 2;
|
||||||
KeyBind mapping = Get(index, left, right);
|
KeyBind mapping = Get(index, left, right);
|
||||||
HandlesKeyDown(game.Input.Keys.GetDefault(mapping));
|
HandlesKeyDown(game.Input.Keys.GetDefault(mapping));
|
||||||
}
|
}
|
||||||
if (btn != MouseButton.Left) return;
|
if (btn != MouseButton.Left) return;
|
||||||
|
|
||||||
if (curWidget != null) {
|
if (curWidget != null) {
|
||||||
index = Array.IndexOf<Widget>(widgets, curWidget) - 2;
|
index = IndexOfWidget(curWidget) - 2;
|
||||||
curWidget.SetText(ButtonText(index));
|
curWidget.SetText(ButtonText(index));
|
||||||
curWidget = null;
|
curWidget = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = Array.IndexOf<Widget>(widgets, widget) - 2;
|
index = IndexOfWidget(widget) - 2;
|
||||||
string text = ButtonText(index);
|
string text = ButtonText(index);
|
||||||
curWidget = (ButtonWidget)widget;
|
curWidget = (ButtonWidget)widget;
|
||||||
curWidget.SetText("> " + text + " <");
|
curWidget.SetText("> " + text + " <");
|
||||||
|
@ -119,7 +119,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
if (key == Key.Escape) {
|
if (key == Key.Escape) {
|
||||||
game.Gui.SetNewScreen(null);
|
game.Gui.SetNewScreen(null);
|
||||||
} else if (curWidget != null) {
|
} else if (curWidget != null) {
|
||||||
int index = Array.IndexOf<Widget>(widgets, curWidget) - 2;
|
int index = IndexOfWidget(curWidget) - 2;
|
||||||
KeyBind mapping = Get(index, left, right);
|
KeyBind mapping = Get(index, left, right);
|
||||||
game.Input.Keys[mapping] = key;
|
game.Input.Keys[mapping] = key;
|
||||||
curWidget.SetText(ButtonText(index));
|
curWidget.SetText(ButtonText(index));
|
||||||
|
|
|
@ -149,7 +149,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
bool canShow = input == null && selectedWidget != null && descriptions != null;
|
bool canShow = input == null && selectedWidget != null && descriptions != null;
|
||||||
if (!canShow) return;
|
if (!canShow) return;
|
||||||
|
|
||||||
int index = Array.IndexOf<Widget>(widgets, selectedWidget);
|
int index = IndexOfWidget(selectedWidget);
|
||||||
if (index < 0 || index >= descriptions.Length) return;
|
if (index < 0 || index >= descriptions.Length) return;
|
||||||
string[] desc = descriptions[index];
|
string[] desc = descriptions[index];
|
||||||
if (desc == null) return;
|
if (desc == null) return;
|
||||||
|
@ -186,7 +186,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
if (button == null) return;
|
if (button == null) return;
|
||||||
DisposeExtendedHelp();
|
DisposeExtendedHelp();
|
||||||
|
|
||||||
int index = Array.IndexOf<Widget>(widgets, button);
|
int index = IndexOfWidget(button);
|
||||||
MenuInputValidator validator = validators[index];
|
MenuInputValidator validator = validators[index];
|
||||||
if (validator is BooleanValidator) {
|
if (validator is BooleanValidator) {
|
||||||
string value = button.GetValue(game);
|
string value = button.GetValue(game);
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
if (descWidget != null) descWidget.Dispose();
|
if (descWidget != null) descWidget.Dispose();
|
||||||
if (button == null) return;
|
if (button == null) return;
|
||||||
|
|
||||||
string text = descriptions[Array.IndexOf<Widget>(widgets, button)];
|
string text = descriptions[IndexOfWidget(button)];
|
||||||
MakeDescWidget(text);
|
MakeDescWidget(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,13 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
protected Font titleFont, regularFont;
|
protected Font titleFont, regularFont;
|
||||||
protected FastColour backCol = new FastColour(60, 60, 60, 160);
|
protected FastColour backCol = new FastColour(60, 60, 60, 160);
|
||||||
|
|
||||||
|
protected int IndexOfWidget(Widget w) {
|
||||||
|
for (int i = 0; i < widgets.Length; i++) {
|
||||||
|
if (widgets[i] == w) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
protected void RenderMenuBounds() {
|
protected void RenderMenuBounds() {
|
||||||
gfx.Draw2DQuad(0, 0, game.Width, game.Height, backCol);
|
gfx.Draw2DQuad(0, 0, game.Width, game.Height, backCol);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
|
|
||||||
void OnYesClick(Game g, Widget w, MouseButton btn, int x, int y) {
|
void OnYesClick(Game g, Widget w, MouseButton btn, int x, int y) {
|
||||||
if (btn != MouseButton.Left) return;
|
if (btn != MouseButton.Left) return;
|
||||||
bool always = Array.IndexOf<Widget>(widgets, w) >= alwaysIndex;
|
bool always = IndexOfWidget(w) >= alwaysIndex;
|
||||||
|
|
||||||
if (yesClick != null) yesClick(this, always);
|
if (yesClick != null) yesClick(this, always);
|
||||||
Dispose();
|
Dispose();
|
||||||
|
@ -75,7 +75,7 @@ namespace ClassicalSharp.Gui.Screens {
|
||||||
|
|
||||||
void OnNoClick(Game g, Widget w, MouseButton btn, int x, int y) {
|
void OnNoClick(Game g, Widget w, MouseButton btn, int x, int y) {
|
||||||
if (btn != MouseButton.Left) return;
|
if (btn != MouseButton.Left) return;
|
||||||
bool always = Array.IndexOf<Widget>(widgets, w) >= alwaysIndex;
|
bool always = IndexOfWidget(w) >= alwaysIndex;
|
||||||
|
|
||||||
if (confirmNo && !confirmingMode) {
|
if (confirmNo && !confirmingMode) {
|
||||||
confirmingMode = true;
|
confirmingMode = true;
|
||||||
|
|
|
@ -78,12 +78,9 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="2D\Drawing\CanvasDrawer2D.cs" />
|
<Compile Include="2D\Drawing\CanvasDrawer2D.cs" />
|
||||||
<Compile Include="2D\Drawing\CanvasDrawer2D.Text.cs" />
|
|
||||||
<Compile Include="2D\Drawing\GdiPlusDrawer2D.Text.cs" />
|
|
||||||
<Compile Include="2D\Drawing\IDrawer2D.TextMC.cs" />
|
<Compile Include="2D\Drawing\IDrawer2D.TextMC.cs" />
|
||||||
<Compile Include="2D\GuiElement.cs" />
|
<Compile Include="2D\GuiElement.cs" />
|
||||||
<Compile Include="2D\IsometricBlockDrawer.cs" />
|
<Compile Include="2D\IsometricBlockDrawer.cs" />
|
||||||
<Compile Include="2D\Drawing\DrawTextArgs.cs" />
|
|
||||||
<Compile Include="2D\Drawing\GdiPlusDrawer2D.cs" />
|
<Compile Include="2D\Drawing\GdiPlusDrawer2D.cs" />
|
||||||
<Compile Include="2D\Drawing\IDrawer2D.cs" />
|
<Compile Include="2D\Drawing\IDrawer2D.cs" />
|
||||||
<Compile Include="2D\Screens\ChatScreen.cs" />
|
<Compile Include="2D\Screens\ChatScreen.cs" />
|
||||||
|
|
|
@ -119,7 +119,7 @@ namespace ClassicalSharp.Entities {
|
||||||
fetchedSkin = true;
|
fetchedSkin = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadedItem item;
|
Request item;
|
||||||
if (!game.AsyncDownloader.TryGetItem(SkinName, out item)) return;
|
if (!game.AsyncDownloader.TryGetItem(SkinName, out item)) return;
|
||||||
if (item == null || item.Data == null) { SetSkinAll(true); return; }
|
if (item == null || item.Data == null) { SetSkinAll(true); return; }
|
||||||
|
|
||||||
|
|
|
@ -112,21 +112,24 @@ namespace ClassicalSharp.Map {
|
||||||
NbtList list = new NbtList();
|
NbtList list = new NbtList();
|
||||||
list.ChildTagId = (NbtTagType)reader.ReadByte();
|
list.ChildTagId = (NbtTagType)reader.ReadByte();
|
||||||
list.ChildrenValues = new object[ReadInt32()];
|
list.ChildrenValues = new object[ReadInt32()];
|
||||||
for (int i = 0; i < list.ChildrenValues.Length; i++)
|
for (int i = 0; i < list.ChildrenValues.Length; i++) {
|
||||||
list.ChildrenValues[i] = ReadTag((byte)list.ChildTagId, false).Value;
|
list.ChildrenValues[i] = ReadTag((byte)list.ChildTagId, false).Value;
|
||||||
|
}
|
||||||
tag.Value = list; break;
|
tag.Value = list; break;
|
||||||
|
|
||||||
case NbtTagType.Compound:
|
case NbtTagType.Compound:
|
||||||
Dictionary<string, NbtTag> children = new Dictionary<string, NbtTag>();
|
Dictionary<string, NbtTag> children = new Dictionary<string, NbtTag>();
|
||||||
NbtTag child;
|
NbtTag child;
|
||||||
while ((child = ReadTag(reader.ReadByte(), true)).TagId != NbtTagType.Invalid)
|
while ((child = ReadTag(reader.ReadByte(), true)).TagId != NbtTagType.Invalid) {
|
||||||
children[child.Name] = child;
|
children[child.Name] = child;
|
||||||
|
}
|
||||||
tag.Value = children; break;
|
tag.Value = children; break;
|
||||||
|
|
||||||
case NbtTagType.Int32Array:
|
case NbtTagType.Int32Array:
|
||||||
int[] array = new int[ReadInt32()];
|
int[] array = new int[ReadInt32()];
|
||||||
for (int i = 0; i < array.Length; i++)
|
for (int i = 0; i < array.Length; i++) {
|
||||||
array[i] = ReadInt32();
|
array[i] = ReadInt32();
|
||||||
|
}
|
||||||
tag.Value = array; break;
|
tag.Value = array; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace ClassicalSharp {
|
||||||
|
|
||||||
protected void WarningScreenTick(Overlay warning) {
|
protected void WarningScreenTick(Overlay warning) {
|
||||||
string identifier = warning.Metadata;
|
string identifier = warning.Metadata;
|
||||||
DownloadedItem item;
|
Request item;
|
||||||
if (!game.AsyncDownloader.TryGetItem(identifier, out item) || item.Data == null) return;
|
if (!game.AsyncDownloader.TryGetItem(identifier, out item) || item.Data == null) return;
|
||||||
|
|
||||||
long contentLength = (long)item.Data;
|
long contentLength = (long)item.Data;
|
||||||
|
@ -130,7 +130,7 @@ namespace ClassicalSharp {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void CheckAsyncResources() {
|
protected void CheckAsyncResources() {
|
||||||
DownloadedItem item;
|
Request item;
|
||||||
if (game.AsyncDownloader.TryGetItem("terrain", out item)) {
|
if (game.AsyncDownloader.TryGetItem("terrain", out item)) {
|
||||||
TexturePack.ExtractTerrainPng(game, item);
|
TexturePack.ExtractTerrainPng(game, item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace ClassicalSharp.Network.Protocols {
|
||||||
internal bool sendWomId = false, sentWomId = false;
|
internal bool sendWomId = false, sentWomId = false;
|
||||||
|
|
||||||
public override void Tick() {
|
public override void Tick() {
|
||||||
DownloadedItem item;
|
Request item;
|
||||||
game.AsyncDownloader.TryGetItem(womEnvIdentifier, out item);
|
game.AsyncDownloader.TryGetItem(womEnvIdentifier, out item);
|
||||||
if (item != null && item.Data != null) {
|
if (item != null && item.Data != null) {
|
||||||
ParseWomConfig((string)item.Data);
|
ParseWomConfig((string)item.Data);
|
||||||
|
|
|
@ -22,10 +22,10 @@ namespace ClassicalSharp.Network {
|
||||||
|
|
||||||
EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset);
|
EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||||
Thread worker;
|
Thread worker;
|
||||||
readonly object requestLocker = new object();
|
readonly object pendingLocker = new object();
|
||||||
List<Request> requests = new List<Request>();
|
List<Request> pending = new List<Request>();
|
||||||
readonly object downloadedLocker = new object();
|
readonly object processedLocker = new object();
|
||||||
Dictionary<string, DownloadedItem> downloaded = new Dictionary<string, DownloadedItem>();
|
List<Request> processed = new List<Request>();
|
||||||
string skinServer = null;
|
string skinServer = null;
|
||||||
readonly IDrawer2D drawer;
|
readonly IDrawer2D drawer;
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ namespace ClassicalSharp.Network {
|
||||||
public void Init(Game game) { Init(game.skinServer); }
|
public void Init(Game game) { Init(game.skinServer); }
|
||||||
public void Ready(Game game) { }
|
public void Ready(Game game) { }
|
||||||
public void Reset(Game game) {
|
public void Reset(Game game) {
|
||||||
lock (requestLocker)
|
lock (pendingLocker)
|
||||||
requests.Clear();
|
pending.Clear();
|
||||||
handle.Set();
|
handle.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,12 +113,12 @@ namespace ClassicalSharp.Network {
|
||||||
|
|
||||||
void AddRequest(string url, bool priority, string identifier,
|
void AddRequest(string url, bool priority, string identifier,
|
||||||
RequestType type, DateTime lastModified, string etag) {
|
RequestType type, DateTime lastModified, string etag) {
|
||||||
lock (requestLocker) {
|
lock (pendingLocker) {
|
||||||
Request request = new Request(url, identifier, type, lastModified, etag);
|
Request request = new Request(url, identifier, type, lastModified, etag);
|
||||||
if (priority) {
|
if (priority) {
|
||||||
requests.Insert(0, request);
|
pending.Insert(0, request);
|
||||||
} else {
|
} else {
|
||||||
requests.Add(request);
|
pending.Add(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handle.Set();
|
handle.Set();
|
||||||
|
@ -129,8 +129,8 @@ namespace ClassicalSharp.Network {
|
||||||
/// Note that this will *block** the calling thread as the method waits until the asynchronous
|
/// Note that this will *block** the calling thread as the method waits until the asynchronous
|
||||||
/// thread has exited the for loop. </summary>
|
/// thread has exited the for loop. </summary>
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
lock (requestLocker) {
|
lock (pendingLocker) {
|
||||||
requests.Insert(0, null);
|
pending.Insert(0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
handle.Set();
|
handle.Set();
|
||||||
|
@ -142,26 +142,14 @@ namespace ClassicalSharp.Network {
|
||||||
/// <summary> Removes older entries that were downloaded a certain time ago
|
/// <summary> Removes older entries that were downloaded a certain time ago
|
||||||
/// but were never removed from the downloaded queue. </summary>
|
/// but were never removed from the downloaded queue. </summary>
|
||||||
public void PurgeOldEntriesTask(ScheduledTask task) {
|
public void PurgeOldEntriesTask(ScheduledTask task) {
|
||||||
const int seconds = 10;
|
lock (processedLocker) {
|
||||||
lock (downloadedLocker) {
|
|
||||||
DateTime now = DateTime.UtcNow;
|
DateTime now = DateTime.UtcNow;
|
||||||
List<string> itemsToRemove = new List<string>(downloaded.Count);
|
for (int i = processed.Count - 1; i >= 0; i--) {
|
||||||
|
Request item = processed[i];
|
||||||
|
if ((now - item.TimeDownloaded).TotalSeconds < 10) continue;
|
||||||
|
|
||||||
foreach (var item in downloaded) {
|
item.Dispose();
|
||||||
DateTime timestamp = item.Value.TimeDownloaded;
|
processed.RemoveAt(i);
|
||||||
if ((now - timestamp).TotalSeconds > seconds) {
|
|
||||||
itemsToRemove.Add(item.Key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < itemsToRemove.Count; i++) {
|
|
||||||
string key = itemsToRemove[i];
|
|
||||||
DownloadedItem item;
|
|
||||||
downloaded.TryGetValue(key, out item);
|
|
||||||
downloaded.Remove(key);
|
|
||||||
Bitmap bmp = item.Data as Bitmap;
|
|
||||||
if (bmp != null)
|
|
||||||
bmp.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,13 +159,12 @@ namespace ClassicalSharp.Network {
|
||||||
/// If it does, it removes the item from the queue and outputs it. </summary>
|
/// If it does, it removes the item from the queue and outputs it. </summary>
|
||||||
/// <remarks> If the asynchronous thread failed to download the item, this method
|
/// <remarks> If the asynchronous thread failed to download the item, this method
|
||||||
/// will return 'true' and 'item' will be set. However, the contents of the 'item' object will be null.</remarks>
|
/// will return 'true' and 'item' will be set. However, the contents of the 'item' object will be null.</remarks>
|
||||||
public bool TryGetItem(string identifier, out DownloadedItem item) {
|
public bool TryGetItem(string identifier, out Request item) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
lock (downloadedLocker) {
|
lock (processedLocker) {
|
||||||
success = downloaded.TryGetValue(identifier, out item);
|
int i = FindRequest(identifier, out item);
|
||||||
if (success) {
|
success = i >= 0;
|
||||||
downloaded.Remove(identifier);
|
if (success) processed.RemoveAt(i);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -185,14 +172,14 @@ namespace ClassicalSharp.Network {
|
||||||
void DownloadThreadWorker() {
|
void DownloadThreadWorker() {
|
||||||
while (true) {
|
while (true) {
|
||||||
Request request = null;
|
Request request = null;
|
||||||
lock (requestLocker) {
|
lock (pendingLocker) {
|
||||||
if (requests.Count > 0) {
|
if (pending.Count > 0) {
|
||||||
request = requests[0];
|
request = pending[0];
|
||||||
requests.RemoveAt(0);
|
pending.RemoveAt(0);
|
||||||
if (request == null)
|
if (request == null) return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
CurrentItem = request;
|
CurrentItem = request;
|
||||||
CurrentItemProgress = -2;
|
CurrentItemProgress = -2;
|
||||||
|
@ -206,21 +193,30 @@ namespace ClassicalSharp.Network {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FindRequest(string identifer, out Request item) {
|
||||||
|
item = null;
|
||||||
|
for (int i = 0; i < processed.Count; i++) {
|
||||||
|
if (processed[i].Identifier != identifer) continue;
|
||||||
|
item = processed[i];
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessRequest(Request request) {
|
void ProcessRequest(Request request) {
|
||||||
string url = request.Url;
|
string url = request.Url;
|
||||||
Utils.LogDebug("Downloading {0} from: {1}", request.Type, url);
|
Utils.LogDebug("Downloading {0} from: {1}", request.Type, url);
|
||||||
object value = null;
|
|
||||||
HttpStatusCode status = HttpStatusCode.OK;
|
HttpStatusCode status = HttpStatusCode.OK;
|
||||||
string etag = null;
|
request.Data = null;
|
||||||
DateTime lastModified = DateTime.MinValue;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HttpWebRequest req = MakeRequest(request);
|
HttpWebRequest req = MakeRequest(request);
|
||||||
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse()) {
|
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse()) {
|
||||||
etag = response.Headers[HttpResponseHeader.ETag];
|
request.ETag = response.Headers[HttpResponseHeader.ETag];
|
||||||
if (response.Headers[HttpResponseHeader.LastModified] != null)
|
if (response.Headers[HttpResponseHeader.LastModified] != null) {
|
||||||
lastModified = response.LastModified;
|
request.LastModified = response.LastModified;
|
||||||
value = DownloadContent(request, response);
|
}
|
||||||
|
request.Data = DownloadContent(request, response);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
if (!(ex is WebException || ex is ArgumentException || ex is UriFormatException || ex is IOException)) throw;
|
if (!(ex is WebException || ex is ArgumentException || ex is UriFormatException || ex is IOException)) throw;
|
||||||
|
@ -239,24 +235,24 @@ namespace ClassicalSharp.Network {
|
||||||
Utils.LogDebug("Failed to download from: " + url);
|
Utils.LogDebug("Failed to download from: " + url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value = CheckIsValidImage(value, url);
|
|
||||||
|
|
||||||
lock (downloadedLocker) {
|
request.Data = CheckIsValidImage(request.Data, url);
|
||||||
DownloadedItem oldItem;
|
request.TimeDownloaded = DateTime.UtcNow;
|
||||||
DownloadedItem newItem = new DownloadedItem(value, request.TimeAdded, url,
|
|
||||||
status, etag, lastModified);
|
|
||||||
|
|
||||||
if (downloaded.TryGetValue(request.Identifier, out oldItem)) {
|
lock (processedLocker) {
|
||||||
if (oldItem.TimeAdded > newItem.TimeAdded) {
|
Request older;
|
||||||
DownloadedItem old = oldItem;
|
int index = FindRequest(request.Identifier, out older);
|
||||||
oldItem = newItem;
|
|
||||||
newItem = old;
|
if (index >= 0) {
|
||||||
|
if (older.TimeAdded > request.TimeAdded) {
|
||||||
|
Request tmp = older; older = request; request = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap oldBmp = oldItem.Data as Bitmap;
|
older.Dispose();
|
||||||
if (oldBmp != null) oldBmp.Dispose();
|
processed[index] = request;
|
||||||
|
} else {
|
||||||
|
processed.Add(request);
|
||||||
}
|
}
|
||||||
downloaded[request.Identifier] = newItem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,24 +328,24 @@ namespace ClassicalSharp.Network {
|
||||||
|
|
||||||
/// <summary> Full url to GET from. </summary>
|
/// <summary> Full url to GET from. </summary>
|
||||||
public string Url;
|
public string Url;
|
||||||
|
|
||||||
/// <summary> Unique identifier for this request. </summary>
|
/// <summary> Unique identifier for this request. </summary>
|
||||||
public string Identifier;
|
public string Identifier;
|
||||||
|
|
||||||
/// <summary> Type of data to return for this request. </summary>
|
/// <summary> Type of data to return for this request. </summary>
|
||||||
public RequestType Type;
|
public RequestType Type;
|
||||||
|
|
||||||
/// <summary> Point in time this request was added to the fetch queue. </summary>
|
/// <summary> Point in time this request was added to the fetch queue. </summary>
|
||||||
public DateTime TimeAdded;
|
public DateTime TimeAdded;
|
||||||
|
/// <summary> Point in time the item was fully downloaded. </summary>
|
||||||
|
public DateTime TimeDownloaded;
|
||||||
|
/// <summary> Contents that were downloaded. </summary>
|
||||||
|
public object Data;
|
||||||
|
|
||||||
/// <summary> Point in time the item most recently cached. (if at all) </summary>
|
/// <summary> Point in time the item most recently cached. (if at all) </summary>
|
||||||
public DateTime LastModified;
|
public DateTime LastModified;
|
||||||
|
|
||||||
/// <summary> ETag of the item most recently cached. (if any) </summary>
|
/// <summary> ETag of the item most recently cached. (if any) </summary>
|
||||||
public string ETag;
|
public string ETag;
|
||||||
|
|
||||||
public Request(string url, string identifier, RequestType type,
|
public Request(string url, string identifier, RequestType type, DateTime lastModified, string etag) {
|
||||||
DateTime lastModified, string etag) {
|
|
||||||
Url = url;
|
Url = url;
|
||||||
Identifier = identifier;
|
Identifier = identifier;
|
||||||
Type = type;
|
Type = type;
|
||||||
|
@ -357,38 +353,10 @@ namespace ClassicalSharp.Network {
|
||||||
LastModified = lastModified;
|
LastModified = lastModified;
|
||||||
ETag = etag;
|
ETag = etag;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Represents an item that was asynchronously downloaded. </summary>
|
public void Dispose() {
|
||||||
public class DownloadedItem {
|
Bitmap bmp = Data as Bitmap;
|
||||||
|
if (bmp != null) bmp.Dispose();
|
||||||
/// <summary> Contents that were downloaded. </summary>
|
|
||||||
public object Data;
|
|
||||||
|
|
||||||
/// <summary> Point in time the item was originally added to the download queue. </summary>
|
|
||||||
public DateTime TimeAdded;
|
|
||||||
|
|
||||||
/// <summary> Point in time the item was fully downloaded. </summary>
|
|
||||||
public DateTime TimeDownloaded;
|
|
||||||
|
|
||||||
/// <summary> Full URL this item was downloaded from. </summary>
|
|
||||||
public string Url;
|
|
||||||
|
|
||||||
/// <summary> Unique identifier assigned by the server to this item. </summary>
|
|
||||||
public string ETag;
|
|
||||||
|
|
||||||
/// <summary> Time the server indicates this item was last modified. </summary>
|
|
||||||
public DateTime LastModified;
|
|
||||||
|
|
||||||
public DownloadedItem(object data, DateTime timeAdded,
|
|
||||||
string url, HttpStatusCode code,
|
|
||||||
string etag, DateTime lastModified) {
|
|
||||||
Data = data;
|
|
||||||
TimeAdded = timeAdded;
|
|
||||||
TimeDownloaded = DateTime.UtcNow;
|
|
||||||
Url = url;
|
|
||||||
ETag = etag;
|
|
||||||
LastModified = lastModified;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -62,7 +62,7 @@ namespace ClassicalSharp.Textures {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static void ExtractTerrainPng(Game game, DownloadedItem item) {
|
internal static void ExtractTerrainPng(Game game, Request item) {
|
||||||
if (item.Data == null) return;
|
if (item.Data == null) return;
|
||||||
game.World.TextureUrl = item.Url;
|
game.World.TextureUrl = item.Url;
|
||||||
game.Events.RaiseTexturePackChanged();
|
game.Events.RaiseTexturePackChanged();
|
||||||
|
@ -101,7 +101,7 @@ namespace ClassicalSharp.Textures {
|
||||||
ms.Dispose();
|
ms.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ExtractTexturePack(Game game, DownloadedItem item) {
|
internal static void ExtractTexturePack(Game game, Request item) {
|
||||||
if (item.Data == null) return;
|
if (item.Data == null) return;
|
||||||
game.World.TextureUrl = item.Url;
|
game.World.TextureUrl = item.Url;
|
||||||
byte[] data = (byte[])item.Data;
|
byte[] data = (byte[])item.Data;
|
||||||
|
|
|
@ -57,15 +57,9 @@
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\ClassicalSharp\2D\Drawing\DrawTextArgs.cs">
|
|
||||||
<Link>Shared\DrawTextArgs.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\ClassicalSharp\2D\Drawing\GdiPlusDrawer2D.cs">
|
<Compile Include="..\ClassicalSharp\2D\Drawing\GdiPlusDrawer2D.cs">
|
||||||
<Link>Shared\GdiPlusDrawer2D.cs</Link>
|
<Link>Shared\GdiPlusDrawer2D.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\ClassicalSharp\2D\Drawing\GdiPlusDrawer2D.Text.cs">
|
|
||||||
<Link>Shared\GdiPlusDrawer2D.Text.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\ClassicalSharp\2D\Drawing\IDrawer2D.cs">
|
<Compile Include="..\ClassicalSharp\2D\Drawing\IDrawer2D.cs">
|
||||||
<Link>Shared\IDrawer2D.cs</Link>
|
<Link>Shared\IDrawer2D.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace Launcher.Patcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Download(string identifier, ref byte[] data, Action<string> setStatus) {
|
bool Download(string identifier, ref byte[] data, Action<string> setStatus) {
|
||||||
DownloadedItem item;
|
Request item;
|
||||||
if (downloader.TryGetItem(identifier, out item)) {
|
if (downloader.TryGetItem(identifier, out item)) {
|
||||||
FilesToDownload.RemoveAt(0);
|
FilesToDownload.RemoveAt(0);
|
||||||
Console.WriteLine("got resource " + identifier);
|
Console.WriteLine("got resource " + identifier);
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Launcher.Patcher {
|
||||||
public bool CheckDownloaded(ResourceFetcher fetcher, Action<string> setStatus) {
|
public bool CheckDownloaded(ResourceFetcher fetcher, Action<string> setStatus) {
|
||||||
if (Done) return true;
|
if (Done) return true;
|
||||||
for (int i = 0; i < identifiers.Length; i++) {
|
for (int i = 0; i < identifiers.Length; i++) {
|
||||||
DownloadedItem item;
|
Request item;
|
||||||
if (fetcher.downloader.TryGetItem(identifiers[i], out item)) {
|
if (fetcher.downloader.TryGetItem(identifiers[i], out item)) {
|
||||||
fetcher.FilesToDownload.RemoveAt(0);
|
fetcher.FilesToDownload.RemoveAt(0);
|
||||||
Console.WriteLine("got sound " + identifiers[i]);
|
Console.WriteLine("got sound " + identifiers[i]);
|
||||||
|
|
Loading…
Add table
Reference in a new issue