//
// Copyright (C) 2014 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace GooglePlayGames.OurUtils
{
using System;
using System.Collections;
using UnityEngine;
using System.Collections.Generic;
public class PlayGamesHelperObject : MonoBehaviour
{
// our (singleton) instance
private static PlayGamesHelperObject instance = null;
// are we a dummy instance (used in the editor?)
private static bool sIsDummy = false;
// queue of actions to run on the game thread
private static List sQueue = new List();
// member variable used to copy actions from the sQueue and
// execute them on the game thread. It is a member variable
// to help minimize memory allocations.
List localQueue = new List();
// flag that alerts us that we should check the queue
// (we do this just so we don't have to lock() the queue every
// frame to check if it's empty or not).
private volatile static bool sQueueEmpty = true;
// callback for application pause and focus events
private static List> sPauseCallbackList =
new List>();
private static List> sFocusCallbackList =
new List>();
// Call this once from the game thread
public static void CreateObject()
{
if (instance != null)
{
return;
}
if (Application.isPlaying)
{
// add an invisible game object to the scene
GameObject obj = new GameObject("PlayGames_QueueRunner");
DontDestroyOnLoad(obj);
instance = obj.AddComponent();
}
else
{
instance = new PlayGamesHelperObject();
sIsDummy = true;
}
}
public void Awake()
{
DontDestroyOnLoad(gameObject);
}
public void OnDisable()
{
if (instance == this)
{
instance = null;
}
}
public static void RunCoroutine(IEnumerator action)
{
if (instance != null)
{
RunOnGameThread(() => instance.StartCoroutine(action));
}
}
public static void RunOnGameThread(System.Action action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
if (sIsDummy)
{
return;
}
lock (sQueue)
{
sQueue.Add(action);
sQueueEmpty = false;
}
}
public void Update()
{
if (sIsDummy || sQueueEmpty)
{
return;
}
// first copy the shared queue into a local queue
localQueue.Clear();
lock (sQueue)
{
// transfer the whole queue to our local queue
localQueue.AddRange(sQueue);
sQueue.Clear();
sQueueEmpty = true;
}
// execute queued actions (from local queue)
// use a loop to avoid extra memory allocations using the
// forEach
for (int i = 0; i < localQueue.Count; i++)
{
localQueue[i].Invoke();
}
}
public void OnApplicationFocus(bool focused)
{
foreach (Action cb in sFocusCallbackList)
{
try
{
cb(focused);
}
catch (Exception e)
{
Logger.e("Exception in OnApplicationFocus:" +
e.Message + "\n" + e.StackTrace);
}
}
}
public void OnApplicationPause(bool paused)
{
foreach (Action cb in sPauseCallbackList)
{
try
{
cb(paused);
}
catch (Exception e)
{
Logger.e("Exception in OnApplicationPause:" +
e.Message + "\n" + e.StackTrace);
}
}
}
///
/// Adds a callback that is called when the Unity method OnApplicationFocus
/// is called.
///
///
/// Callback.
public static void AddFocusCallback(Action callback)
{
if (!sFocusCallbackList.Contains(callback))
{
sFocusCallbackList.Add(callback);
}
}
///
/// Removes the callback from the list to call when handling OnApplicationFocus
/// is called.
///
/// true, if focus callback was removed, false otherwise.
/// Callback.
public static bool RemoveFocusCallback(Action callback)
{
return sFocusCallbackList.Remove(callback);
}
///
/// Adds a callback that is called when the Unity method OnApplicationPause
/// is called.
///
///
/// Callback.
public static void AddPauseCallback(Action callback)
{
if (!sPauseCallbackList.Contains(callback))
{
sPauseCallbackList.Add(callback);
}
}
///
/// Removes the callback from the list to call when handling OnApplicationPause
/// is called.
///
/// true, if focus callback was removed, false otherwise.
/// Callback.
public static bool RemovePauseCallback(Action callback)
{
return sPauseCallbackList.Remove(callback);
}
}
}