public T Get <T>(string asset) where T : class, IAsset { // Calling GetUnresolved from the client is an expensive operation, // so we do everything we can to cache the result. The NetworkAsset // proxy magic means that we'll automatically know on the client side // when we need to pull down new data, and this is handled inside // the NetworkAssetProxy. Thus we can cache our resolved asset // forever. if (!(this as ITransparent).Node.IsServer) { // If the network asset already exists, return it. if (this.m_ClientCache == null) { this.m_ClientCache = new Dictionary <string, IAsset>(); } if (this.m_ClientCache.ContainsKey(asset)) { return((T)this.m_ClientCache[asset]); } // Otherwise we really do need to make a request over // the network to get an initial NetworkAsset. NetworkAsset networkAsset = null; while (networkAsset == null) { networkAsset = (NetworkAsset)this.GetUnresolved(asset); } networkAsset.InjectLoaders(this.m_Kernel.GetAll <IAssetLoader>().ToArray()); this.m_ClientCache.Add(asset, networkAsset.Resolve <T>()); return((T)this.m_ClientCache[asset]); } // We can efficiently call this on the server as much as we like. return(this.GetUnresolved(asset).Resolve <T>()); }
public NetworkAssetProxy(NetworkAssetManager manager, NetworkAsset networkAsset, string name, T instance) : base(instance.GetType()) { this.m_Instance = instance; this.m_Manager = manager; this.m_NetworkAsset = networkAsset; this.m_AssetName = name; this.m_Dirty = false; this.m_NetworkAsset.Dirtied += MarkDirty; }
public IAsset GetUnresolved(string asset) { lock (this.m_Assets) { // If the network asset already exists, return it. if (this.m_Assets.ContainsKey(asset)) { if (!this.m_Assets[asset].IsDirty) { return(this.m_Assets[asset]); } this.m_Assets.Remove(asset); } // Otherwise load the raw assets if that doesn't exist. object[] candidates; NetworkAsset result; if (!this.m_RawAssets.ContainsKey(asset)) { if (this.m_RawAssetLoader == null) { this.m_RawAssetLoader = this.m_Kernel.Get <IRawAssetLoader>(); } try { candidates = this.m_RawAssetLoader.LoadRawAssetCandidates(asset); } catch (AssetNotFoundException) { result = new NetworkAsset(this.m_Kernel.GetAll <IAssetLoader>().ToArray(), this.m_TransparentAssetCompiler, null, asset, this); this.m_Assets.Add(asset, result); return(result); } } else { candidates = this.m_RawAssets[asset]; } // We now have our raw asset and we need to wrap it in // a NetworkAsset. result = new NetworkAsset(this.m_Kernel.GetAll <IAssetLoader>().ToArray(), this.m_TransparentAssetCompiler, candidates, asset, this); this.m_Assets.Add(asset, result); return(result); } }
public override IMessage Invoke(IMessage msg) { if (this.m_Dirty) { this.m_NetworkAsset.Dirtied -= MarkDirty; this.m_NetworkAsset = this.m_Manager.GetUnresolved(this.m_AssetName) as NetworkAsset; var proxy = this.m_NetworkAsset.Resolve <T>(); if (!RemotingServices.IsTransparentProxy(proxy)) { throw new InvalidOperationException("Object retrieved was not transparent proxy."); } var realProxy = RemotingServices.GetRealProxy(proxy); var newNetworkAssetProxy = realProxy as NetworkAssetProxy <T>; if (newNetworkAssetProxy == null) { throw new InvalidOperationException("Unable to cast real proxy back to NetworkAssetProxy<>."); } this.m_Instance = newNetworkAssetProxy.m_Instance; this.m_Dirty = false; this.m_NetworkAsset.Dirtied += MarkDirty; } var methodCall = (IMethodCallMessage)msg; var method = (MethodInfo)methodCall.MethodBase; try { var result = method.Invoke(this.m_Instance, methodCall.InArgs); return(new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall)); } catch (Exception e) { if (e is TargetInvocationException && e.InnerException != null) { return(new ReturnMessage(e.InnerException, msg as IMethodCallMessage)); } return(new ReturnMessage(e, msg as IMethodCallMessage)); } }