예제 #1
0
            /// <summary>
            /// 开始处理下载任务。
            /// </summary>
            /// <param name="task">要处理的下载任务。</param>
            public void Start(DownloadTask task)
            {
                if (task == null)
                {
                    throw new GameFrameworkException("Task is invalid.");
                }

                m_Task = task;

                m_Task.Status = DownloadTaskStatus.Doing;
                string downloadFile = string.Format("{0}.download", m_Task.DownloadPath);

                try
                {
                    if (File.Exists(downloadFile))
                    {
                        m_FileStream = File.OpenWrite(downloadFile);
                        m_FileStream.Seek(0, SeekOrigin.End);
                        m_StartLength      = m_SavedLength = (int)m_FileStream.Length;
                        m_DownloadedLength = 0;
                    }
                    else
                    {
                        string directory = Path.GetDirectoryName(m_Task.DownloadPath);
                        if (!Directory.Exists(directory))
                        {
                            Directory.CreateDirectory(directory);
                        }

                        m_FileStream  = new FileStream(downloadFile, FileMode.Create, FileAccess.Write);
                        m_StartLength = m_SavedLength = m_DownloadedLength = 0;
                    }

                    DownloadAgentStart?.Invoke(this);

                    if (m_StartLength > 0)
                    {
                        m_Helper.Download(m_Task.DownloadUri, m_StartLength, m_Task.UserData);
                    }
                    else
                    {
                        m_Helper.Download(m_Task.DownloadUri, m_Task.UserData);
                    }
                }
                catch (Exception exception)
                {
                    OnDownloadAgentHelperError(this, new DownloadAgentHelperErrorEventArgs(exception.Message));
                }
            }
예제 #2
0
            private void OnDownloadAgentHelperError(object sender, DownloadAgentHelperErrorEventArgs e)
            {
                m_Helper.Reset();
                if (m_FileStream != null)
                {
                    m_FileStream.Close();
                    m_FileStream = null;
                }

                m_Task.Status = DownloadTaskStatus.Error;

                DownloadAgentFailure?.Invoke(this, e.ErrorMessage);

                m_Task.Done = true;
            }
            private void OnDownloadSuccess(object sender, DownloadSuccessEventArgs e)
            {
                VersionListProcessor versionListProcessor = e.UserData as VersionListProcessor;

                if (versionListProcessor == null || versionListProcessor != this)
                {
                    return;
                }

                byte[] bytes = File.ReadAllBytes(e.DownloadPath);
                if (m_VersionListZipLength != bytes.Length)
                {
                    string errorMessage = string.Format("Latest version list zip length error, need '{0}', downloaded '{1}'.", m_VersionListZipLength.ToString(), bytes.Length.ToString());
                    OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                    return;
                }

                int hashCode = Utility.Converter.GetIntFromBytes(Utility.Verifier.GetCrc32(bytes));

                if (m_VersionListZipHashCode != hashCode)
                {
                    string errorMessage = string.Format("Latest version list zip hash code error, need '{0}', downloaded '{1}'.", m_VersionListZipHashCode.ToString("X8"), hashCode.ToString("X8"));
                    OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                    return;
                }

                try
                {
                    bytes = Utility.Zip.Decompress(bytes);
                }
                catch (Exception exception)
                {
                    string errorMessage = string.Format("Unable to decompress latest version list '{0}' with error message '{1}'.", e.DownloadPath, exception.Message);
                    OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                    return;
                }

                if (m_VersionListLength != bytes.Length)
                {
                    string errorMessage = string.Format("Latest version list length error, need '{0}', downloaded '{1}'.", m_VersionListLength.ToString(), bytes.Length.ToString());
                    OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                    return;
                }

                File.WriteAllBytes(e.DownloadPath, bytes);

                VersionListUpdateSuccess?.Invoke(e.DownloadPath, e.DownloadUri);
            }
            private void OnDownloadFailure(object sender, DownloadFailureEventArgs e)
            {
                VersionListProcessor versionListProcessor = e.UserData as VersionListProcessor;

                if (versionListProcessor == null || versionListProcessor != this)
                {
                    return;
                }

                if (File.Exists(e.DownloadPath))
                {
                    File.Delete(e.DownloadPath);
                }

                VersionListUpdateFailure?.Invoke(e.DownloadUri, e.ErrorMessage);
            }
예제 #5
0
        /// <summary>
        /// 界面销毁
        /// </summary>
        protected override void OnDestroy()
        {
            luaOnDestroy?.Invoke();

            luaOnInit         = null;
            luaOnOpen         = null;
            luaOnClose        = null;
            luaOnPause        = null;
            luaOnResume       = null;
            luaOnCover        = null;
            luaOnReveal       = null;
            luaOnRefocus      = null;
            luaOnUpdate       = null;
            luaOnDepthChanged = null;
            luaOnDestroy      = null;
            m_luaForm.Dispose();

            base.OnDestroy();
        }
예제 #6
0
        /// <summary>
        /// 界面销毁
        /// </summary>
        public override void Clear()
        {
            luaOnDestroy?.Invoke();

            luaOnInit         = null;
            luaOnOpen         = null;
            luaOnClose        = null;
            luaOnPause        = null;
            luaOnResume       = null;
            luaOnCover        = null;
            luaOnReveal       = null;
            luaOnRefocus      = null;
            luaOnUpdate       = null;
            luaOnDepthChanged = null;
            luaOnDestroy      = null;
            m_luaForm?.Dispose();

            base.Clear();
        }
 /// <summary>
 /// 资源更新器轮询。
 /// </summary>
 /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
 /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
 public void Update(float elapseSeconds, float realElapseSeconds)
 {
     if (m_UpdateAllowed && !m_UpdateComplete)
     {
         if (m_UpdateWaitingInfo.Count > 0)
         {
             if (m_DownloadManager.FreeAgentCount > 0)
             {
                 UpdateInfo updateInfo = m_UpdateWaitingInfo[0];
                 m_UpdateWaitingInfo.RemoveAt(0);
                 m_DownloadManager.AddDownload(updateInfo.DownloadPath, updateInfo.DownloadUri, updateInfo);
                 m_UpdatingCount++;
             }
         }
         else if (m_UpdatingCount <= 0)
         {
             m_UpdateComplete = true;
             Utility.Path.RemoveEmptyDirectory(m_ResourceManager.m_ReadWritePath);
             ResourceUpdateAllComplete?.Invoke();
         }
     }
 }
예제 #8
0
            /// <summary>
            /// 开始处理 Web 请求任务。
            /// </summary>
            /// <param name="task">要处理的 Web 请求任务。</param>
            public void Start(WebRequestTask task)
            {
                if (task == null)
                {
                    throw new GameFrameworkException("Task is invalid.");
                }

                m_Task = task;

                m_Task.Status = WebRequestTaskStatus.Doing;
                WebRequestAgentStart?.Invoke(this);

                if (m_Task.PostData == null)
                {
                    m_Helper.Request(m_Task.WebRequestUri, m_Task.UserData);
                }
                else
                {
                    m_Helper.Request(m_Task.WebRequestUri, m_Task.PostData, m_Task.UserData);
                }

                m_WaitTime = 0f;
            }
            /// <summary>
            /// 关闭连接并释放所有相关资源。
            /// </summary>
            public void Close()
            {
                if (m_Socket == null)
                {
                    return;
                }

                m_Active = false;
                try
                {
                    m_Socket.Shutdown(SocketShutdown.Both);
                }
                catch
                {
                }
                finally
                {
                    m_Socket.Close();
                    m_Socket       = null;
                    m_ReceiveState = null;

                    NetworkChannelClosed?.Invoke(this);
                }
            }
 public static void Handle <T1, T2>(
     this GameFrameworkAction <T1, T2> action,
     T1 arg1, T2 arg2)
 {
     action?.Invoke(arg1, arg2);
 }
예제 #11
0
 /// <summary>
 /// 界面暂停。
 /// </summary>
 protected override void OnPause()
 {
     base.OnPause();
     luaOnPause?.Invoke();
 }
            private void OnDownloadSuccess(object sender, DownloadSuccessEventArgs e)
            {
                UpdateInfo updateInfo = e.UserData as UpdateInfo;

                if (updateInfo == null)
                {
                    return;
                }

                bool zip = (updateInfo.Length != updateInfo.ZipLength || updateInfo.HashCode != updateInfo.ZipHashCode);

                byte[] bytes = File.ReadAllBytes(e.DownloadPath);

                if (updateInfo.ZipLength != bytes.Length)
                {
                    string errorMessage = string.Format("Zip length error, need '{0}', downloaded '{1}'.", updateInfo.ZipLength.ToString(), bytes.Length.ToString());
                    OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                    return;
                }

                if (!zip)
                {
                    byte[] hashBytes = Utility.Converter.GetBytesFromInt(updateInfo.HashCode);
                    if (updateInfo.LoadType == LoadType.LoadFromMemoryAndQuickDecrypt)
                    {
                        bytes = Utility.Encryption.GetQuickXorBytes(bytes, hashBytes);
                    }
                    else if (updateInfo.LoadType == LoadType.LoadFromMemoryAndDecrypt)
                    {
                        bytes = Utility.Encryption.GetXorBytes(bytes, hashBytes);
                    }
                }

                int hashCode = Utility.Converter.GetIntFromBytes(Utility.Verifier.GetCrc32(bytes));

                if (updateInfo.ZipHashCode != hashCode)
                {
                    string errorMessage = string.Format("Zip hash code error, need '{0}', downloaded '{1}'.", updateInfo.ZipHashCode.ToString("X8"), hashCode.ToString("X8"));
                    OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                    return;
                }

                if (zip)
                {
                    try
                    {
                        bytes = Utility.Zip.Decompress(bytes);
                    }
                    catch (Exception exception)
                    {
                        string errorMessage = string.Format("Unable to decompress from file '{0}' with error message '{1}'.", e.DownloadPath, exception.Message);
                        OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                        return;
                    }

                    if (updateInfo.Length != bytes.Length)
                    {
                        string errorMessage = string.Format("Resource length error, need '{0}', downloaded '{1}'.", updateInfo.Length.ToString(), bytes.Length.ToString());
                        OnDownloadFailure(this, new DownloadFailureEventArgs(e.SerialId, e.DownloadPath, e.DownloadUri, errorMessage, e.UserData));
                        return;
                    }

                    File.WriteAllBytes(e.DownloadPath, bytes);
                }

                m_UpdatingCount--;

                if (m_ResourceManager.m_ResourceInfos.ContainsKey(updateInfo.ResourceName))
                {
                    throw new GameFrameworkException(string.Format("Resource info '{0}' is already exist.", updateInfo.ResourceName.FullName));
                }

                m_ResourceManager.m_ResourceInfos.Add(updateInfo.ResourceName, new ResourceInfo(updateInfo.ResourceName, updateInfo.LoadType, updateInfo.Length, updateInfo.HashCode, false));

                if (m_ResourceManager.m_ReadWriteResourceInfos.ContainsKey(updateInfo.ResourceName))
                {
                    throw new GameFrameworkException(string.Format("Read-write resource info '{0}' is already exist.", updateInfo.ResourceName.FullName));
                }

                m_ResourceManager.m_ReadWriteResourceInfos.Add(updateInfo.ResourceName, new ReadWriteResourceInfo(updateInfo.LoadType, updateInfo.Length, updateInfo.HashCode));

                GenerateReadWriteList();

                ResourceUpdateSuccess?.Invoke(updateInfo.ResourceName, e.DownloadPath, e.DownloadUri, updateInfo.Length, updateInfo.ZipLength);
            }
 public static void Handle <T1, T2, T3, T4>(
     this GameFrameworkAction <T1, T2, T3, T4> action,
     T1 arg1, T2 arg2, T3 arg3, T4 arg4)
 {
     action?.Invoke(arg1, arg2, arg3, arg4);
 }
 public static void Handle <T1>(
     this GameFrameworkAction <T1> action,
     T1 arg1)
 {
     action?.Invoke(arg1);
 }
 public static void Handle <T1, T2, T3, T4, T5, T6>(
     this GameFrameworkAction <T1, T2, T3, T4, T5, T6> action,
     T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6)
 {
     action?.Invoke(arg1, arg2, arg3, arg4, arg5, arg6);
 }
 public static void Handle <T1, T2, T3, T4, T5, T6, T7, T8, T9>(
     this GameFrameworkAction <T1, T2, T3, T4, T5, T6, T7, T8, T9> action,
     T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9)
 {
     action?.Invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
 }
예제 #17
0
 /// <summary>
 /// 界面轮询。
 /// </summary>
 /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
 /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
 protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
 {
     base.OnUpdate(elapseSeconds, realElapseSeconds);
     luaOnUpdate?.Invoke(elapseSeconds, realElapseSeconds);
 }
예제 #18
0
 /// <summary>
 /// 界面遮挡恢复。
 /// </summary>
 protected override void OnReveal()
 {
     base.OnReveal();
     luaOnReveal?.Invoke();
 }
예제 #19
0
 /// <summary>
 /// 界面暂停恢复。
 /// </summary>
 protected override void OnResume()
 {
     base.OnResume();
     luaOnResume?.Invoke();
 }
 public static void Handle <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(this GameFrameworkAction <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13)
 {
     action?.Invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
 }
예제 #21
0
 /// <summary>
 /// 界面遮挡。
 /// </summary>
 protected override void OnCover()
 {
     base.OnCover();
     luaOnCover?.Invoke();
 }
            private bool Process()
            {
                if (m_ReceiveState.ReceivedLength != m_ReceiveState.Length)
                {
                    throw new GameFrameworkException(string.Format("Receive length '{0}' is not equal to length '{1}'.", m_ReceiveState.ReceivedLength.ToString(), m_ReceiveState.Length.ToString()));
                }

                if (m_ReceiveState.Length < ReceiveState.HeaderLength)
                {
                    throw new GameFrameworkException(string.Format("Length '{0}' is smaller than length header.", m_ReceiveState.Length.ToString()));
                }

                if (m_ReceiveState.Length == ReceiveState.HeaderLength)
                {
                    int packetLength = Utility.Converter.GetIntFromBytes(m_ReceiveState.Buffer);
                    if (packetLength <= 0)
                    {
                        string errorMessage = string.Format("Packet length '{0}' is invalid.", packetLength.ToString());
                        if (NetworkChannelError != null)
                        {
                            NetworkChannelError(this, NetworkErrorCode.HeaderError, errorMessage);
                            return(false);
                        }

                        throw new GameFrameworkException(errorMessage);
                    }

                    m_ReceiveState.Length += packetLength;
                    if (m_ReceiveState.Length > m_ReceiveState.BufferSize)
                    {
                        string errorMessage = string.Format("Length '{0}' is larger than buffer size '{1}'.", m_ReceiveState.Length.ToString(), m_ReceiveState.BufferSize.ToString());
                        if (NetworkChannelError != null)
                        {
                            NetworkChannelError(this, NetworkErrorCode.OutOfRangeError, errorMessage);
                            return(false);
                        }

                        throw new GameFrameworkException(errorMessage);
                    }

                    return(true);
                }

                lock (m_HeartBeatState)
                {
                    m_HeartBeatState.Reset(m_ResetHeartBeatElapseSecondsWhenReceivePacket);
                }

                Packet packet = null;

                try
                {
                    int    packetLength    = m_ReceiveState.Length - ReceiveState.HeaderLength;
                    object customErrorData = null;
                    using (MemoryStream memoryStream = new MemoryStream(m_ReceiveState.Buffer, ReceiveState.HeaderLength, packetLength, false))
                    {
                        lock (m_NetworkHelper)
                        {
                            packet = m_NetworkHelper.Deserialize(this, memoryStream, out customErrorData);
                        }
                    }

                    m_ReceiveState.Reset();
                    if (packet == null)
                    {
                        NetworkChannelCustomError?.Invoke(this, customErrorData);
                    }
                    else
                    {
                        NetworkChannelReceived?.Invoke(this, packet);
                    }
                }
                catch (Exception exception)
                {
                    m_Active = false;
                    if (NetworkChannelError != null)
                    {
                        NetworkChannelError(this, NetworkErrorCode.DeserializeError, string.Format("{0}\n{1}", exception.Message, exception.StackTrace));
                        return(false);
                    }

                    throw;
                }

                return(true);
            }
예제 #23
0
 /// <summary>
 /// 界面激活。
 /// </summary>
 /// <param name="userData">用户自定义数据。</param>
 protected override void OnRefocus(object userData)
 {
     base.OnRefocus(userData);
     luaOnRefocus?.Invoke();
 }
예제 #24
0
        private IEnumerator _check(Dictionary <string, string> headers)
        {
            var path = GameFramework.Utility.Path.GetRemotePath(Path.Combine(Application.streamingAssetsPath,
                                                                             ConstTable.VersionFileName));
            VersionInfo streamInfos;
            VersionInfo persistentInfos;
            VersionInfo serverInfos;
            VersionInfo version;

            using (WWW www = new WWW(path))
            {
                yield return(www);

                if (string.IsNullOrEmpty(www.error))
                {
                    version = _jieMi(www.bytes);
                    if (version == null)
                    {
                        streamInfos = new VersionInfo();
                    }
                    else
                    {
                        streamInfos = version;
                        _stateUpdate($"发现App资源版本,版本为:{streamInfos.Version}");
                    }
                }
                else
                {
                    streamInfos = new VersionInfo();
                }
            }

            var versionInfoFilePath = Path.Combine(Application.persistentDataPath, ConstTable.VersionFileName);

            if (File.Exists(versionInfoFilePath))
            {
                var versionInfoFileBy =
                    File.ReadAllBytes(versionInfoFilePath);
                version = _jieMi(versionInfoFileBy);
                if (version != null)
                {
                    persistentInfos = version;
                    persistentInfos.AssetBundleInfos.ForEach(x => x.PathType = VersionInfoPathType.ReadWritePath);
                    _stateUpdate($"发现本地资源版本,版本为:{persistentInfos.Version}");
                }
                else
                {
                    persistentInfos = new VersionInfo();
                }
            }
            else
            {
                persistentInfos = new VersionInfo();
            }


            PersistentInfos      = persistentInfos;
            StreamingVersionInfo = streamInfos;

            _persistentAssetBundleCheck();

            var localAllInfo = new VersionInfo(persistentInfos.Version,
                                               persistentInfos.AssetBundleInfos.Union(streamInfos.AssetBundleInfos).ToList());

            using (UnityWebRequest request = UnityWebRequest.Get(Url))
            {
                if (headers != null)
                {
                    foreach (var pair in headers)
                    {
                        request.SetRequestHeader(pair.Key, pair.Value);
                    }
                }
                request.downloadHandler = new DownloadHandlerBuffer();
                yield return(request.SendWebRequest());

                if (!string.IsNullOrEmpty(request.error))
                {
                    _stateUpdate($"资源版本检查失败!");
                    _errorHandle?.Invoke(request.error);
                    yield break;
                }

                version = _jieMi(request.downloadHandler.data);
                if (version == null)
                {
                    _stateUpdate($"资源版本检查失败!");
                    _errorHandle?.Invoke("解析服务器version.info失败.");
                    yield break;
                }
                serverInfos = version;
            }

            ServerVersionInfo = serverInfos;

            if (!_checkAppVersion())
            {
                var appUrl = _getAppUpdateUrl.Handle();
                if (!string.IsNullOrWhiteSpace(appUrl))
                {
                    Application.OpenURL(appUrl);
                }
                yield break;
            }

            List <AssetBundleInfo> result = _chckVersion(serverInfos, localAllInfo);

            _isInitCheck = true;
            _stateUpdate($"资源版本检查完成! 最新版本为:{ServerVersionInfo.Version}");
            _completeHandle?.Invoke(result);
        }
예제 #25
0
 /// <summary>
 /// 界面深度改变。
 /// </summary>
 /// <param name="uiGroupDepth">界面组深度。</param>
 /// <param name="depthInUIGroup">界面在界面组中的深度。</param>
 protected override void OnDepthChanged(int uiGroupDepth, int depthInUIGroup)
 {
     base.OnDepthChanged(uiGroupDepth, depthInUIGroup);
     luaOnDepthChanged?.Invoke(uiGroupDepth, depthInUIGroup);
 }
예제 #26
0
 void _stateUpdate(string str)
 {
     //todo 临时写法,后面加入国际化变为国际化
     _stateUpdateHandle?.Invoke(str);
 }
예제 #27
0
        /// <summary>
        /// 界面初始化。
        /// </summary>
        /// <param name="userData">用户自定义数据。</param>
        protected override void OnInit(object userData)
        {
            base.OnInit(userData);
            m_UserData = userData;

            m_luaEnv = GameEntry.Lua.LuaEnv;
            string luaFormName = GameEntry.FairyGui.GetLuaForm(m_FormId);

            if (string.IsNullOrEmpty(luaFormName))
            {
                Log.Error("luaForm is invalid. ID:{0}", m_FormId);
                return;
            }

            string assetName = AssetUtility.GetLuaAsset(luaFormName);
            string script    = string.Empty;

            if (GameEntry.Base.EditorResourceMode)
            {
                script = GameEntry.Resource.LoadTextAsset(assetName);
            }
            else
            {
                TextAsset asset = GameEntry.Resource.LoadAssetSync(assetName) as TextAsset;
                if (asset == null)
                {
                    Log.Error("Can no load Lua file:{0}", assetName);
                    return;
                }
                script = asset.text;
            }

            if (string.IsNullOrEmpty(script))
            {
                Log.Error("Lua script file is empty. file:{0}", assetName);
                return;
            }

            m_luaForm = m_luaEnv.NewTable();

            LuaTable meta = m_luaEnv.NewTable();

            meta.Set("__index", m_luaEnv.Global);
            m_luaForm.SetMetaTable(meta);
            meta.Dispose();

            m_luaForm.Set("self", this);
            m_luaEnv.DoString(script, luaFormName, m_luaForm);

            luaOnInit         = m_luaForm.Get <GameFrameworkAction <object> >("OnInit");
            luaOnOpen         = m_luaForm.Get <GameFrameworkAction <object> >("OnOpen");
            luaOnClose        = m_luaForm.Get <GameFrameworkAction <object> >("OnClose");
            luaOnPause        = m_luaForm.Get <GameFrameworkAction>("OnPause");
            luaOnResume       = m_luaForm.Get <GameFrameworkAction>("OnResume");
            luaOnCover        = m_luaForm.Get <GameFrameworkAction>("OnCover");
            luaOnReveal       = m_luaForm.Get <GameFrameworkAction>("OnReveal");
            luaOnRefocus      = m_luaForm.Get <GameFrameworkAction>("OnRefocus");
            luaOnUpdate       = m_luaForm.Get <GameFrameworkAction <float, float> >("OnUpdate");
            luaOnDepthChanged = m_luaForm.Get <GameFrameworkAction <int, int> >("OnDepthChanged");
            luaOnDestroy      = m_luaForm.Get <GameFrameworkAction>("OnDestroy");

            luaOnInit?.Invoke(userData);
        }
 public static void Handle(this GameFrameworkAction action)
 {
     action?.Invoke();
 }