public static void Delete <T>(T obj, Action <bool> callback) where T : NetworkDataObject, new() { int hash = GetHashCode(typeof(T), obj.Id); Action <object> emitCallback = o => { CommunicationsApi.RunOnMainThread(() => { ObjectTracker.Remove(hash); OfflineCache.Purge(hash); if (callback != null) { callback(true); } }); }; string eventName = typeof(T).Name + ".delete"; if (CommunicationsApi.IsAvailable) { CommunicationsApi.Socket.Emit(eventName, obj.Id, "", emitCallback); } else { QueuedRequests.Add(new QueuedRequest(QueuedRequestType.Delete, emitCallback)); } }
public static void Create <T>(T obj, Action <T> callback) where T : NetworkDataObject, new() { Action <object> emitCallback = o => { CommunicationsApi.RunOnMainThread(() => { var created = (o as JsonEncodedEventMessage).GetFirstArgAs <T>(); int hash = GetHashCode(typeof(T), created.Id); if (!ObjectTracker.ContainsKey(hash)) { ObjectTracker[hash] = new T(); } ObjectTracker[hash].Merge(created); OfflineCache.QueueStore(hash, ObjectTracker[hash]); if (callback != null) { callback(ObjectTracker[hash] as T); } }); }; string eventName = typeof(T).Name + ".create"; if (CommunicationsApi.IsAvailable) { CommunicationsApi.Socket.Emit(eventName, obj, "", emitCallback); } else { // queue for update QueuedRequests.Add(new QueuedRequest(QueuedRequestType.Create, emitCallback)); } }
public static Task <T> CachedQuery <T>(this DataSource datasource, OfflineCacheEnumeration type, TimeSpan?optionalTimeSpan = null) { var query = datasource.Query(); var manager = new OfflineCache(targetdirectory, datasource.dsname, DataSourceServiceName); if (optionalTimeSpan != null) { manager.Expiration = optionalTimeSpan.Value; } var task = manager.TaskManager(query, type); return(Task.Factory.StartNew <T>(() => { var result = JsonConvert.DeserializeObject <T>(task.Result); return result; })); }
/// <summary> /// Registers an NetworkDataObject type for AutoUpdates. /// </summary> /// <typeparam name="T">The type of object to register.</typeparam> public static void RegisterAutoUpdate <T>() where T : NetworkDataObject, new() { var eventName = typeof(T).Name + ".update"; CommunicationsApi.Socket.On(eventName, message => { CommunicationsApi.RunOnMainThread(() => { var obj = message.Json.GetFirstArgAs <T>(); int hash = GetHashCode(typeof(T), obj.Id); if (!ObjectTracker.ContainsKey(hash)) { ObjectTracker[hash] = new T(); } ObjectTracker[hash].Merge(obj); // Update Offline Cache, is done async so it doesn't block OfflineCache.QueueStore(hash, ObjectTracker[hash]); }); }); }
public static Task <string> CachedInvoke <U>(this DataSource datasource, U parameters, TimeSpan?optionalTimeSpan = null) { var manager = new OfflineCache(targetdirectory, datasource.dsname, DataSourceServiceName); var invoke = datasource.Invoke(parameters); var task = manager.RequestQueueManager(invoke, parameters, OfflineCacheEnumeration.NetworkElseLocal); manager.RequestQueueManagerFetch += (object sender, OfflineCache.RequestQueueManagerEventArgs e) => { e.Requests.ForEach(r => { Console.WriteLine("calling again invoke with parameters: " + r); Task.Factory.StartNew(() => { var dsparam = JsonConvert.DeserializeObject <U>(r); var result = datasource.Invoke(dsparam).Result; Console.WriteLine("calling again result: " + result); }); manager.DeleteRequest(r); } ); }; return(Task.Factory.StartNew <string>(() => { return task.Result; })); }
/// <summary> /// Gets a list of objects corresponding to the relevancy of the request. Is async with callback in most cases. /// </summary> /// <typeparam name="T">The type of objects to list</typeparam> /// <param name="list">The list to fetch</param> /// <param name="callback">A callback to handle the requested data. Can be null to just queue update from server or heat up data from disk cache.</param> public static void List <T>(string list, Action <IEnumerable <T> > callback) where T : NetworkDataObject, new() { string eventName = typeof(T).Name + ".list"; int hash = eventName.GetHashCode(); if (CommunicationsApi.IsAvailable) { // fetch array with ids, then Get each object (allows us to fetch from local cache instead of sending buttloads of data over net by default) CommunicationsApi.Socket.Emit(eventName, list, "", o => { CommunicationsApi.RunOnMainThread(() => { List <T> returns = new List <T>(); var got = (o as JsonEncodedEventMessage).GetFirstArgAs <string[]>(); int i = got.Length; foreach (var id in got) { Get <T>(id, obj => { returns.Add(obj); i--; if (i == 0) { if (callback != null) { callback(returns); } } }); } }); }); } else { var cache = OfflineCache.Fetch <T>(hash); if (cache != null) { List <T> returns = new List <T>(); var got = (cache as string[]); int i = got.Length; foreach (var id in got) { Get <T>(id, obj => { returns.Add(obj); i--; if (i == 0) { if (callback != null) { callback(returns); } } }); } } else { if (callback != null) { callback(new T[0]); } } } }
/// <summary> /// Retreives an object from a datasource, depending on the availability. /// </summary> /// <typeparam name="T">Type of object to retreive, must of type NetworkDataObject</typeparam> /// <param name="id">The Id for the object to retreive</param> /// <param name="callback">A callback to handle the retreived data. Can be null to just queue update from server or heat up data from disk cache.</param> public static void Get <T>(string id, Action <T> callback) where T : NetworkDataObject, new() { // we define event as "get Type", needs to be mapped on server as well string eventName = typeof(T).Name + ".get"; // get unique-ish hash key for object int hash = GetHashCode(typeof(T), id); // if object was last modified less than a minute ago, return instantly and queue an update bool fast = false; if (ObjectTracker.ContainsKey(hash) && ObjectTracker[hash].LastModified > (DateTime.UtcNow - TimeSpan.FromMinutes(1))) { if (callback != null) { callback(ObjectTracker[hash] as T); } fast = true; } if (CommunicationsApi.IsAvailable) { // Queue update from server CommunicationsApi.Socket.Emit(eventName, id, "", o => { CommunicationsApi.RunOnMainThread(() => { // New object? create empty instance and merge data to it if (!ObjectTracker.ContainsKey(hash)) { ObjectTracker[hash] = new T(); } ObjectTracker[hash].Merge((o as JsonEncodedEventMessage).GetFirstArgAs <T>()); // Update Offline Cache, is done async so it doesn't block OfflineCache.QueueStore(hash, ObjectTracker[hash]); if (!fast && callback != null) { callback(ObjectTracker[hash] as T); } }); }); } else { if (fast) // fast cache but API offline? not our problem for now { return; } // Got an object tracked but older than a minute? lets just use it if (ObjectTracker.ContainsKey(hash)) { if (callback != null) { callback(ObjectTracker[hash] as T); } return; } // Attempt to fetch sync from Offline Cache var cache = OfflineCache.Fetch <T>(hash); if (cache != null) { ObjectTracker[hash] = cache; if (callback != null) { callback(cache); } return; } else { if (callback != null) { callback(new T()); // returns empty object that is considered unavailable } } } }