Rework mod enumeration / caching.

- Replaced ModMetadata.AllMods with Game.Mods.
- Store / reference mod Manifest instead of ModMetadata.
- Removes engine dependency on ModContent class.
This commit is contained in:
Paul Chote
2016-08-05 17:07:04 +01:00
parent 45a596953e
commit 3df9efb95d
33 changed files with 301 additions and 219 deletions

View File

@@ -24,32 +24,39 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
readonly Widget modList;
readonly ButtonWidget modTemplate;
readonly ModMetadata[] allMods;
readonly Manifest[] allMods;
readonly Dictionary<string, Sprite> previews = new Dictionary<string, Sprite>();
readonly Dictionary<string, Sprite> logos = new Dictionary<string, Sprite>();
readonly Cache<Manifest, ModContent> content = new Cache<Manifest, ModContent>(LoadModContent);
readonly Widget modChooserPanel;
readonly ButtonWidget loadButton;
readonly SheetBuilder sheetBuilder;
ModMetadata selectedMod;
Manifest selectedMod;
string selectedAuthor;
string selectedDescription;
int modOffset = 0;
static ModContent LoadModContent(Manifest mod)
{
return mod.Get<ModContent>(Game.ModData.ObjectCreator);
}
[ObjectCreator.UseCtor]
public ModBrowserLogic(Widget widget, ModData modData)
{
modChooserPanel = widget;
loadButton = modChooserPanel.Get<ButtonWidget>("LOAD_BUTTON");
loadButton.OnClick = () => LoadMod(selectedMod);
loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Mod.Id;
loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Id;
var contentButton = modChooserPanel.Get<ButtonWidget>("CONFIGURE_BUTTON");
contentButton.IsDisabled = () => selectedMod.ModContent == null;
contentButton.OnClick = () =>
{
var widgetArgs = new WidgetArgs
{
{ "modId", selectedMod.Id },
{ "mod", selectedMod },
{ "content", content[selectedMod] },
{ "onCancel", () => { } }
};
@@ -62,9 +69,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
modTemplate = modList.Get<ButtonWidget>("MOD_TEMPLATE");
modChooserPanel.Get<LabelWidget>("MOD_DESC").GetText = () => selectedDescription;
modChooserPanel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Title;
modChooserPanel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Mod.Title;
modChooserPanel.Get<LabelWidget>("MOD_AUTHOR").GetText = () => selectedAuthor;
modChooserPanel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Version;
modChooserPanel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Mod.Version;
var prevMod = modChooserPanel.Get<ButtonWidget>("PREV_MOD");
prevMod.OnClick = () => { modOffset -= 1; RebuildModList(); };
@@ -82,8 +89,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
sheetBuilder = new SheetBuilder(SheetType.BGRA);
allMods = ModMetadata.AllMods.Values.Where(m => !m.Hidden)
.OrderBy(m => m.Title)
allMods = Game.Mods.Values.Where(m => !m.Mod.Hidden)
.OrderBy(m => m.Mod.Title)
.ToArray();
// Load preview images, and eat any errors
@@ -91,7 +98,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
try
{
using (var stream = ModMetadata.AllMods[mod.Id].Package.GetStream("preview.png"))
using (var stream = mod.Package.GetStream("preview.png"))
using (var preview = new Bitmap(stream))
if (preview.Width == 296 && preview.Height == 196)
previews.Add(mod.Id, sheetBuilder.Add(preview));
@@ -100,7 +107,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
try
{
using (var stream = ModMetadata.AllMods[mod.Id].Package.GetStream("logo.png"))
using (var stream = mod.Package.GetStream("logo.png"))
using (var logo = new Bitmap(stream))
if (logo.Width == 96 && logo.Height == 96)
logos.Add(mod.Id, sheetBuilder.Add(logo));
@@ -108,9 +115,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
catch (Exception) { }
}
ModMetadata initialMod;
ModMetadata.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : ModMetadata.AllMods["ra"]);
Manifest initialMod;
Game.Mods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : Game.Mods["ra"]);
RebuildModList();
}
@@ -146,7 +153,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
SelectMod(mod);
};
item.TooltipText = mod.Title;
item.TooltipText = mod.Mod.Title;
if (j < 9)
item.Key = new Hotkey((Keycode)((int)Keycode.NUMBER_1 + j), Modifiers.None);
@@ -160,23 +167,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
}
void SelectMod(ModMetadata mod)
void SelectMod(Manifest mod)
{
selectedMod = mod;
selectedAuthor = "By " + (mod.Author ?? "unknown author");
selectedDescription = (mod.Description ?? "").Replace("\\n", "\n");
selectedAuthor = "By " + (mod.Mod.Author ?? "unknown author");
selectedDescription = (mod.Mod.Description ?? "").Replace("\\n", "\n");
var selectedIndex = Array.IndexOf(allMods, mod);
if (selectedIndex - modOffset > 4)
modOffset = selectedIndex - 4;
}
void LoadMod(ModMetadata mod)
void LoadMod(Manifest mod)
{
if (!Game.IsModInstalled(mod.Id))
var modId = mod.Id;
if (!Game.IsModInstalled(modId))
{
var widgetArgs = new WidgetArgs
{
{ "modId", mod.Id }
{ "mod", selectedMod },
{ "content", content[selectedMod] },
};
Ui.OpenWindow("INSTALL_MOD_PANEL", widgetArgs);
@@ -188,8 +197,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var widgetArgs = new WidgetArgs
{
{ "continueLoading", () =>
Game.RunAfterTick(() => Game.InitializeMod(mod.Id, new Arguments())) },
{ "modId", mod.Id }
Game.RunAfterTick(() => Game.InitializeMod(modId, new Arguments())) },
{ "mod", selectedMod },
{ "content", content[selectedMod] },
};
Ui.OpenWindow("CONTENT_PROMPT_PANEL", widgetArgs);
@@ -201,13 +211,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
Ui.CloseWindow();
sheetBuilder.Dispose();
Game.InitializeMod(mod.Id, null);
Game.InitializeMod(modId, null);
});
}
static bool IsModInstalled(ModMetadata mod)
bool IsModInstalled(Manifest mod)
{
return mod.ModContent.Packages
return content[mod].Packages
.Where(p => p.Value.Required)
.All(p => p.Value.TestFiles.All(f => File.Exists(Platform.ResolvePath(f))));
}