MVVM frame work done, under unit test

This commit is contained in:
Nitload
2024-07-25 04:41:24 +08:00
parent 924fe6eef7
commit da75200347
101 changed files with 8435 additions and 847 deletions
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace StgSharpDebug.Logic
{
#nullable enable
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate ref object BindingDataGetter();
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void BindingDataSetter(ref object value);
public unsafe struct DataBindingEntry
{
private IntPtr getterPtr, setterPtr;
public DataBindingEntry(
[NotNull] BindingDataGetter gettingCallback,
[NotNull] BindingDataSetter settingCallback)
{
getterPtr = Marshal.GetFunctionPointerForDelegate(gettingCallback);
setterPtr = Marshal.GetFunctionPointerForDelegate(settingCallback);
}
public ref object GetValue()
{
return ref ((delegate* unmanaged[Cdecl]<ref object>)getterPtr)();
}
public void SetData(ref object value)
{
((delegate* unmanaged[Cdecl]<ref object, void>)setterPtr)(ref value);
}
public static DataBindingEntry NullBinding
{
get => new DataBindingEntry();
}
public bool ExactEqual(DataBindingEntry other)
{
return getterPtr == other.getterPtr && setterPtr == other.setterPtr;
}
}
#nullable restore
}
@@ -9,40 +9,35 @@ namespace StgSharp.Logic
{
public abstract partial class ViewModelBase
{
public void ShowViewPort()
{
private View _nextView, _currentView;
protected View CurrentView
{
get => _currentView;
set => _nextView = value;
}
private Blueprint renderLogic;
/// <summary>
/// Render logic for every frame with no relation to <see cref="View"/>.
/// </summary>
public Blueprint GeneralRenderLogic
protected void UseViewInNextFrame(string name)
{
get => renderLogic;
set => renderLogic = value;
if (allView.TryGetValue(name, out View v))
{
throw new KeyNotFoundException($"Cannot find View named {name} " +
$"in current View Model of {this.GetType().FullName}");
}
CurrentView = v;
}
/// <summary>
/// Init this form and render it on screen, and respond with operation
/// CustomizeInit this form and render it on screen, and respond with operation
/// </summary>
public unsafe void Show()
{
BuildGlobalKeyControl();
CustomizeInitialize();
//BuildGlobalKeyControl();
while(0 == InternalIO.glfwWindowShouldClose(this.viewPortDisplay.ViewPortID))
{
viewPortDisplay.FlushSize();
foreach (var item in this._globalKeyAction)
{
if (InternalIO.glfwGetKey(this.viewPortDisplay.ViewPortID, (int)item.Key.TargetKeyOrButtonID)
== item.Key.TriggeredStatus)
{
item.Value();
}
}
BlueprintRunner.Run(renderLogic, ()=>ShouldClose);
CurrentView.Use();
RenderStream.PollEvents();
frameTimeProvider.WaitNextSpan();
Interlocked.Add(ref _frameCount, 1);
@@ -53,36 +48,10 @@ namespace StgSharp.Logic
{
if(0 == InternalIO.glfwWindowShouldClose(this.viewPortDisplay.ViewPortID))
{
frameTimeProvider.WaitNextSpan();
Interlocked.Add(ref _frameCount, 1);
viewPortDisplay.FlushSize();
foreach (var item in this._globalKeyAction)
{
if (InternalIO.glfwGetKey(this.viewPortDisplay.ViewPortID, (int)item.Key.TargetKeyOrButtonID)
== item.Key.TriggeredStatus)
{
item.Value();
}
}
BlueprintRunner.Run(renderLogic, () => ShouldClose);
CurrentView.Use();
RenderStream.PollEvents();
}
}
public T BuildNewRenderStream<T>(View arg, (int x, int y, int z) unitCubeSize) where T : RenderStream
{
if (arg.ContextName == this.Name)
{
}
T? ret = Activator.CreateInstance(typeof(T), arg) as T;
if (ret == null)
{
throw new InvalidOperationException("Failed in building a new RenderStream when calling AsMainStreamOf");
}
ret!.InternalInit();
ret.timeProvider = this.frameTimeProvider;
return ret;
}
}
}
@@ -1,31 +1,40 @@
using StgSharp.Graphics;
using StgSharp.Graphics.GL;
using StgSharp.Graphics.OpenGL;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Text;
namespace StgSharp.Logic
{
public partial class ViewModelBase
{
private List<View> allView;
private Dictionary<string,View> allView;
public View BuildNewView(
ViewPortDesigner designer, (int x, int y, int z) unitCubeSize
)
public T BuildNewView<T>(string name,(int x, int y, int z) unitCubeSize)
where T : View,new()
{
View ret = new View(this.viewPortDisplay, designer,unitCubeSize);
allView.Add(ret);
var ret = new T();
ret.SelfName = name;
ret.InternalInitialize(this);
allView.Add(name, ret);
return ret;
}
public T BuildRenderStream<T>(View view) where T : RenderStream
{
T ret = Activator.CreateInstance(typeof(T), view.Port, view.UnitCubeSize) as T ??
throw new InvalidOperationException("Cannot build new render stream.");
#nullable enable
T? ret = Activator.CreateInstance(typeof(T), view.Port, view.UnitCubeSize) as T;
#nullable restore
if (ret == null)
{
throw new InvalidOperationException(
$"Failed in creating a new {typeof(T).Name} instance when calling ShareContextWith."
);
}
ret.timeProvider = this.frameTimeProvider;
ret.InternalInit();
ret.PlatformSpecifiedInit();
return ret;
}
}
+115 -62
View File
@@ -30,13 +30,16 @@
//-----------------------------------------------------------------------
using StgSharp.Controlling.UsrActivity;
using StgSharp.Graphics;
using StgSharp.Graphics.GL;
using StgSharp.Graphics.OpenGL;
using StgSharp.Math;
using StgSharpDebug.Logic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@@ -64,7 +67,7 @@ namespace StgSharp.Logic
size: (800, 600),
monitor: IntPtr.Zero
);
allView = new List<View>();
allView = new();
fpsCountProvider = new TimeSpanProvider(1.0, TimeSpanProvider.DefaultProvider);
_frameSpeed = 0;
_frameCount = 0;
@@ -77,13 +80,35 @@ namespace StgSharp.Logic
() =>
{
};
_globalKeyAction = new Dictionary<KeyTrigger, Action>();
}
protected ViewModelBase(float frameLength)
{
viewPortDisplay = new ViewPort(
name: "Hello, Stg#!",
size: (800, 600),
monitor: IntPtr.Zero
);
allView = new();
fpsCountProvider = new TimeSpanProvider(1.0, TimeSpanProvider.DefaultProvider);
_frameSpeed = 0;
_frameCount = 0;
fpsCountProvider.SpanRefreshCallback = CountFps;
long _frameLength = (FrameSpeed > 0) ? ((long)(1000 * frameLength)) : 0;
frameTimeProvider = new TimeSpanProvider(
_frameLength, TimeSpanProvider.DefaultProvider
);
frameTimeProvider.SpanRefreshCallback =
() =>
{
};
}
public ViewModelBase(ViewPort vbinding, int framespeed)
{
viewPortDisplay = vbinding;
allView = new List<View>();
allView = new();
fpsCountProvider = new TimeSpanProvider(1.0, TimeSpanProvider.DefaultProvider);
_frameSpeed = 0;
_frameCount = 0;
@@ -96,12 +121,11 @@ namespace StgSharp.Logic
() =>
{
};
_globalKeyAction = new Dictionary<KeyTrigger, Action>();
viewPortDisplay.FrameSizeCallback = (handle, width, height)
=>
{
InternalIO.glfwMakeContextCurrent(viewPortDisplay.ViewPortID);
glFunc.Viewport(0, 0, width, height);
GlFunction.CurrentGL.Viewport(0, 0, width, height);
PrivateShow();
};
viewPortDisplay.FramePostionCallback = (handle, xpos, ypos)
@@ -111,14 +135,41 @@ namespace StgSharp.Logic
};
}
private void CountFps()
public ViewModelBase(ViewPort vbinding, float frameLength)
{
/**/
Console.Clear();
Console.WriteLine(FrameSpeed);
/**/
Interlocked.Exchange(ref _frameSpeed, _frameCount);
Interlocked.Exchange(ref _frameCount, 0);
viewPortDisplay = vbinding;
allView = new();
fpsCountProvider = new TimeSpanProvider(1.0, TimeSpanProvider.DefaultProvider);
_frameSpeed = 0;
_frameCount = 0;
fpsCountProvider.SpanRefreshCallback = CountFps;
long _frameLength = (frameLength > 0) ? ((long)(1000 * frameLength)) : 0;
frameTimeProvider = new TimeSpanProvider(
_frameLength, TimeSpanProvider.DefaultProvider
);
frameTimeProvider.SpanRefreshCallback =
() =>
{
};
viewPortDisplay.FrameSizeCallback = (handle, width, height)
=>
{
InternalIO.glfwMakeContextCurrent(viewPortDisplay.ViewPortID);
GlFunction.CurrentGL.Viewport(0, 0, width, height);
PrivateShow();
};
viewPortDisplay.FramePostionCallback = (handle, xpos, ypos)
=>
{
PrivateShow();
};
}
public bool ShouldClose
{
get => InternalIO.glfwWindowShouldClose(viewPortDisplay.ViewPortID) != 0;
set => InternalIO.glfwSetWindowShouldClose(viewPortDisplay.ViewPortID, value ? 1 : 0);
}
public int CurrentFrameCount => frameTimeProvider.CurrentSpan;
@@ -134,17 +185,37 @@ namespace StgSharp.Logic
set { viewPortDisplay.Height = value; }
}
/// <summary>
/// Width of this form, represent in <see cref="int"/>
/// </summary>
public int Width
{
get => viewPortDisplay.Width;
set
{
viewPortDisplay.Width = value;
if (WindowID != IntPtr.Zero)
{
InternalIO.glfwSetWindowSize(viewPortDisplay.ViewPortID, Width, Height);
}
}
}
public ViewPort ViewPortBinding
{
get => viewPortDisplay;
}
public unsafe IntPtr WindowID
{
get => viewPortDisplay.ViewPortID;
}
public string Name
{
get => viewPortDisplay.Name;
}
public bool ShouldClose
{
get => InternalIO.glfwWindowShouldClose(viewPortDisplay.ViewPortID) != 0;
set => InternalIO.glfwSetWindowShouldClose(viewPortDisplay.ViewPortID, value ? 1 : 0);
}
/// <summary>
/// Width of this form, represent in <see cref="int"/>
/// </summary>
@@ -162,28 +233,6 @@ namespace StgSharp.Logic
}
}
/// <summary>
/// Width of this form, represent in <see cref="int"/>
/// </summary>
public int Width
{
get => viewPortDisplay.Width;
set
{
viewPortDisplay.Width = value;
if (WindowID != IntPtr.Zero)
{
InternalIO.glfwSetWindowSize(viewPortDisplay.ViewPortID, Width, Height);
}
}
}
public unsafe IntPtr WindowID
{
get => viewPortDisplay.ViewPortID;
}
#pragma warning disable CA1044
protected FrameBufferSizeHandler FrameSizeCallback
{
@@ -196,6 +245,14 @@ namespace StgSharp.Logic
#pragma warning restore CA1044
public abstract bool TryGetObjectReference(string name,out DataBindingEntry entry);
public Action MethodLookup(string methodName)
{
MethodInfo method = GetType().GetMethod(methodName);
return (method != null) ? ((Action)Delegate.CreateDelegate(typeof(Action), this, method)) : null;
}
/// <summary>
/// Resize the current form
/// </summary>
@@ -209,7 +266,6 @@ namespace StgSharp.Logic
InternalIO.glfwSetWindowSize(this.viewPortDisplay.ViewPortID, (int)size.X, (int)size.Y);
}
/// <summary>
/// Set the size limit of current form
/// </summary>
@@ -244,33 +300,30 @@ namespace StgSharp.Logic
InternalIO.glfwSetWindowSizeLimits(this.viewPortDisplay.ViewPortID, minWidth, minHeight, maxWidth, maxHeight);
}
#region Key Control
protected KeyStatus CheckKey(KeyboardKey key)
private void CountFps()
{
return InternalIO.glfwGetKey(this.WindowID, (int)key);
/**/
Console.Clear();
Console.WriteLine(FrameSpeed);
/**/
Interlocked.Exchange(ref _frameSpeed, _frameCount);
Interlocked.Exchange(ref _frameCount, 0);
}
protected KeyStatus CheckKey(Mouse key)
public DataBindingEntry this[string name]
{
return InternalIO.glfwGetKey(this.WindowID, (int)key);
get
{
if (this.TryGetObjectReference(name, out DataBindingEntry entry))
{
return entry;
}
throw new KeyNotFoundException();
}
}
protected KeyStatus CheckKey(Joystick key)
{
return InternalIO.glfwGetKey(this.WindowID, (int)key);
}
public abstract void CustomizeInitialize();
#endregion
protected abstract void BuildGlobalKeyControl();
private Dictionary<KeyTrigger, Action> _globalKeyAction;
protected Dictionary<KeyTrigger, Action> GlobalKeyAction
{
get => _globalKeyAction;
}
}
}