Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
557f1a7
[wip] autorefreshing cache
wilhelmberg Nov 14, 2017
55f422d
implement actual tile request when cache tile is outdated
wilhelmberg Nov 15, 2017
4eeeee1
Merge branch 'develop' of github.com:mapbox/mapbox-unity-sdk into aut…
wilhelmberg Jan 4, 2018
0beddba
auto-migrate old caches (add etag and lastmodified columns)
wilhelmberg Jan 5, 2018
a5ea633
Merge branch 'develop' of github.com:mapbox/mapbox-unity-sdk into aut…
wilhelmberg Jan 10, 2018
2ae13b5
TileJSON objects for API wrapper
wilhelmberg Jan 10, 2018
4dbe23e
tests for TileJSON wrapper
wilhelmberg Jan 10, 2018
f709eac
MBTilesCache: implement 'force update'
wilhelmberg Jan 10, 2018
e224269
TileJSON tests: test for 'Name' property being not empty
wilhelmberg Jan 10, 2018
8551e53
TileJSONResponse: add inlince docs about which properties can be empty
wilhelmberg Jan 10, 2018
6051480
add test scene
wilhelmberg Jan 11, 2018
caa86e4
fix MBTilesCache exception when automigrating cache when no cached e…
wilhelmberg Jan 11, 2018
12f5107
add inline docs to CachingWebFileSource
wilhelmberg Jan 12, 2018
3637bf3
add custom tileset to test scene
wilhelmberg Jan 12, 2018
e624f5a
expose menuitem to delete all existing cache files
wilhelmberg Jan 16, 2018
c48f2a4
Merge branch 'develop' of github.com:mapbox/mapbox-unity-sdk into aut…
wilhelmberg Jan 17, 2018
3858d13
add 'Updated' property to HttpResponse and Tile
wilhelmberg Jan 17, 2018
7cda955
VectorTileFactory: on update call delete gameobjects
wilhelmberg Jan 17, 2018
3c213f3
additional null checks
wilhelmberg Jan 17, 2018
61b6308
TODO remove!!! scene and asset changes for testing
wilhelmberg Jan 17, 2018
371033b
Merge branch 'develop' of github.com:mapbox/mapbox-unity-sdk into aut…
wilhelmberg Jan 18, 2018
da83fac
own POI visualizer for test tileset
wilhelmberg Jan 18, 2018
10514c0
Merge branch 'develop' of github.com:mapbox/mapbox-unity-sdk into aut…
wilhelmberg Jan 18, 2018
2d51d3a
Merge branch 'develop' of github.com:mapbox/mapbox-unity-sdk into aut…
wilhelmberg Jan 25, 2018
63f052c
expose auto-refreshing-cache option in the settings
wilhelmberg Jan 25, 2018
6d88d88
change tile factory from destroying object to unregistering tiles (wh…
brnkhy Feb 7, 2018
bbc5550
delete test scene
wilhelmberg Feb 20, 2018
8c925f6
Merge branch 'develop' of github.com:mapbox/mapbox-unity-sdk into aut…
wilhelmberg Feb 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions sdkproject/Assets/Mapbox/Core/mapbox-sdk-cs/Map/Tile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Mapbox.Map
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Mapbox.Unity.Utilities;


/// <summary>
Expand Down Expand Up @@ -38,7 +39,9 @@ public enum State
/// <summary> Data loaded and parsed. </summary>
Loaded,
/// <summary> Data loading cancelled. </summary>
Canceled
Canceled,
/// <summary> Data has been loaded before and got updated. </summary>
Updated
}

/// <summary> Gets the <see cref="T:Mapbox.Map.CanonicalTileId"/> identifier. </summary>
Expand Down Expand Up @@ -103,6 +106,10 @@ public State CurrentState
}
}


public HttpRequestType RequestType { get { return _request.RequestType; } }


public bool IsCompleted
{
get
Expand Down Expand Up @@ -209,7 +216,7 @@ private void HandleTileResponse(Response response)
ids.Add(_id.ToString());
else
return;

response.Exceptions.ToList().ForEach(e => AddException(e));
}
else
Expand All @@ -225,7 +232,14 @@ private void HandleTileResponse(Response response)
// Cancelled is not the same as loaded!
if (_state != State.Canceled)
{
_state = State.Loaded;
if (response.IsUpdate)
{
_state = State.Updated;
}
else
{
_state = State.Loaded;
}
}
_callback();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

namespace Mapbox.Platform.Cache
{

using System;


public class CacheItem
{
/// <summary> Raw response data- </summary>
public byte[] Data;
/// <summary> UTC ticks when item was added to the cache. </summary>
public long AddedToCacheTicksUtc;
/// <summary> ETag value of API response. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag </summary>
public string ETag;
/// <summary> Can be 'null' as not all APIs populated this value. Last-Modified value of API response in GMT: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified </summary>
public DateTime? LastModified;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using Mapbox.Unity.Utilities;
using Mapbox.Map;
using System.Collections;
using System.Linq;


public class CachingWebFileSource : IFileSource, IDisposable
{
Expand All @@ -14,11 +16,13 @@ public class CachingWebFileSource : IFileSource, IDisposable
private bool _disposed;
private List<ICache> _caches = new List<ICache>();
private string _accessToken;
private bool _autoRefreshCache;


public CachingWebFileSource(string accessToken)
public CachingWebFileSource(string accessToken, bool autoRefreshCache)
{
_accessToken = accessToken;
_autoRefreshCache = autoRefreshCache;
}


Expand Down Expand Up @@ -104,64 +108,160 @@ string uri
throw new Exception("Cannot cache without a map id");
}

byte[] data = null;
CacheItem cachedItem = null;

// go through existing caches and check if we already have the requested tile available
foreach (var cache in _caches)
{
data = cache.Get(mapId, tileId);
if (null != data)
cachedItem = cache.Get(mapId, tileId);
if (null != cachedItem)
{
break;
}
}

// if tile was available propagate to all other caches and return
if (null != data)
var uriBuilder = new UriBuilder(uri);
if (!string.IsNullOrEmpty(_accessToken))
{
foreach (var cache in _caches)
string accessTokenQuery = "access_token=" + _accessToken;
if (uriBuilder.Query != null && uriBuilder.Query.Length > 1)
{
uriBuilder.Query = uriBuilder.Query.Substring(1) + "&" + accessTokenQuery;
}
else
{
cache.Add(mapId, tileId, data);
uriBuilder.Query = accessTokenQuery;
}
}
string finalUrl = uriBuilder.ToString();


// if tile was available call callback with it, propagate to all other caches and check if a newer one is available
if (null != cachedItem)
{
// immediately return cached tile
callback(Response.FromCache(cachedItem.Data));

// check for updated tiles online if this is enabled in the settings
if (_autoRefreshCache)
{
// check if tile on the web is newer than the one we already have locally
IAsyncRequestFactory.CreateRequest(
finalUrl,
(Response headerOnly) =>
{
// on error getting information from API just return. tile we have locally has already been returned above
if (headerOnly.HasError)
{
return;
}

// TODO: remove Debug.Log before PR
//UnityEngine.Debug.LogFormat(
// "{1}{0}cached:{2}{0}header:{3}"
// , Environment.NewLine
// , finalUrl
// , cachedItem.ETag
// , headerOnly.Headers["ETag"]
//);

// data from cache is the same as on the web:
// * tile has already been returned above
// * make sure all all other caches have it too, but don't force insert via cache.add(false)
// additional ETag empty check: for backwards compability with old caches
if (!string.IsNullOrEmpty(cachedItem.ETag) && cachedItem.ETag.Equals(headerOnly.Headers["ETag"]))
{
foreach (var cache in _caches)
{
cache.Add(mapId, tileId, cachedItem, false);
}
}
else
{
// TODO: remove Debug.Log before PR
UnityEngine.Debug.LogWarningFormat(
"updating cached tile {1} mapid:{2}{0}cached etag:{3}{0}remote etag:{4}{0}{5}"
, Environment.NewLine
, tileId
, mapId
, cachedItem.ETag
, headerOnly.Headers["ETag"]
, finalUrl
);

// request updated tile and pass callback to return new data to subscribers
requestTileAndCache(finalUrl, mapId, tileId, timeout, callback);
}
}
, timeout
, HttpRequestType.Head
);
}

callback(Response.FromCache(data));
return new MemoryCacheAsyncRequest(uri);
}
else
{
// requested tile is not in any of the caches yet, get it
var uriBuilder = new UriBuilder(uri);
return requestTileAndCache(finalUrl, mapId, tileId, timeout, callback);
}
}

if (!string.IsNullOrEmpty(_accessToken))

private IAsyncRequest requestTileAndCache(string url, string mapId, CanonicalTileId tileId, int timeout, Action<Response> callback)
{
return IAsyncRequestFactory.CreateRequest(
url,
(Response r) =>
{
string accessTokenQuery = "access_token=" + _accessToken;
if (uriBuilder.Query != null && uriBuilder.Query.Length > 1)
// if the request was successful add tile to all caches
if (!r.HasError && null != r.Data)
{
uriBuilder.Query = uriBuilder.Query.Substring(1) + "&" + accessTokenQuery;
}
else
{
uriBuilder.Query = accessTokenQuery;
}
}
//UnityEngine.Debug.Log(uri);
string eTag = string.Empty;
DateTime? lastModified = null;

return IAsyncRequestFactory.CreateRequest(
uriBuilder.ToString(),
(Response r) =>
{
// if the request was successful add tile to all caches
if (!r.HasError && null != r.Data)
if (!r.Headers.ContainsKey("ETag"))
{
foreach (var cache in _caches)
{
cache.Add(mapId, tileId, r.Data);
}
UnityEngine.Debug.LogWarningFormat("no 'ETag' header present in response for {0}", url);
}
else
{
eTag = r.Headers["ETag"];
}

// not all APIs populate 'Last-Modified' header
// don't log error if it's missing
if (r.Headers.ContainsKey("Last-Modified"))
{
lastModified = DateTime.ParseExact(r.Headers["Last-Modified"], "r", null);
}

// propagate to all caches forcing update
foreach (var cache in _caches)
{
cache.Add(
mapId
, tileId
, new CacheItem()
{
Data = r.Data,
ETag = eTag,
LastModified = lastModified
}
, true // force insert/update
);
}
}
if (null != callback)
{
r.IsUpdate = true;
callback(r);
}, timeout);
}
}
}, timeout);
}


class MemoryCacheAsyncRequest : IAsyncRequest
{

Expand All @@ -184,6 +284,9 @@ public bool IsCompleted
}


public HttpRequestType RequestType { get { return HttpRequestType.Get; } }


public void Cancel()
{
// Empty. We can't cancel an instantaneous response.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using Mapbox.Map;
using System.Collections;
using System.Collections.Generic;


namespace Mapbox.Platform.Cache
{

using Mapbox.Map;
using System;


public interface ICache
{
Expand All @@ -20,8 +19,9 @@ public interface ICache
/// </summary>
/// <param name="mapId">Tile set name</param>
/// <param name="tileId">Tile ID</param>
/// <param name="data">Tile data</param>
void Add(string mapId, CanonicalTileId tileId, byte[] data);
/// <param name="item">Item to cache</param>
/// <param name="replaceIfExists">Force insert even if item already exists.</param>
void Add(string mapId, CanonicalTileId tileId, CacheItem item, bool replaceIfExists);


/// <summary>
Expand All @@ -30,7 +30,7 @@ public interface ICache
/// <param name="mapId"></param>
/// <param name="tileId"></param>
/// <returns>byte[] with tile data. Null if requested tile is not in cache</returns>
byte[] Get(string mapId, CanonicalTileId tileId);
CacheItem Get(string mapId, CanonicalTileId tileId);


/// <summary>Clear cache for all tile sets</summary>
Expand Down
Loading