// zlib/libpng License // // Copyright (c) 2018 Sinoa // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it freely, // subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. // If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. // 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. // 3. This notice may not be removed or altered from any source distribution. using System; using System.Collections; using UnityEngine; namespace IceMilkTea.Core { /// /// UnityのMonoBehaviourでしか得られないイベントを引き込むためのコンポーネントクラスです /// internal class MonoBehaviourEventBridge : MonoBehaviour { // 以下メンバ変数定義 private WaitForEndOfFrame waitForEndOfFrame; private Action onApplicationFocusFunction; private Action onApplicationPauseFunction; private Action onEndOfFrame; /// /// 対象のゲームオブジェクトに MonoBehaviourEventBridge コンポーネントを新規アタッチを行い初期化を行います /// /// アタッチする対象のゲームオブジェクト /// 新規でアタッチした MonoBehaviourEventBridge のインスタンスを返します /// targetGameObject が null です public static MonoBehaviourEventBridge Attach(GameObject targetGameObject) { // nullなゲームオブジェクトを渡されたら if (targetGameObject == null) { // そんなことは許さない throw new ArgumentNullException(nameof(targetGameObject)); } // 自身をアタッチして初期化をする var component = targetGameObject.AddComponent(); component.waitForEndOfFrame = new WaitForEndOfFrame(); component.onApplicationFocusFunction = new Action(_ => { }); component.onApplicationPauseFunction = new Action(_ => { }); component.onEndOfFrame = new Action(() => { }); // コルーチンを開始する component.StartCoroutine(component.DoEndOfFrameLoop()); // インスペクタから姿を消して返す component.hideFlags = HideFlags.HideInInspector; return component; } /// /// OnApplicationFocusを実行する関数を設定します /// /// OnApplicationFocusを実行する関数 /// focusFunction が null です public void SetApplicationFocusFunction(Action focusFunction) { // null が渡されたら if (focusFunction == null) { // 許さない throw new ArgumentNullException(nameof(focusFunction)); } // 新しい関数を受け取る onApplicationFocusFunction = focusFunction; } /// /// OnApplicationPauseを実行する関数を設定します /// /// OnApplicationPauseを実行する関数 /// pauseFunction が null です public void SetApplicationPauseFunction(Action pauseFunction) { // null が渡されたら if (pauseFunction == null) { // 許さない throw new ArgumentNullException(nameof(pauseFunction)); } // 新しい関数を受け取る onApplicationPauseFunction = pauseFunction; } /// /// WaitForEndOfFrameの継続関数を設定します /// /// WaitForEndOfFrameの継続を行う関数 /// endOfFrameFunction が null です public void SetEndOfFrameFunction(Action endOfFrameFunction) { // null が渡されたら if (endOfFrameFunction == null) { // 許さない throw new ArgumentNullException(nameof(endOfFrameFunction)); } // 新しい関数を受け取る onEndOfFrame = endOfFrameFunction; } /// /// コンポーネントが破棄される時の処理を実行します /// private void OnDestroy() { // 関数の参照を殺す onApplicationFocusFunction = null; onApplicationPauseFunction = null; onEndOfFrame = null; } /// /// ゲームアプリケーションがウィンドウなどプレイヤーのフォーカスの状態が変化したときの処理を行います /// /// フォーカスを得られたときはtrueを、失ったときはfalse private void OnApplicationFocus(bool focus) { // 本来実行したい関数を叩く onApplicationFocusFunction(focus); } /// /// ゲームアプリケーションの再生状態が変化したときの処理を行います /// /// 一時停止になったときはtrueを、再生状態になったときはfalse private void OnApplicationPause(bool pause) { // 本来実行したい関数を叩く onApplicationPauseFunction(pause); } /// /// UnityのWaitForEndOfFrameの処理を永遠に実行し続けます /// /// WaitForEndOfFrame のインスタンスを常に返し続けます private IEnumerator DoEndOfFrameLoop() { // 無限ループ while (true) { // フレームの終端まで待機(描画の終端でゲームループの終端ではない)して関数を叩く yield return waitForEndOfFrame; onEndOfFrame(); } } } }