You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mapbox-sdk/Unity/MapboxAccess.cs

358 lines
8.7 KiB

6 months ago
using System.Collections;
using Mapbox.Unity.Utilities;
using MapboxAccountsUnity;
namespace Mapbox.Unity
{
using UnityEngine;
using System;
using System.IO;
using Mapbox.Geocoding;
using Mapbox.Directions;
using Mapbox.Platform;
using Mapbox.Platform.Cache;
using Mapbox.Unity.Telemetry;
using Mapbox.Map;
using Mapbox.MapMatching;
using Mapbox.Tokens;
using Mapbox.Platform.TilesetTileJSON;
/// <summary>
/// Object for retrieving an API token and making http requests.
/// Contains a lazy <see cref="T:Mapbox.Geocoding.Geocoder">Geocoder</see> and a lazy <see cref="T:Mapbox.Directions.Directions">Directions</see> for convenience.
/// </summary>
public class MapboxAccess : IFileSource
{
ITelemetryLibrary _telemetryLibrary;
CachingWebFileSource _fileSource;
public delegate void TokenValidationEvent(MapboxTokenStatus response);
public event TokenValidationEvent OnTokenValidation;
private static MapboxAccess _instance;
/// <summary>
/// The singleton instance.
/// </summary>
public static MapboxAccess Instance
{
get
{
if (_instance == null)
{
_instance = new MapboxAccess();
}
return _instance;
}
}
public static bool Configured;
public static string ConfigurationJSON;
private MapboxConfiguration _configuration;
private string _tokenNotSetErrorMessage = "No configuration file found! Configure your access token from the Mapbox > Setup menu.";
/// <summary>
/// The Mapbox API access token.
/// </summary>
public MapboxConfiguration Configuration
{
get
{
return _configuration;
}
}
MapboxAccess()
{
LoadAccessToken();
if (null == _configuration || string.IsNullOrEmpty(_configuration.AccessToken))
{
Debug.LogError(_tokenNotSetErrorMessage);
}
}
public void SetConfiguration(MapboxConfiguration configuration, bool throwExecptions = true)
{
if (configuration == null)
{
if (throwExecptions)
{
throw new InvalidTokenException(_tokenNotSetErrorMessage);
}
}
if (null == configuration || string.IsNullOrEmpty(configuration.AccessToken))
{
Debug.LogError(_tokenNotSetErrorMessage);
}
else
{
TokenValidator.Retrieve(configuration.GetMapsSkuToken, configuration.AccessToken, (response) =>
{
if (OnTokenValidation != null)
{
OnTokenValidation(response.Status);
}
if (response.Status != MapboxTokenStatus.TokenValid
&& throwExecptions)
{
configuration.AccessToken = string.Empty;
Debug.LogError(new InvalidTokenException(response.Status.ToString().ToString()));
}
});
_configuration = configuration;
ConfigureFileSource();
Debug.Log("starting location service");
Input.location.Start();
Runnable.Run(TelemetryDelay());
Configured = true;
}
}
private IEnumerator TelemetryDelay()
{
yield return new WaitForSeconds(5);
Debug.Log("starting configure telemetry");
Debug.Log(Input.location.status);
ConfigureTelemetry();
}
public void ClearAllCacheFiles()
{
// explicity call Clear() to close any connections that might be referenced by the current scene
CachingWebFileSource cwfs = _fileSource as CachingWebFileSource;
if (null != cwfs) { cwfs.Clear(); }
// remove all left over files (eg orphaned .journal) from the cache directory
string cacheDirectory = Path.Combine(Application.persistentDataPath, "cache");
if (!Directory.Exists(cacheDirectory)) { return; }
foreach (var file in Directory.GetFiles(cacheDirectory))
{
try
{
File.Delete(file);
}
catch (Exception deleteEx)
{
Debug.LogErrorFormat("Could not delete [{0}]: {1}", file, deleteEx);
}
}
//reinit caches after clear
if (null != cwfs) { cwfs.ReInit(); }
Debug.Log("done clearing caches");
}
/// <summary>
/// Loads the access token from <see href="https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity6.html">Resources folder</see>.
/// </summary>
private void LoadAccessToken()
{
if (string.IsNullOrEmpty(ConfigurationJSON))
{
TextAsset configurationTextAsset = Resources.Load<TextAsset>(Constants.Path.MAPBOX_RESOURCES_RELATIVE);
if (null == configurationTextAsset)
{
throw new InvalidTokenException(_tokenNotSetErrorMessage);
}
ConfigurationJSON = configurationTextAsset.text;
}
#if !WINDOWS_UWP
var test = JsonUtility.FromJson<MapboxConfiguration>(ConfigurationJSON);
SetConfiguration(ConfigurationJSON == null ? null : test);
#else
SetConfiguration(ConfigurationJSON == null ? null : Mapbox.Json.JsonConvert.DeserializeObject<MapboxConfiguration>(ConfigurationJSON));
#endif
}
void ConfigureFileSource()
{
_fileSource = new CachingWebFileSource(_configuration.AccessToken, _configuration.GetMapsSkuToken, _configuration.AutoRefreshCache)
.AddCache(new MemoryCache(_configuration.MemoryCacheSize))
#if !UNITY_WEBGL
.AddCache(new SQLiteCache(_configuration.FileCacheSize))
#endif
;
}
void ConfigureTelemetry()
{
// TODO: enable after token validation has been made async
//if (
// null == _configuration
// || string.IsNullOrEmpty(_configuration.AccessToken)
// || !_tokenValid
//)
//{
// Debug.LogError(_tokenNotSetErrorMessage);
// return;
//}
try
{
_telemetryLibrary = TelemetryFactory.GetTelemetryInstance();
_telemetryLibrary.Initialize(_configuration.AccessToken);
_telemetryLibrary.SetLocationCollectionState(GetTelemetryCollectionState());
_telemetryLibrary.SendTurnstile();
}
catch (Exception ex)
{
Debug.LogErrorFormat("Error initializing telemetry: {0}", ex);
}
}
public void SetLocationCollectionState(bool enable)
{
PlayerPrefs.SetInt(Constants.Path.SHOULD_COLLECT_LOCATION_KEY, (enable ? 1 : 0));
PlayerPrefs.Save();
_telemetryLibrary.SetLocationCollectionState(enable);
}
bool GetTelemetryCollectionState()
{
if (!PlayerPrefs.HasKey(Constants.Path.SHOULD_COLLECT_LOCATION_KEY))
{
PlayerPrefs.SetInt(Constants.Path.SHOULD_COLLECT_LOCATION_KEY, 1);
}
return PlayerPrefs.GetInt(Constants.Path.SHOULD_COLLECT_LOCATION_KEY) != 0;
}
/// <summary>
/// Makes an asynchronous url query.
/// </summary>
/// <returns>The request.</returns>
/// <param name="url">URL.</param>
/// <param name="callback">Callback.</param>
public IAsyncRequest Request(
string url
, Action<Response> callback
, int timeout = 10
, CanonicalTileId tileId = new CanonicalTileId()
, string tilesetId = null
)
{
return _fileSource.Request(url, callback, _configuration.DefaultTimeout, tileId, tilesetId);
}
Geocoder _geocoder;
/// <summary>
/// Lazy geocoder.
/// </summary>
public Geocoder Geocoder
{
get
{
if (_geocoder == null)
{
_geocoder = new Geocoder(new FileSource(Instance.Configuration.GetMapsSkuToken, _configuration.AccessToken));
}
return _geocoder;
}
}
Directions _directions;
/// <summary>
/// Lazy Directions.
/// </summary>
public Directions Directions
{
get
{
if (_directions == null)
{
_directions = new Directions(new FileSource(Instance.Configuration.GetMapsSkuToken, _configuration.AccessToken));
}
return _directions;
}
}
MapMatcher _mapMatcher;
/// <summary>
/// Lazy Map Matcher.
/// </summary>
public MapMatcher MapMatcher
{
get
{
if (_mapMatcher == null)
{
_mapMatcher = new MapMatcher(new FileSource(Instance.Configuration.GetMapsSkuToken, _configuration.AccessToken), _configuration.DefaultTimeout);
}
return _mapMatcher;
}
}
MapboxTokenApi _tokenValidator;
/// <summary>
/// Lazy token validator.
/// </summary>
public MapboxTokenApi TokenValidator
{
get
{
if (_tokenValidator == null)
{
_tokenValidator = new MapboxTokenApi();
}
return _tokenValidator;
}
}
TileJSON _tileJson;
/// <summary>
/// Lazy TileJSON wrapper: https://www.mapbox.com/api-documentation/maps/#retrieve-tilejson-metadata
/// </summary>
public TileJSON TileJSON
{
get
{
if (_tileJson == null)
{
_tileJson = new TileJSON(new FileSource(Instance.Configuration.GetMapsSkuToken, _configuration.AccessToken), _configuration.DefaultTimeout);
}
return _tileJson;
}
}
class InvalidTokenException : Exception
{
public InvalidTokenException(string message) : base(message)
{
}
}
}
public class MapboxConfiguration
{
[NonSerialized] private MapboxAccounts mapboxAccounts = new MapboxAccounts();
public string AccessToken;
public uint MemoryCacheSize = 500;
public uint FileCacheSize = 2500;
public int DefaultTimeout = 30;
public bool AutoRefreshCache = false;
public string GetMapsSkuToken()
{
return mapboxAccounts.ObtainMapsSkuUserToken(Application.persistentDataPath);
}
}
}