Last active
June 14, 2021 18:03
-
-
Save jaredthirsk/38d797960b2df41e4718 to your computer and use it in GitHub Desktop.
Wire up a C# code-behind file to a NoesisGUI XAML file automatically, by convention and reflection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#define TRACE_XamlCodeBehind | |
#define WARN_XamlCodeBehind | |
// Installation Recommendation: Place this file as a loose C# file in your Unity Assets tree. | |
// Copyright: placed in Public Domain by Jared Thirsk, 2015 | |
// Note: Noesis plans to add code-behind support. Once they do this, this file should become obsolete. | |
// Created for NoesisGUI 1.2.3 | |
using Noesis; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text; | |
using UnityEngine; | |
public class XamlCodeBehind : MonoBehaviour | |
{ | |
public string CodeBehindClass; | |
private FrameworkElement content; | |
private object codebehindObject; | |
NoesisGUIPanel noesisGUI; | |
void Start() | |
{ | |
#region NoesisGUI | |
noesisGUI = GetComponent<NoesisGUIPanel>(); | |
if (noesisGUI == null) | |
{ | |
UnityEngine.Debug.LogWarning("[XamlCodeBehind] No NoesisGUIPanel attached to this object. Nothing for a XamlCodeBehind class to bind to."); | |
return; | |
} | |
var subpath = noesisGUI._xamlFile; | |
var filename = System.IO.Path.GetFileNameWithoutExtension(subpath); | |
#if TRACE_XamlCodeBehind | |
UnityEngine.Debug.Log("XamlFile: " + filename); | |
#endif | |
if (String.IsNullOrEmpty(CodeBehindClass)) | |
{ | |
#if trueX | |
string defaultNamespacePrefix = "LionFire.Gaxastar.Views."; | |
CodeBehindClass = defaultNamespacePrefix + filename; | |
#else | |
CodeBehindClass = filename; | |
#endif | |
} | |
#endregion | |
content = noesisGUI.GetContent(); | |
if(content==null) | |
{ | |
UnityEngine.Debug.LogError("Failed to get NoesisGUI content for " + noesisGUI._xamlFile); | |
return; | |
} | |
#if TRACE_XamlCodeBehind | |
else{ | |
UnityEngine.Debug.Log("Got NoesisGUI content: " + (content == null ? "null" : content.GetType().FullName)); | |
} | |
#endif | |
try | |
{ | |
Type codebehindType = Type.GetType(CodeBehindClass); | |
if (content == null) | |
{ | |
UnityEngine.Debug.LogError("Failed to get codebehind type for " + noesisGUI._xamlFile); | |
return; | |
} | |
#if TRACE_XamlCodeBehind | |
else{ | |
UnityEngine.Debug.Log("[XamlCodeBehind] Got code behind Type: " + (codebehindType == null ? "" : codebehindType.FullName)); | |
} | |
#endif | |
codebehindObject = Activator.CreateInstance(codebehindType, new object[] { content }); | |
foreach (var methodInfo in codebehindType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) | |
{ | |
if (!methodInfo.Name.Contains('_')) continue; | |
if (methodInfo.Name == "obj_address") continue; | |
var chunks = methodInfo.Name.Split('_'); | |
if (chunks.Length != 2) continue; | |
if (chunks[0] == "get" || chunks[0] == "set") continue; | |
if (chunks[0] == "add" || chunks[0] == "remove") continue; | |
object target = content.FindName(chunks[0]); | |
if (target == null) | |
{ | |
#if WARN_XamlCodeBehind | |
UnityEngine.Debug.LogWarning("[CODEBEHIND] Did not find element: " + chunks[0] + " for method: " + methodInfo.Name); | |
#endif | |
continue; | |
} | |
#if TRACE_XamlCodeBehind | |
else | |
{ | |
UnityEngine.Debug.Log("[codebehind] Found element: " + chunks[0]); | |
} | |
#endif | |
var eventInfo = target.GetType().GetEvent(chunks[1], BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); | |
if (eventInfo == null) | |
{ | |
#if WARN_XamlCodeBehind | |
UnityEngine.Debug.LogWarning("[CODEBEHIND] Did not find event: " + chunks[1] + " for method: " + methodInfo.Name + " on type " + target.GetType().FullName); | |
#endif | |
continue; | |
} | |
#if TRACE_XamlCodeBehind | |
else | |
{ | |
UnityEngine.Debug.Log("[codebehind] Found event: " + chunks[1]); | |
} | |
#endif | |
Delegate del = Delegate.CreateDelegate(eventInfo.EventHandlerType, codebehindObject, methodInfo); | |
try | |
{ | |
eventInfo.AddEventHandler(target, del); | |
} | |
catch (Exception ex) | |
{ | |
UnityEngine.Debug.LogError("[CODEBEHIND] Failed to attach event for method: " + methodInfo.Name + ". Event type: " + eventInfo.EventHandlerType.FullName + ", Delegate type: " + del.GetType().FullName + ", Delegate return type: " + methodInfo.ReturnType + " with parameter types: " + methodInfo.GetParameters().Select(p => p.ParameterType.FullName).Aggregate((x, y) => x + ", " + y) + " Exception: " + ex); | |
} | |
} | |
} | |
catch (Exception ex) | |
{ | |
UnityEngine.Debug.LogError("[CODEBEHIND] " + ex); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment