/// <summary> /// Put a resource in the warehouse. /// </summary> /// <param name="resource">Resource instance.</param> /// <param name="name">Resource name.</param> /// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param> /// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param> public static void Put(IResource resource, string name, IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null) { resource.Instance = new Instance(resourceCounter++, name, resource, store, customTemplate, age); if (manager != null) { resource.Instance.Managers.Add(manager); } if (store == parent) { parent = null; } if (parent == null) { if (!(resource is IStore)) { store.Instance.Children.Add(resource); } } else { parent.Instance.Children.Add(resource); } if (resource is IStore) { stores.Add(resource as IStore); StoreConnected?.Invoke(resource as IStore, name); } else { store.Put(resource); } resources.Add(resource.Instance.Id, resource); if (!storeIsOpen) { resource.Trigger(ResourceTrigger.Initialize); } }
//public static async AsyncReply<T> Push<T>(string path, T resource) where T : IResource //{ // await Put(path, resource); // return resource; //} /// <summary> /// Put a resource in the warehouse. /// </summary> /// <param name="name">Resource name.</param> /// <param name="resource">Resource instance.</param> /// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param> /// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param> public static async AsyncReply <T> Put <T>(string name, T resource, IStore store = null, IResource parent = null, TypeTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null) where T : IResource { if (resource.Instance != null) { throw new Exception("Resource has a store."); } var path = name.TrimStart('/').Split('/'); if (path.Length > 1) { if (parent != null) { throw new Exception("Parent can't be set when using path in instance name"); } parent = await Warehouse.Get <IResource>(string.Join("/", path.Take(path.Length - 1))); if (parent == null) { throw new Exception("Can't find parent"); } store = store ?? parent.Instance.Store; } var instanceName = path.Last(); var resourceReference = new WeakReference <IResource>(resource); if (store == null) { // assign parent's store as a store if (parent != null) { // assign parent as a store if (parent is IStore) { store = (IStore)parent; List <WeakReference <IResource> > list; if (stores.TryGetValue(store, out list)) { lock (((ICollection)list).SyncRoot) list.Add(resourceReference); } //stores[store].Add(resourceReference); } else { store = parent.Instance.Store; List <WeakReference <IResource> > list; if (stores.TryGetValue(store, out list)) { lock (((ICollection)list).SyncRoot) list.Add(resourceReference); } } } // assign self as a store (root store) else if (resource is IStore) { store = (IStore)resource; } else { throw new Exception("Can't find a store for the resource."); } } resource.Instance = new Instance(resourceCounter++, instanceName, resource, store, customTemplate, age); if (attributes != null) { resource.Instance.SetAttributes(Map <string, object> .FromObject(attributes)); } if (manager != null) { resource.Instance.Managers.Add(manager); } if (store == parent) { parent = null; } try { if (resource is IStore) { stores.TryAdd(resource as IStore, new List <WeakReference <IResource> >()); } if (!await store.Put(resource)) { throw new Exception("Store failed to put the resource"); } //return default(T); if (parent != null) { await parent.Instance.Store.AddChild(parent, resource); await store.AddParent(resource, parent); } var t = resource.GetType(); Global.Counters["T-" + t.Namespace + "." + t.Name]++; resources.TryAdd(resource.Instance.Id, resourceReference); if (warehouseIsOpen) { await resource.Trigger(ResourceTrigger.Initialize); if (resource is IStore) { await resource.Trigger(ResourceTrigger.Open); } } if (resource is IStore) { StoreConnected?.Invoke(resource as IStore); } } catch (Exception ex) { Warehouse.Remove(resource); throw ex; } return(resource); }