// // /*===============================================================================
// // Copyright (C) 2022 PhantomsXR Ltd. All Rights Reserved.
// //
// // This file is part of the UnityFusion.Adapter.Runtime.
// //
// // The ARMOD-SDK cannot be copied, distributed, or made available to
// // third-parties for commercial purposes without written permission of PhantomsXR Ltd.
// //
// // Contact nswell@phantomsxr.com for licensing requests.
// // ===============================================================================*/
using System;
using JetBrains.Annotations;
using UnityFusion.CLR.Method;
using UnityFusion.Runtime.Enviorment;
using UnityFusion.Runtime.Intepreter;
using UnityEngine.EventSystems;
using Phantom.XRMOD.Core.Runtime;
using UnityEngine;
using AppDomain = UnityFusion.Runtime.Enviorment.AppDomain;
namespace UnityFusion.CLRBinding.Adapter
{
///
/// Adapter for the custom .
/// Handles specialized UI lifecycle and event systems for hot-reload UI components.
///
public class UIBehaviourAdaptor : CrossBindingAdaptor
{
public override Type BaseCLRType => typeof(UIMonoBehaviour);
public override Type AdaptorType => typeof(Adapter);
public override object CreateCLRInstance(AppDomain _appdomain, ILTypeInstance _instance)
{
return new Adapter(_appdomain, _instance);
}
///
/// The implementation class that bridges UIBehaviour messages and input events to the hot-reload domain.
///
public class Adapter : UIMonoBehaviour,CrossBindingAdaptorType, IDragHandler, IBeginDragHandler,
IEndDragHandler, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerClickHandler,
IPointerExitHandler, IPointerMoveHandler
{
CrossBindingMethodInfo mOnDrag_0 =
new CrossBindingMethodInfo("OnDrag");
CrossBindingMethodInfo mOnBeginDrag_1 =
new CrossBindingMethodInfo("OnBeginDrag");
CrossBindingMethodInfo mOnEndDrag_2 =
new CrossBindingMethodInfo("OnEndDrag");
CrossBindingMethodInfo mOnPointerDown_3 =
new CrossBindingMethodInfo("OnPointerDown");
CrossBindingMethodInfo mOnPointerUp_4 =
new CrossBindingMethodInfo("OnPointerUp");
CrossBindingMethodInfo mOnPointerEnter_5 =
new CrossBindingMethodInfo("OnPointerEnter");
CrossBindingMethodInfo mOnPointerClick_6 =
new CrossBindingMethodInfo("OnPointerClick");
CrossBindingMethodInfo mOnPointerExit_7 =
new CrossBindingMethodInfo("OnPointerExit");
CrossBindingMethodInfo mOnPointerMove_8 =
new CrossBindingMethodInfo("OnPointerMove");
protected ILTypeInstance instance;
protected AppDomain appdomain;
public Adapter(AppDomain _appdomain, ILTypeInstance _instance)
{
this.appdomain = _appdomain;
this.instance = _instance;
}
public ILTypeInstance ILInstance
{
get => instance;
set => instance = value;
}
public UnityFusion.Runtime.Enviorment.AppDomain AppDomain
{
get => appdomain;
set => appdomain = value;
}
public Adapter()
{
}
public void OnDrag(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnDrag_0.Invoke(this.instance, eventData);
}
public void OnBeginDrag(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnBeginDrag_1.Invoke(this.instance, eventData);
}
public void OnEndDrag(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnEndDrag_2.Invoke(this.instance, eventData);
}
public void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnPointerDown_3.Invoke(this.instance, eventData);
}
public void OnPointerUp(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnPointerUp_4.Invoke(this.instance, eventData);
}
public void OnPointerEnter(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnPointerEnter_5.Invoke(this.instance, eventData);
}
public void OnPointerClick(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnPointerClick_6.Invoke(this.instance, eventData);
}
public void OnPointerExit(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnPointerExit_7.Invoke(this.instance, eventData);
}
public void OnPointerMove(UnityEngine.EventSystems.PointerEventData eventData)
{
mOnPointerMove_8.Invoke(this.instance, eventData);
}
#region MonoCallback
object[] param0 = new object[0];
private bool destroyed = false;
IMethod awakeMethod;
bool awakeMethodGot;
private bool awaked = false;
public void Awake()
{
if (instance == null) return;
if (!awakeMethodGot)
{
awakeMethod = instance.Type.GetMethod("Awake", 0);
awakeMethodGot = true;
}
if (awakeMethod != null)
{
appdomain.Invoke(awakeMethod, instance, param0);
}
awaked = true;
if (gameObject.activeSelf)
OnEnable();
}
IMethod onEnableMethod;
bool onEnableMethodGot;
private bool onEnableInvoked;
private void OnEnable()
{
if (instance == null || destroyed || !awaked)
{
return;
}
if (!onEnableMethodGot)
{
onEnableMethod = instance.Type.GetMethod("OnEnable", 0);
onEnableMethodGot = true;
}
if (onEnableMethod != null && !onEnableInvoked)
{
onEnableInvoked = true;
appdomain.Invoke(onEnableMethod, instance, param0);
}
}
IMethod startMethod;
bool startMethodGot;
void Start()
{
if (instance == null || destroyed || !awaked) return;
if (!startMethodGot)
{
startMethod = instance.Type.GetMethod("Start", 0);
startMethodGot = true;
}
if (startMethod != null)
{
appdomain.Invoke(startMethod, instance, param0);
}
}
IMethod updateMethod;
bool updateMethodGot;
void Update()
{
if (instance == null || destroyed) return;
if (!updateMethodGot)
{
updateMethod = instance.Type.GetMethod("Update", 0);
updateMethodGot = true;
}
if (updateMethod != null)
{
appdomain.Invoke(updateMethod, instance, param0);
}
}
IMethod fixedUpdateMethod;
bool fixedUpdateMethodGot;
void FixedUpdate()
{
if (instance == null || destroyed) return;
if (!fixedUpdateMethodGot)
{
fixedUpdateMethod = instance.Type.GetMethod("FixedUpdate", 0);
fixedUpdateMethodGot = true;
}
if (fixedUpdateMethod != null)
{
appdomain.Invoke(fixedUpdateMethod, instance, param0);
}
}
IMethod lateUpdateMethod;
bool lateUpdateMethodGot;
void LateUpdate()
{
if (instance == null || destroyed) return;
if (!lateUpdateMethodGot)
{
lateUpdateMethod = instance.Type.GetMethod("LateUpdate", 0);
lateUpdateMethodGot = true;
}
if (lateUpdateMethod != null)
{
appdomain.Invoke(lateUpdateMethod, instance, param0);
}
}
IMethod onDestroyMethod;
bool onDestroyMethodGot;
private void OnDestroy()
{
if (instance == null || destroyed || appdomain == null) return;
if (!onDestroyMethodGot)
{
onDestroyMethod = instance.Type.GetMethod("OnDestroy", 0);
onDestroyMethodGot = true;
}
if (onDestroyMethod != null)
{
try
{
appdomain.Invoke(onDestroyMethod, instance, param0);
}
catch (Exception tmp_Exception)
{
Debug.LogError($"[{this.gameObject.name}]:{tmp_Exception}");
}
}
//To avoid null exception after destroy
destroyed = true;
}
IMethod onDisableMethod;
bool onDisableMethodGot;
private void OnDisable()
{
onEnableInvoked = false;
if (instance == null || destroyed) return;
if (!onDisableMethodGot)
{
onDisableMethod = instance.Type.GetMethod("OnDisable", 0);
onDisableMethodGot = true;
}
if (onDisableMethod != null)
{
appdomain.Invoke(onDisableMethod, instance, param0);
}
}
IMethod onApplicationFocusMethod;
bool onApplicationFocusMethodGot;
private void OnApplicationFocus(bool _hasFocus)
{
if (instance == null || destroyed) return;
if (!onApplicationFocusMethodGot)
{
onApplicationFocusMethod = instance.Type.GetMethod("OnApplicationFocus", 1);
onApplicationFocusMethodGot = true;
}
if (onApplicationFocusMethod != null)
{
appdomain.Invoke(onApplicationFocusMethod, instance, _hasFocus);
}
}
IMethod onApplicationPauseMethod;
bool onApplicationPauseMethodGot;
private void OnApplicationPause(bool _hasFocus)
{
if (instance == null || destroyed) return;
if (!onApplicationPauseMethodGot)
{
onApplicationPauseMethod = instance.Type.GetMethod("OnApplicationPause", 1);
onApplicationPauseMethodGot = true;
}
if (onApplicationPauseMethod != null)
{
appdomain.Invoke(onApplicationPauseMethod, instance, _hasFocus);
}
}
private IMethod onMouseDownMethod;
bool onMouseDownMethodGot;
private void OnMouseDown()
{
if (instance == null || destroyed) return;
if (!onMouseDownMethodGot)
{
onMouseDownMethod = instance.Type.GetMethod("OnMouseDown", 0);
onMouseDownMethodGot = true;
}
if (onMouseDownMethod != null)
{
appdomain.Invoke(onMouseDownMethod, instance);
}
}
private IMethod onMouseUpMethod;
bool onMouseUpMethodGot;
private void OnMouseUp()
{
if (instance == null || destroyed) return;
if (!onMouseUpMethodGot)
{
onMouseUpMethod = instance.Type.GetMethod(nameof(OnMouseUp), 0);
onMouseUpMethodGot = true;
}
if (onMouseUpMethod != null)
{
appdomain.Invoke(onMouseUpMethod, instance);
}
}
#endregion
#region Collider3D
IMethod onTriggerEnterMethod;
bool onTriggerEnterMethodGot;
private void OnTriggerEnter(Collider _collider)
{
if (instance == null || destroyed) return;
if (!onTriggerEnterMethodGot)
{
onTriggerEnterMethod = instance.Type.GetMethod("OnTriggerEnter", 1);
onTriggerEnterMethodGot = true;
}
if (onTriggerEnterMethod != null)
{
appdomain.Invoke(onTriggerEnterMethod, instance, _collider);
}
}
IMethod onTriggerStayMethod;
bool onTriggerStayMethodGot;
private void OnTriggerStay(Collider _collider)
{
if (instance == null || destroyed) return;
if (!onTriggerStayMethodGot)
{
onTriggerStayMethod = instance.Type.GetMethod("OnTriggerStay", 1);
onTriggerStayMethodGot = true;
}
if (onTriggerStayMethod != null)
{
appdomain.Invoke(onTriggerStayMethod, instance, _collider);
}
}
IMethod onTriggerExitMethod;
bool onTriggerExitMethodGot;
private void OnTriggerExit(Collider _collider)
{
if (instance == null || destroyed) return;
if (!onTriggerExitMethodGot)
{
onTriggerExitMethod = instance.Type.GetMethod("OnTriggerExit", 1);
onTriggerExitMethodGot = true;
}
if (onTriggerExitMethod != null)
{
appdomain.Invoke(onTriggerExitMethod, instance, _collider);
}
}
IMethod onCollisionEnterMethod;
bool onCollisionEnterMethodGot;
private void OnCollisionEnter(Collision _collision)
{
if (instance == null || destroyed) return;
if (!onCollisionEnterMethodGot)
{
onCollisionEnterMethod = instance.Type.GetMethod("OnCollisionEnter", 1);
onCollisionEnterMethodGot = true;
}
if (onCollisionEnterMethod != null)
{
appdomain.Invoke(onCollisionEnterMethod, instance, _collision);
}
}
IMethod onCollisionStayMethod;
bool onCollisionStayMethodGot;
private void OnCollisionStay(Collision _collision)
{
if (instance == null || destroyed) return;
if (!onCollisionStayMethodGot)
{
onCollisionStayMethod = instance.Type.GetMethod("OnCollisionStay", 1);
onCollisionStayMethodGot = true;
}
if (onCollisionStayMethod != null)
{
appdomain.Invoke(onCollisionStayMethod, instance, _collision);
}
}
IMethod onCollisionExitMethod;
bool onCollisionExitMethodGot;
private void OnCollisionExit(Collision _collision)
{
if (instance == null || destroyed) return;
if (!onCollisionExitMethodGot)
{
onCollisionExitMethod = instance.Type.GetMethod("OnCollisionExit", 1);
onCollisionExitMethodGot = true;
}
if (onCollisionExitMethod != null)
{
appdomain.Invoke(onCollisionExitMethod, instance, _collision);
}
}
#endregion
#region Collider2D
IMethod onTriggerEnter2DMethod;
bool onTriggerEnter2DMethodGot;
private void OnTriggerEnter2D(Collider2D _collider)
{
if (instance == null || destroyed) return;
if (!onTriggerEnter2DMethodGot)
{
onTriggerEnter2DMethod = instance.Type.GetMethod(nameof(OnTriggerEnter2D), 1);
onTriggerEnter2DMethodGot = true;
}
if (onTriggerEnter2DMethod != null)
{
appdomain.Invoke(onTriggerEnter2DMethod, instance, _collider);
}
}
IMethod onTriggerSta2DyMethod;
bool onTriggerStay2DMethodGot;
private void OnTriggerStay2D(Collider2D _collider)
{
if (instance == null || destroyed) return;
if (!onTriggerStay2DMethodGot)
{
onTriggerSta2DyMethod = instance.Type.GetMethod(nameof(OnTriggerStay2D), 1);
onTriggerStay2DMethodGot = true;
}
if (onTriggerSta2DyMethod != null)
{
appdomain.Invoke(onTriggerSta2DyMethod, instance, _collider);
}
}
IMethod onTriggerExit2DMethod;
bool onTriggerExit2DMethodGot;
private void OnTriggerExit2D(Collider2D _collider)
{
if (instance == null || destroyed) return;
if (!onTriggerExit2DMethodGot)
{
onTriggerExit2DMethod = instance.Type.GetMethod(nameof(OnTriggerExit2D), 1);
onTriggerExit2DMethodGot = true;
}
if (onTriggerExit2DMethodGot != null)
{
appdomain.Invoke(onTriggerExit2DMethod, instance, _collider);
}
}
IMethod onCollisionEnter2DMethod;
bool onCollisionEnter2DMethodGot;
private void OnCollisionEnter2D(Collision2D _collision)
{
if (instance == null || destroyed) return;
if (!onCollisionEnter2DMethodGot)
{
onCollisionEnter2DMethod = instance.Type.GetMethod(nameof(OnCollisionEnter2D), 1);
onCollisionEnter2DMethodGot = true;
}
if (onCollisionEnter2DMethod != null)
{
appdomain.Invoke(onCollisionEnter2DMethod, instance, _collision);
}
}
IMethod onCollisionStay2DMethod;
bool onCollisionStay2DMethodGot;
private void OnCollisionStay2D(Collision2D _collision)
{
if (instance == null || destroyed) return;
if (!onCollisionStay2DMethodGot)
{
onCollisionStayMethod = instance.Type.GetMethod(nameof(OnCollisionStay2D), 1);
onCollisionStay2DMethodGot = true;
}
if (onCollisionStay2DMethod != null)
{
appdomain.Invoke(onCollisionStay2DMethod, instance, _collision);
}
}
IMethod onCollisionExit2DMethod;
bool onCollisionExit2DMethodGot;
private void OnCollisionExit2D(Collision2D _collision)
{
if (instance == null || destroyed) return;
if (!onCollisionExit2DMethodGot)
{
onCollisionExit2DMethod = instance.Type.GetMethod(nameof(OnCollisionExit2D), 1);
onCollisionExit2DMethodGot = true;
}
if (onCollisionExit2DMethod != null)
{
appdomain.Invoke(onCollisionExit2DMethod, instance, _collision);
}
}
#endregion
#region Animator
IMethod onAnimatorIkMethod;
bool onAnimatorIkMethodGot;
public void OnAnimatorIK(int _layerIndex)
{
if (instance == null || destroyed) return;
if (!onAnimatorIkMethodGot)
{
onAnimatorIkMethod = instance.Type.GetMethod("OnAnimatorIK", 1);
onAnimatorIkMethodGot = true;
}
if (onAnimatorIkMethod != null)
{
appdomain.Invoke(onAnimatorIkMethod, instance, _layerIndex);
}
}
#endregion
#region Partical
private IMethod onParticleTriggerMethod;
bool onParticleMethodGot;
public void OnParticleTrigger()
{
if (instance == null || destroyed) return;
if (!onParticleMethodGot)
{
onParticleTriggerMethod = instance.Type.GetMethod("OnAnimatorIK", 0);
onParticleMethodGot = true;
}
if (onParticleTriggerMethod != null)
{
appdomain.Invoke(onParticleTriggerMethod, instance, null);
}
}
private IMethod onParticleCollisionMethod;
bool onParticleCollisionMethodGot;
public void OnParticleCollision([NotNull] GameObject _other)
{
if (instance == null || destroyed) return;
if (_other == null) throw new ArgumentNullException(nameof(_other));
if (!onParticleCollisionMethodGot)
{
onParticleCollisionMethod = instance.Type.GetMethod("OnParticleCollision", 1);
onParticleCollisionMethodGot = true;
}
if (onParticleCollisionMethod != null)
{
appdomain.Invoke(onParticleCollisionMethod, instance, _other);
}
}
#endregion
}
}
}