using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; namespace StgSharp.Graphics { public abstract partial class Form { #region form thread setting private List frameAsyncThreadList; #endregion form thread setting /// /// Init this form and render it on screen, and respond with operation /// public unsafe void Show() { if (gl == null) { InternalIO.InternalWriteLog($"Attempt to show form {name} before init", LogType.Error); } else { frameTimeProvider = new TimeSpanProvider(1 / 60.0, TimeSpanProvider.DefaultProvider); MethodInfo[] methods = this.GetType().GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (methods.Length != 0) { foreach (MethodInfo m in methods) //find all methods decorated by RenderActivityAttribute { RenderActivityAttribute attr = m.GetCustomAttribute(false); if (attr == null) { continue; } if (!m.IsStatic && (m.GetParameters().Length != 0) && (m.ReturnType != typeof(void))) { throw new NotSupportedException("A render activity cannot have parameters, returning value or be static."); } if (m.Name != "Main") { ThreadStart s = (ThreadStart)Delegate.CreateDelegate(typeof(ThreadStart), this, m); FrameAsyncThread t = new(s,attr._priority); frameAsyncThreadList.Add(t); } } } List> threadGroup = frameAsyncThreadList.GroupBy((t) => t.Priority).ToList(); int priority = 0; foreach (var group in threadGroup) { foreach (var t in group) { t.Priority = priority; } priority++; } (Barrier, Barrier) b = FrameAsyncThread.CombineAsync(true, frameAsyncThreadList); FrameAsyncThread.AsyncStartAll(frameAsyncThreadList); if (b.Item1 == null) { while (!ShouldClose) { Main(); SwapBuffers(); PollEvents(); frameTimeProvider.WaitNextSpan(); Interlocked.Add(ref _frameCount, 1); } } else { while (!ShouldClose) { b.Item1.SignalAndWait(); Main(); b.Item2.SignalAndWait(); SwapBuffers(); PollEvents(); frameTimeProvider.WaitNextSpan(); Interlocked.Add(ref _frameCount, 1); } FrameAsyncThread.TerminateAll(frameAsyncThreadList); b.Item1.SignalAndWait(); FrameAsyncThread.WaitAll(frameAsyncThreadList); } //InternalDeinit(); } } } }