This commit is contained in:
Javier Suárez 2022-11-04 18:00:48 +01:00
Родитель 055b2e910e
Коммит 0ab6ff39c7
8 изменённых файлов: 373 добавлений и 5 удалений

Просмотреть файл

@ -0,0 +1,134 @@
using System;
namespace AlohaKit.UI.Gallery.Helpers
{
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: Random
**
**
** Purpose: A random number generator.
**
**
===========================================================*/
/// <summary>
/// To have consistent behaviour of random generator across Runtimes (Mono, Core) and avoid changes to it in future releases src from Github repo is used instead of stock BCL class.
/// </summary>
public class Random2
{
//
// Private Constants
//
private const int MBIG = 2000000000;
private const int MSEED = 161803398;
//
// Member Variables
//
private int inext;
private int inextp;
private int[] SeedArray = new int[56];
//
// Public Constants
//
//
// Native Declarations
//
//
// Constructors
//
public Random2(int Seed)
{
int ii;
int mj, mk;
//Initialize our Seed array.
//This algorithm comes from Numerical Recipes in C (2nd Ed.)
int subtraction = (Seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(Seed);
mj = MSEED - subtraction;
SeedArray[55] = mj;
mk = 1;
for (int i = 1; i < 55; i++)
{ //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position.
ii = (21 * i) % 55;
SeedArray[ii] = mk;
mk = mj - mk;
if (mk < 0) mk += MBIG;
mj = SeedArray[ii];
}
for (int k = 1; k < 5; k++)
{
for (int i = 1; i < 56; i++)
{
SeedArray[i] -= SeedArray[1 + (i + 30) % 55];
if (SeedArray[i] < 0) SeedArray[i] += MBIG;
}
}
inext = 0;
inextp = 21;
}
//
// Package Private Methods
//
/*====================================Sample====================================
**Action: Return a new random number [0..1) and reSeed the Seed array.
**Returns: A double [0..1)
**Arguments: None
**Exceptions: None
==============================================================================*/
protected virtual double Sample()
{
//Including this division at the end gives us significantly improved
//random number distribution.
return (InternalSample() * (1.0 / MBIG));
}
private int InternalSample()
{
int retVal;
int locINext = inext;
int locINextp = inextp;
if (++locINext >= 56) locINext = 1;
if (++locINextp >= 56) locINextp = 1;
retVal = SeedArray[locINext] - SeedArray[locINextp];
if (retVal == MBIG) retVal--;
if (retVal < 0) retVal += MBIG;
SeedArray[locINext] = retVal;
inext = locINext;
inextp = locINextp;
return retVal;
}
//
// Public Instance Methods
//
/*=====================================Next=====================================
**Returns: A double [0..1)
**Arguments: None
**Exceptions: None
==============================================================================*/
public virtual double NextDouble()
{
return Sample();
}
}
}

Просмотреть файл

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AlohaKit.UI.Gallery.Views.LolBenchmarkPage"
xmlns:alohakit="clr-namespace:AlohaKit.UI;assembly=AlohaKit.UI"
Title="AlohaKit UI LOL's Benchmark">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<alohakit:CanvasView
x:Name="CanvasView"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0" />
<Grid
x:Name="GridLayout"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<Label
x:Name="LolLabel"
Grid.Row="0" Grid.Column="0"
Margin="0,20,0,0"
Padding="7,7,7,7"
BackgroundColor="Red"
TextColor="White"
VerticalOptions="Start"
HorizontalOptions="Center"
Text="Warming up..."
IsVisible="False"/>
<HorizontalStackLayout
x:Name="ButtonsLayout"
Grid.Row="1"
Grid.Column="0"
VerticalOptions="End"
HorizontalOptions="Center"
Margin="6">
<Button
x:Name="StopButton"
Text="Stop"
BackgroundColor="Red"
HorizontalOptions="Center"
IsVisible="False"
Clicked="OnStopButtonClicked"/>
<Button
x:Name="StartButton"
Text="Start"
BackgroundColor="Green"
Clicked="OnStartButtonClicked"/>
</HorizontalStackLayout>
</Grid>
</ContentPage>

Просмотреть файл

@ -0,0 +1,148 @@
using System.Diagnostics;
using AlohaKit.UI.Gallery.Helpers;
namespace AlohaKit.UI.Gallery.Views;
public partial class LolBenchmarkPage : ContentPage
{
public LolBenchmarkPage()
{
InitializeComponent();
}
volatile bool breakTest = false;
const int Max = 500;
void StartTestCanvasView()
{
var rand = new Random2(0);
breakTest = false;
var width = CanvasView.Width;
var height = CanvasView.Height;
const int step = 20;
var labels = new Label[step * 2];
var processed = 0;
long prevTicks = 0;
long prevMs = 0;
int prevProcessed = 0;
double avgSum = 0;
int avgN = 0;
var sw = new Stopwatch();
Action loop = null;
loop = () =>
{
var now = sw.ElapsedMilliseconds;
if (breakTest)
{
var avg = avgSum / avgN;
LolLabel.Text = string.Format("{0:0.00} LOL/s (AVG)", avg).PadLeft(21);
return;
}
// 60hz, 16ms to build the frame
while (sw.ElapsedMilliseconds - now < 16)
{
var label = new Label()
{
Text = "lol?",
TextColor = new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble()),
Rotation = (float)rand.NextDouble() * 360
};
label.X = (float)(rand.NextDouble() * width);
label.Y = (float)(rand.NextDouble() * height);
label.WidthRequest = 80f;
label.HeightRequest = 24f;
if (processed > Max)
{
CanvasView.Children.RemoveAt(0);
}
CanvasView.Children.Add(label);
CanvasView.Invalidate();
processed++;
if (sw.ElapsedMilliseconds - prevMs > 500)
{
var r = (processed - prevProcessed) / ((double)(sw.ElapsedTicks - prevTicks) / Stopwatch.Frequency);
prevTicks = sw.ElapsedTicks;
prevProcessed = processed;
if (processed > Max)
{
LolLabel.Text = string.Format("{0:0.00} LOL/s", r).PadLeft(15);
avgSum += r;
avgN++;
}
prevMs = sw.ElapsedMilliseconds;
}
}
Dispatcher.Dispatch(loop);
};
sw.Start();
loop();
}
void SetControlsAtStart()
{
StartButton.IsVisible = false;
StopButton.IsVisible = LolLabel.IsVisible = true;
CanvasView.Children.Clear();
GridLayout.Children.Clear();
LolLabel.Text = "Warming up...";
}
void OnStopButtonClicked(object sender, EventArgs e)
{
breakTest = true;
StopButton.IsVisible = false;
StartButton.IsVisible = true;
}
async void OnStartButtonClicked(object sender, EventArgs e)
{
int testLengthMs = 60000;
int pauseLengthMs = 100;
SetControlsAtStart();
StartTestCanvasView();
await Task.Delay(testLengthMs);
OnStopButtonClicked(default, default);
await Task.Delay(pauseLengthMs);
_ = decimal.TryParse(LolLabel.Text.Replace(" LOL/s (AVG)", "").Trim(), out var resultST);
var platformVersion = "AlohaKit UI";
#if ANDROID
var operatingSystem = "Android";
#elif IOS
var operatingSystem = "iOS";
#elif MACCATALYST
var operatingSystem = "MacCatalyst";
#elif WINDOWS
var operatingSystem = "WinUI";
#else
var operatingSystem = "Unknown";
#endif
var results = new { OS = operatingSystem, Platform = platformVersion, Build = resultST, Reuse = 0, Grid = 0 };
LolLabel.Text = $"Build: {results.Build}";
}
}

Просмотреть файл

@ -16,6 +16,9 @@
<Button
Text="Custom Drawn Controls"
Clicked="OnCustomControlsButtonClicked"/>
<Button
Text="LOL/s Benchmark"
Clicked="OnBenchmarkButtonClicked"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>

Просмотреть файл

@ -20,6 +20,11 @@
void OnCustomControlsButtonClicked(object sender, EventArgs e)
{
Navigation.PushAsync(new CustomControlsPage());
}
}
}
void OnBenchmarkButtonClicked(object sender, EventArgs e)
{
Navigation.PushAsync(new LolBenchmarkPage());
}
}
}

Просмотреть файл

@ -85,7 +85,7 @@ namespace AlohaKit.UI
}
canvas.Alpha = (float)Opacity;
canvas.Transform(TranslationX, TranslationY, ScaleX, ScaleY);
canvas.Transform(Rotation, TranslationX, TranslationY, ScaleX, ScaleY);
DrawShadow(canvas, bounds);

Просмотреть файл

@ -1,4 +1,6 @@
namespace AlohaKit.UI
using Microsoft.Maui.Devices.Sensors;
namespace AlohaKit.UI
{
public interface IVisualElement
{
@ -52,6 +54,10 @@
BindableProperty.Create(nameof(Shadow), typeof(Shadow), typeof(VisualElement), null,
propertyChanged: InvalidatePropertyChanged);
public static readonly BindableProperty RotationProperty =
BindableProperty.Create(nameof(Rotation), typeof(float), typeof(VisualElement), 0f,
propertyChanged: InvalidatePropertyChanged);
public static readonly BindableProperty TranslationXProperty =
BindableProperty.Create(nameof(TranslationX), typeof(float), typeof(VisualElement), 0f,
propertyChanged: InvalidatePropertyChanged);
@ -113,6 +119,12 @@
set => SetValue(ShadowProperty, value);
}
public float Rotation
{
get => (float)GetValue(RotationProperty);
set => SetValue(RotationProperty, value);
}
public float TranslationX
{
get => (float)GetValue(TranslationXProperty);

Просмотреть файл

@ -2,8 +2,9 @@
{
public static class CanvasExtensions
{
public static void Transform(this ICanvas canvas, float tX, float tY, float sX, float sY)
public static void Transform(this ICanvas canvas, float rotation, float tX, float tY, float sX, float sY)
{
canvas.Rotate(rotation);
canvas.Translate(tX, tY);
canvas.Scale(sX, sY);
}