Skip to content

Instantly share code, notes, and snippets.

@dimmduh
Created September 8, 2018 12:21
Show Gist options
  • Save dimmduh/2a701cb32d887e28798e3f53b76aa857 to your computer and use it in GitHub Desktop.
Save dimmduh/2a701cb32d887e28798e3f53b76aa857 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using com.ootii.Messages;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.UI;
namespace DK.InGameEditor.Utils
{
public class MyMonoBehaviour : SerializedMonoBehaviour
{
private static readonly BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
private static readonly BindingFlags bindingFlagsStatic = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;
protected BoxCollider _boxCollider;
protected MeshRenderer _meshRenderer;
protected Rigidbody _rigidbody;
protected bool _wasAwake;
protected bool _wasStart;
protected bool _wasStartOnNextFrame;
private static bool _isStaticSingletonsLoaded;
//game specific singletons
[NonSerialized]
protected static z_InputManager z_InputManager;
[NonSerialized]
protected static z_GameManager z_GameManager;
[NonSerialized]
protected static z_CanvasGameplay z_CanvasGameplay;
[NonSerialized]
protected static z_CanvasBase z_CanvasBase;
[NonSerialized]
protected static z_WorldController z_WorldController;
[NonSerialized]
protected static z_BaseManager z_BaseManager;
[NonSerialized]
protected static z_FlyingTextManager z_FlyingTextManager;
[NonSerialized]
protected static z_SceneTransition z_SceneTransition;
[NonSerialized]
protected static z_LootManager z_LootManager;
[NonSerialized]
protected static z_ObjectPool z_ObjectPool;
[NonSerialized]
protected static z_PurchaseInfo z_PurchaseInfo;
[NonSerialized]
protected static z_Settings z_Settings;
[NonSerialized]
protected static z_CameraBase z_CameraBase;
[NonSerialized]
protected static z_AudioManager z_AudioManager;
//@todo fix it!!!!
//@todo it's logical error - helicopter is not need to be singleton
[NonSerialized]
protected static z_Helicopter z_Helicopter;
protected void Awake()
{
if (!_isStaticSingletonsLoaded)
{
_isStaticSingletonsLoaded = true;
AutoLoadStaticSingletons();
}
AutoLoadValuesSimple();
#if OOTII_MD
InitMessageDispatcher();
#endif
AfterAwake();
_wasAwake = true;
}
protected void Start()
{
// AutoLoadValues();
AfterStart();
StartCoroutine(StartOnNextFrameCoroutine());
_wasStart = true;
}
private IEnumerator StartOnNextFrameCoroutine()
{
yield return null;
StartOnNextFrame();
_wasStartOnNextFrame = true;
}
protected void AutoLoadStaticSingletons()
{
var fields = GetType().GetFields(bindingFlagsStatic);
foreach (var fieldInfo in fields)
{
var value = fieldInfo.GetValue(this);
if (value != null)
{
Debug.Log("Static value " + fieldInfo.Name + " is not empty");
continue;
}
var singleton = fieldInfo.FieldType.IsSubClassOfGeneric(typeof(Singleton<>));
if (singleton)
{
Debug.Log($"Load static singleton value {fieldInfo.FieldType}");
var propertyInfo = fieldInfo.FieldType.GetProperty("InstanceWithoutCreating", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
var propertyValue = propertyInfo.GetValue(null, null);
fieldInfo.SetValue(this, propertyValue);
}
else
{
Debug.Log($"Skip - load static - it's not a singleton {fieldInfo.FieldType}");
}
}
}
//check gameobject components and singletons
protected void AutoLoadValuesSimple()
{
var fields = GetType().GetFields(bindingFlags);
foreach (var fieldInfo in fields)
{
var nested = fieldInfo.FieldType.IsSubclassOf(typeof(Component))
|| fieldInfo.FieldType.IsSubclassOf(typeof(Graphic))
|| fieldInfo.FieldType.IsSubclassOf(typeof(Camera))
;
if (!nested)
continue;
var value = fieldInfo.GetValue(this);
if (value != null && !ReferenceEquals(value, null) && (((object) value) != null) && value != "null")
{
continue;
}
var singleton = fieldInfo.FieldType.IsSubClassOfGeneric(typeof(Singleton<>));
if (singleton)
{
Debug.Log($"Load singleton value {fieldInfo.FieldType}");
var propertyInfo = fieldInfo.FieldType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
var propertyValue = propertyInfo.GetValue(null, null);
fieldInfo.SetValue(this, propertyValue);
}
else
{
var comp = GetComponent(fieldInfo.FieldType);
if (comp)
{
fieldInfo.SetValue(this, comp);
}
}
}
}
#if OOTII_MD
private Dictionary<string, MessageHandler> listenMethods;
protected void InitMessageDispatcher()
{
var methods = GetType().GetMethods(bindingFlags)
.Where(m => m.GetCustomAttribute(typeof(ListenAttribute), true) != null)
.ToArray();
if (methods.Length == 0)
return;
listenMethods = new Dictionary<string, MessageHandler>(methods.Length);
foreach (var methodInfo in methods)
{
//validate method signature
var methodParameters = methodInfo.GetParameters();
if (methodParameters.Length == 0 || methodParameters[0].ParameterType != typeof(IMessage))
{
Debug.LogError($"Listen attribute - SKIP - validation failed on - {methodInfo.DeclaringType}.{methodInfo.Name}");
continue;
}
var attribute = methodInfo.GetCustomAttribute<ListenAttribute>();
listenMethods.Add(attribute.rType, message => methodInfo.Invoke(this, new object[] {message}));
// Debug.Log($"Detected listen method {methodInfo.Name} in {gameObject.name}");
}
}
private void AddMessageListeners()
{
foreach (var listenMethod in listenMethods)
{
// D($"Start listen {listenMethod.Key}");
MessageDispatcher.AddListener(listenMethod.Key, listenMethod.Value);
}
}
private void RemoveMessageListeners()
{
foreach (var listenMethod in listenMethods)
{
// D($"Stop listen {listenMethod.Key}");
MessageDispatcher.RemoveListener(listenMethod.Key, listenMethod.Value);
}
}
#endif
protected void OnEnable()
{
if (listenMethods != null)
AddMessageListeners();
AfterOnEnable();
}
protected void OnDisable()
{
if (listenMethods != null)
RemoveMessageListeners();
AfterOnDisable();
}
protected void AutoLoadValues()
{
var fields = GetType().GetFields(bindingFlags);
foreach (var fieldInfo in fields)
{
var value = fieldInfo.GetValue(this);
if (value != null)
{
// Debug.LogFormat("Search for {0} of type: {1} skipped because values is not null and equals {2}", fieldInfo.Name, fieldInfo.FieldType, value);
continue;
}
var nested = fieldInfo.FieldType.IsSubclassOf(typeof(Component));
if (nested)
{
// Debug.LogFormat("Searching for {0} of type: {1}", fieldInfo.Name, fieldInfo.FieldType.ToString());
{
// comp = (Component) FindObjectOfType(fieldInfo.FieldType);
// if (comp)
// {
// fieldInfo.SetValue(this, comp);
// }
}
}
else
{
// Debug.LogFormat("Search for {0} of type: {1} skipped because of it's not nested from unity", fieldInfo.Name, fieldInfo.FieldType);
}
}
}
protected virtual void AfterAwake()
{
}
protected virtual void StartOnNextFrame()
{
}
protected virtual void AfterStart()
{
}
protected virtual void AfterOnEnable()
{
}
protected virtual void AfterOnDisable()
{
}
public void D(object message)
{
Debug.Log(message);
}
protected bool HasRigidbody()
{
return _rigidbody != null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment