/// <summary> /// ContentManager is responsible for creating proxies, because all content is ultimately owned by a ContentManager /// And also probably an owner ContentBase (except for the top-level directory) /// </summary> internal ContentBase CreateContentProxy(Type type, string name) { ContentBase content = (ContentBase)Activator.CreateInstance(type, true); content.Manager = this; content.ContentCreate(); return(content); }
/// <summary> /// Gets a pipeline suitable for building the given content /// </summary> public virtual IContentPipeline GetPipeline(ContentBase content) { //OK, here's the deal //we don't want this assembly to have to have a reference to the pipelines assembly //so what we're going to do is establish a convention here //Pipelines for type EngineType will be implemented by MTS.Engine.Pipeline.Pipelines.EngineTypePipeline //we'll walk down the base type hierarchy to find EngineType (since sometimes the provided content will be derived from EngineType) //and we'll use reflection to try finding each thing //Now, this is meant for use on the Proto target.. nonetheless, to speed it up, we'll keep it cached //TODO - this is not a great system, it is hard for the user to extend. //well, I'll improve it later //could we have the content type return which pipeline typename it wants to use? //that could be powerful! you could then extend it later. and the BASE type could implement ALL THIS LOGIC! fascinating! //(or at least call into here to do it) DO THAT LATER var type = content.GetType(); IContentPipeline ret; if (pipelinesCache.TryGetValue(type, out ret)) { return(ret); } var baseType = type; for (;;) { //remove prefix, and path into the pipelines from there var name = baseType.FullName.Replace("MTS.Engine.ContentTypes.", ""); var candidateTypeName = "MTS.Engine.Pipeline.Pipelines." + name + "Pipeline"; foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { var pipelineType = assembly.GetType(candidateTypeName, false); if (pipelineType != null) { ret = (IContentPipeline)Activator.CreateInstance(pipelineType); pipelinesCache[type] = ret; break; } } baseType = baseType.BaseType; if (baseType == null) { break; } } return(ret); }
public bool EmbeddedLoadBaked(ContentBase content, PipelineLoadBakedContext context) { //older approach //var shim = new ContentLoaderBakedEmbed((IContentBakeable)content, context); //return LoadWith(content, shim); //this way we don't set the loader.. is that a problem? It's only a problem if we unload it.. and then call load again... //that's really not sensible in this case, so I guess it's OK to not have a loader //in that case also really only the owner should be able to unload it. we need some way to enforce that //for instance, what happens if you unload an animset cell? should be nothing. if (content.IsLoaded) { content.Unload(); } return(content.LoadFromBakedInProgress(context)); }
/// <summary> /// Creates a content proxy which is.. 'bound'.. to a field? /// That's the intent, but it looks like the different logic in here isn't directly related to that. /// It should be possible to do oven stuff without... man, I dont know /// </summary> protected virtual ContentBase CreateBoundContentProxy(Type type, string name, ContentManifestEntry manifestEntry) { //manifestEntry has to come in so we can use it during creating content.. yeah.. i should have thought of that. //I need to clean that up ContentBase content = CreateContentProxy(type, name); content.attributes = manifestEntry.Attributes; //if we're bruted, just create the baked loader and move on #if !BRUTED //try getting the pipeline we'd use to bake this content. If there's such a pipeline, set us up to use it var pipeline = Manager.PipelineConnector.GetPipeline(content); if (pipeline != null) { //TODO - I had intended a 1:1 correspondence of loaders to content instances, but maybe I can have the loaders have the required name and directory context? I think it should be possible content._loader = new Loaders.ProtoLoader(content) { directoryOwner = this as ContentDirectory, //I guess we know this is true name = name }; return(content); } #endif //if we weren't able to setup the proto loader, we can still load it baked //this probably doesnt make any sense in a Proto target.. //maybe it makes sense for binary content not managed by a content type really? //but we should probably have some setup that copies it over, anyway //else, a ProtoSlimLoader which loads it straight from the content directory. //not sure yet. anyway, this is harmless. content._loader = new Loaders.BakedLoader(content) { directoryOwner = this as ContentDirectory, //I guess we know this is true name = name }; return(content); }
public bool LoadWith(ContentBase content, IContentLoader loader) { content._loader = loader; return(content.Load()); }