using System;
using System.Linq;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using CatLib;
using CatLib.Container;
using TinaX.Services;
using TinaX.Const;
using UniRx;
using TinaX.Container;
using System.Text;
using TinaX.Internal;
using TinaX.Systems.Configuration.Internal;
using TinaX.Systems.Configuration;
using TinaX.Systems.Configuration.CommandLine;
namespace TinaX
{
public class XCore : IXCore
{
#region instance and create
private static XCore _MainInstance;
private static object _lock_obj = new object();
public static IXCore MainInstance => _MainInstance;
public static IXCore New()
{
if (_MainInstance == null)
{
_MainInstance = new XCore();
return MainInstance;
}
else
return new XCore();
}
public static IXCore GetMainInstance() => XCore.MainInstance;
#endregion
public GameObject BaseGameObject { get; private set; }
public string FrameworkVersionName => FrameworkConst.Framework_VersionName;
///
/// 框架的沙箱存储路径
///
public string LocalStoragePath_TinaX => XCore.LocalStorage_TinaX;
public static string LocalStorage_TinaX => UnityEngine.Application.persistentDataPath + "/" + FrameworkConst.Framework_LocalStorage_TinaX;
///
/// App的沙箱存储路径(提供给业务逻辑开发者)
///
public string LocalStoragePath_App => XCore.LocalStorage_App;
public static string LocalStorage_App => UnityEngine.Application.persistentDataPath + "/" + FrameworkConst.Framework_LocalStorage_App;
public bool IsRunning { get; private set; } = false;
public string ProfileName { get; private set; } = FrameworkConst.DefaultProfileName;
public bool DevelopMode { get; private set; } = false;
public IServiceContainer Services => m_ServiceContainer;
///
/// Get game command line args.
///
public ICommandLineArgs CommandLineArgs => m_ArgsManager;
public IConfigurationBuilder ConfigurationBuilder => m_ConfigurationBuilder;
private bool m_Inited = false;
//private CatLib.Application mCatApp;
private List m_XServiceProvidersList = new List();
private List m_XBootstrapList = new List();
///
/// 服务初始化失败的事件注册, string:service name
///
private Action m_ServicesInitExceptionAction;
///
/// 服务启动失败的事件注册, string:service name
///
private Action m_ServicesStartExceptionAction;
private ServiceContainer m_ServiceContainer;
///
/// 是否尝试获取过IAppDomain
///
internal bool m_TryGetIAppDomain = false;
private IAppDomain m_IAppDomain;
private ArgsManager m_ArgsManager;
private ConfigurationBuilder m_ConfigurationBuilder;
public XCore()
{
if (_MainInstance == null)
{
lock (_lock_obj)
{
if (_MainInstance == null)
_MainInstance = this;
}
}
//mCatApp = CatLib.Application.New();
m_ServiceContainer = new ServiceContainer(this);
UnityEngine.Application.quitting += OnUnityQuit;
m_ArgsManager = new ArgsManager();
}
~XCore()
{
UnityEngine.Application.quitting -= OnUnityQuit;
}
#region Dependency Injection | 依赖注入
public IXCore RegisterServiceProvider(IXServiceProvider provider)
{
if (!m_XServiceProvidersList.Contains(provider))
m_XServiceProvidersList.Add(provider);
return this;
}
public void BindService()
{
m_ServiceContainer.Bind();
}
public void BindSingletonService()
{
m_ServiceContainer.Singleton();
}
public bool TryGetBuiltinService(out TBuiltInInterface service) where TBuiltInInterface: IBuiltInService
=> m_ServiceContainer.TryGetBuildInService(out service);
public TService GetService(params object[] userParams)
=> m_ServiceContainer.Get(userParams);
public object GetService(Type type, params object[] userParams)
=> m_ServiceContainer.Get(type, userParams);
public bool TryGetService(out TService service, params object[] userParams)
=> m_ServiceContainer.TryGet(out service, userParams);
public bool TryGetService(Type type, out object service, params object[] userParams)
=> m_ServiceContainer.TryGet(type, out service,userParams);
public IXCore ConfigureServices(Action options)
{
options?.Invoke(m_ServiceContainer);
return this;
}
///
/// 对传入的类进行依赖注入
///
///
public void InjectObject(object target)
=> m_ServiceContainer.Inject(target);
#endregion
#region Exceptions | 异常处理
public IXCore OnServicesInitException(Action callback)
{
m_ServicesInitExceptionAction += callback;
return this;
}
public IXCore OnServicesStartException(Action callback)
{
m_ServicesStartExceptionAction += callback;
return this;
}
#endregion
#region Domains
public object CreateInstance(Type type, params object[] args)
{
if (m_Inited)
{
if (!m_TryGetIAppDomain)
{
Services.TryGetBuildInService(out m_IAppDomain);
m_TryGetIAppDomain = true;
}
if (m_IAppDomain != null)
return m_IAppDomain.CreateInstance(type, args);
}
return Activator.CreateInstance(type, args);
}
public object CreateInstanceAndInject(Type type)
{
if (m_Inited)
{
if (!m_TryGetIAppDomain)
{
Services.TryGetBuildInService(out m_IAppDomain);
m_TryGetIAppDomain = true;
}
if (m_IAppDomain != null)
return m_IAppDomain.CreateInstanceAndInject(type);
}
return createInstanceAndInject(type);
}
private object createInstanceAndInject(Type type)
{
var ctors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance);
//找到可注入的ctor
foreach(var ctor in ctors)
{
var ctor_params = ctor.GetParameters();
List