Skip to content

Instantly share code, notes, and snippets.

@Spartan322
Created February 20, 2020 22:30
Show Gist options
  • Save Spartan322/c5d4774bf1314ea15a9d421b9144581c to your computer and use it in GitHub Desktop.
Save Spartan322/c5d4774bf1314ea15a9d421b9144581c to your computer and use it in GitHub Desktop.
using System;
using System.Reflection;
using Godot;
using MSG.Source.Global.Attribute;
using MSG.Source.Utility;
using SpartansLib;
using SpartansLib.Extensions;
namespace MSG.Source
{
namespace Global
{
public class GlobalScript : Control
{
public static GlobalScript Singleton { get; private set; }
public delegate void GlobalScriptEvent(GlobalScript global);
public delegate void GlobalScriptEvent<T>(GlobalScript global, T arg1);
public static event GlobalScriptEvent OnInit;
public static event GlobalScriptEvent OnReady;
public static event GlobalScriptEvent OnDraw;
public static event GlobalScriptEvent OnEnterTree;
public static event GlobalScriptEvent OnExitTree;
public static event GlobalScriptEvent<InputEvent> OnInput;
public static event GlobalScriptEvent<InputEvent> OnUnhandledInput;
public static event GlobalScriptEvent<InputEventKey> OnUnhandledKeyInput;
public static event GlobalScriptEvent<float> OnProcess;
public static event GlobalScriptEvent<float> OnPhysicsProcess;
public static event GlobalScriptEvent<int> OnNotification;
public static event GlobalScriptEvent OnIdleFrame;
public static event UnhandledExceptionEventHandler OnUnhandledExeception;
static GlobalScript()
{
AppDomain.CurrentDomain.UnhandledException += CaptureUnhandledExeception;
foreach (var t in typeof(GlobalScript).Assembly.GetExportedTypes())
{
if (!(t.IsAbstract && t.IsSealed))
continue;
//RuntimeHelpers.RunClassConstructor(t.TypeHandle);
foreach (var m in t.GetMethods(BindingFlags.Public | BindingFlags.Static))
{
if (m.HasAttribute<ReadyAttribute>())
OnReady += m.CreateDelegate<GlobalScriptEvent>();
if (m.HasAttribute<InitAttribute>())
OnInit += m.CreateDelegate<GlobalScriptEvent>();
if (m.HasAttribute<DrawAttribute>())
OnDraw += m.CreateDelegate<GlobalScriptEvent>();
if (m.HasAttribute<EnterTreeAttribute>())
OnEnterTree += m.CreateDelegate<GlobalScriptEvent>();
if (m.HasAttribute<ExitTreeAttribute>())
OnExitTree += m.CreateDelegate<GlobalScriptEvent>();
if (m.HasAttribute<InputAttribute>())
OnInput += m.CreateDelegate<GlobalScriptEvent<InputEvent>>();
if (m.HasAttribute<UnhandledInputAttribute>())
OnUnhandledInput += m.CreateDelegate<GlobalScriptEvent<InputEvent>>();
if (m.HasAttribute<UnhandledKeyInputAttribute>())
OnUnhandledKeyInput += m.CreateDelegate<GlobalScriptEvent<InputEventKey>>();
if (m.HasAttribute<ProcessAttribute>())
OnProcess += m.CreateDelegate<GlobalScriptEvent<float>>();
if (m.HasAttribute<PhysicsProcessAttribute>())
OnPhysicsProcess += m.CreateDelegate<GlobalScriptEvent<float>>();
if (m.HasAttribute<NotificationAttribute>())
OnNotification += m.CreateDelegate<GlobalScriptEvent<int>>();
if (m.HasAttribute<IdleFrameAttribute>())
OnIdleFrame += m.CreateDelegate<GlobalScriptEvent>();
}
}
}
public override void _Ready()
{
PauseMode = PauseModeEnum.Process;
Singleton = this;
GetTree().Connect("idle_frame", this, nameof(_OnIdleFrame));
OnReady?.Invoke(this);
}
public GlobalScript() => OnInit?.Invoke(this);
public override void _Draw() => OnDraw?.Invoke(this);
public override void _EnterTree() => OnEnterTree?.Invoke(this);
public override void _ExitTree() => OnExitTree?.Invoke(this);
public override void _Input(InputEvent @event) => OnInput?.Invoke(this, @event);
public override void _UnhandledInput(InputEvent @event) => OnUnhandledInput?.Invoke(this, @event);
public override void _UnhandledKeyInput(InputEventKey @event) => OnUnhandledKeyInput?.Invoke(this, @event);
public override void _Process(float delta) => OnProcess?.Invoke(this, delta);
public override void _PhysicsProcess(float delta) => OnPhysicsProcess?.Invoke(this, delta);
public override void _Notification(int what) => OnNotification?.Invoke(this, what);
public void _OnIdleFrame() => OnIdleFrame?.Invoke(this);
private static void CaptureUnhandledExeception(object sender, UnhandledExceptionEventArgs arg)
{
OnUnhandledExeception?.Invoke(sender, arg);
Logger.Fatal($"Unhandled Mono Exeception Thrown '{arg.ExceptionObject.GetType().Name}':\n───────────────\n{arg.ExceptionObject}\n───────────────");
if (arg.IsTerminating) Logger.Fatal("Exeception Terminating");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment