// Ok, let's explain why this method uses the "new" keyword. // In the olden days (before September 2009) the user would call // FlatRedBallServices.Load<TypeToLoad> which would investigate whether // the user passed an assetName that had an extension or not. Then the // FlatRedBallServices class would call LoadFromFile or LoadFromProject // depending on the presence of an extension. // // In an effort to reduce the responsibilities of the FlatRedBallServices // class, Vic decided to move the loading code (including the logic that branches // depending on whether an asset has an extension) into the ContentManager class. // To keep things simple, the FlatRedBallServices just has to call Load and the Load // method will do the branching inside the ContentManager class. That all worked well, // except that the branching code also "standardizes" the name, which means it turns relative // paths into absolute paths. The reason this is a problem is IF the user loads an object (such // as a .X file) which references another file, then the Load method will be called again on the referenced // asset name. // // The FRB ContentManager doesn't use relative directories - instead, it makes all assets relative to the .exe // by calling Standardize. However, if Load is called by XNA code (such as when loading a .X file) // then any files referenced by the X will come in already made relative to the ContentManager. // This means that if a .X file was "Content\myModel" and it referenced myTexture.png which was in the same // folder as the .X file, then Load would get called with "Content\myTexture" as the argument. That is, the .X loading // code would already prepend "Content\" before "myTexture. But the FRB content manager wouldn't know this, and it'd // try to standardize it as well, making the file "Content\Content\myTexture." // // So the solution? We make Load a "new" method. That means that if Load is called by XNA, then it'll call the // Load of XNA's ContentManager. But if FRB calls it, it'll call the "new" version. Problem solved. public new T Load<T>(string assetName) { var standardized = FileManager.Standardize(assetName); if(FileAliases.ContainsKey(standardized)) { assetName = FileAliases[standardized]; } // Assets can be loaded either from file or from assets referenced // in the project. string extension = FileManager.GetExtension(assetName); #region If there is an extension, loading from file or returning an already-loaded asset assetName = FileManager.Standardize(assetName); if (extension != String.Empty) { return LoadFromFile<T>(assetName); } #endregion #region Else there is no extension, so the file is already part of the project. Use a ContentManager else { #if PROFILE bool exists = false; exists = IsAssetLoadedByName<T>(assetName); if (exists) { mHistory.Add(new ContentLoadHistory( TimeManager.CurrentTime, typeof(T).Name, assetName, ContentLoadDetail.Cached)); } else { mHistory.Add(new ContentLoadHistory( TimeManager.CurrentTime, typeof(T).Name, assetName, ContentLoadDetail.HddFromContentPipeline)); } #endif return LoadFromProject<T>(assetName); } #endregion }