misc performance improvements

Preallocate the terrain-building objects and reuse

changed:
- grid alternates with a slightly-darker to help indicate the larger 2x2 tile grid.
- put plaza & buildings behind the gridlines
This commit is contained in:
Kurt
2020-05-02 23:02:37 -07:00
parent 5b5d1b2bce
commit 928e699168
12 changed files with 165 additions and 120 deletions

View File

@@ -16,6 +16,7 @@ protected override void Dispose(bool disposing)
if (disposing && (components != null))
{
components.Dispose();
Map.Dispose();
}
base.Dispose(disposing);
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using NHSE.Core;
using NHSE.Sprites;
@@ -10,21 +11,29 @@ public partial class BuildingEditor : Form
{
private readonly IReadOnlyList<Building> Buildings;
private readonly MainSave SAV;
private readonly TerrainManager Terrain;
private static readonly IReadOnlyDictionary<string, string[]> HelpDictionary = StructureUtil.GetStructureHelpList();
public BuildingEditor(IReadOnlyList<Building> buildings, MainSave sav)
private readonly Bitmap Map;
private readonly int[] Scale1;
private readonly int[] ScaleX;
private readonly MapTerrainStructure Manager;
private const int scale = 4;
public BuildingEditor(MainSave sav)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Manager = new MapTerrainStructure(sav);
SAV = sav;
Buildings = buildings;
Terrain = new TerrainManager(sav.GetTerrainTiles());
Buildings = Manager.Buildings;
Scale1 = new int[Manager.Terrain.MapWidth * Manager.Terrain.MapHeight];
ScaleX = new int[Scale1.Length * scale * scale];
Map = new Bitmap(Manager.Terrain.MapWidth * scale, Manager.Terrain.MapHeight * scale);
NUD_PlazaX.Value = sav.PlazaX;
NUD_PlazaY.Value = sav.PlazaY;
foreach (var obj in buildings)
foreach (var obj in Manager.Buildings)
LB_Items.Items.Add(obj.ToString());
LB_Items.SelectedIndex = 0;
@@ -43,6 +52,7 @@ private void B_Save_Click(object sender, EventArgs e)
SAV.PlazaY = (uint)NUD_PlazaY.Value;
DialogResult = DialogResult.OK;
SAV.Buildings = Manager.Buildings;
Close();
}
@@ -52,10 +62,9 @@ private void B_Save_Click(object sender, EventArgs e)
private void DrawMap(in int index)
{
var font = B_Save.Font;
const int scale = 4;
var px = (ushort) NUD_PlazaX.Value;
var py = (ushort) NUD_PlazaY.Value;
PB_Map.Image = TerrainSprite.GetMapWithBuildings(Terrain, Buildings, px, py, font, scale, index);
Manager.PlazaX = (ushort) NUD_PlazaX.Value;
Manager.PlazaY = (ushort) NUD_PlazaY.Value;
PB_Map.Image = TerrainSprite.GetMapWithBuildings(Manager, font, Scale1, ScaleX, Map, scale, index);
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)

View File

@@ -66,8 +66,19 @@ private void LoadItemGridAcre()
}
private int GetItemTransparency() => ((int)(0xFF * TR_Transparency.Value / 100d) << 24) | 0x00FF_FFFF;
private void ReloadMapBackground() => PB_Map.BackgroundImage = View.GetBackgroundTerrain(SelectedBuildingIndex);
private void ReloadAcreBackground() => PB_Acre.BackgroundImage = View.GetBackgroundAcre(L_Coordinates.Font, SelectedBuildingIndex);
private void ReloadMapBackground()
{
PB_Map.BackgroundImage = View.GetBackgroundTerrain(SelectedBuildingIndex);
PB_Map.Invalidate(); // background image reassigning to same img doesn't redraw; force it
}
private void ReloadAcreBackground()
{
PB_Acre.BackgroundImage = View.GetBackgroundAcre(L_Coordinates.Font, SelectedBuildingIndex);
PB_Acre.Invalidate(); // background image reassigning to same img doesn't redraw; force it
}
private void ReloadMapItemGrid() => PB_Map.Image = View.GetMapWithReticle(GetItemTransparency());
private void ReloadAcreItemGrid() => PB_Acre.Image = View.GetLayerAcre(GetItemTransparency());
@@ -392,7 +403,7 @@ private void Menu_SavePNG_Click(object sender, EventArgs e)
}
const string name = "map";
var bmp = FieldItemSpriteDrawer.GetBitmapLayer(Map.Items.Layer1);
var bmp = FieldItemSpriteDrawer.GetBitmapItemLayer(Map.Items.Layer1);
using var sfd = new SaveFileDialog
{
Filter = "png file (*.png)|*.png|All files (*.*)|*.*",

View File

@@ -8,53 +8,68 @@ namespace NHSE.WinForms
public sealed class MapViewer : MapView, IDisposable
{
// Cached acre view objects to remove allocation/GC
private readonly int[] Scale1;
private readonly int[] ScaleX;
private readonly int[] PixelsItemAcre1;
private readonly int[] PixelsItemAcreX;
private readonly Bitmap ScaleAcre;
private readonly int[] MapPixels;
private readonly int[] PixelsItemMap;
private readonly Bitmap MapReticle;
private readonly int[] PixelsBackgroundAcre1;
private readonly int[] PixelsBackgroundAcreX;
private readonly Bitmap BackgroundAcre;
private readonly int[] PixelsBackgroundMap1;
private readonly int[] PixelsBackgroundMapX;
private readonly Bitmap BackgroundMap;
public MapViewer(MapManager m) : base(m)
{
var l1 = m.Items.Layer1;
Scale1 = new int[l1.GridWidth * l1.GridHeight];
ScaleX = new int[Scale1.Length * AcreScale * AcreScale];
PixelsItemAcre1 = new int[l1.GridWidth * l1.GridHeight];
PixelsItemAcreX = new int[PixelsItemAcre1.Length * AcreScale * AcreScale];
ScaleAcre = new Bitmap(l1.GridWidth * AcreScale, l1.GridHeight * AcreScale);
MapPixels = new int[l1.MapWidth * l1.MapHeight * MapScale * MapScale];
PixelsItemMap = new int[l1.MapWidth * l1.MapHeight * MapScale * MapScale];
MapReticle = new Bitmap(l1.MapWidth * MapScale, l1.MapHeight * MapScale);
PixelsBackgroundAcre1 = new int[16 * 16];
PixelsBackgroundAcreX = new int[PixelsItemAcreX.Length];
BackgroundAcre = new Bitmap(ScaleAcre.Width, ScaleAcre.Height);
PixelsBackgroundMap1 = new int[PixelsItemMap.Length / 4];
PixelsBackgroundMapX = new int[PixelsItemMap.Length];
BackgroundMap = new Bitmap(MapReticle.Width, MapReticle.Height);
}
public void Dispose()
{
ScaleAcre.Dispose();
MapReticle.Dispose();
BackgroundAcre.Dispose();
BackgroundMap.Dispose();
}
public Bitmap GetLayerAcre(int t) => GetLayerAcre(X, Y, t);
public Bitmap GetBackgroundAcre(Font f, int index = -1) => GetBackgroundAcre(X, Y, f, index);
public Bitmap GetMapWithReticle(int t) => GetMapWithReticle(X, Y, t, Map.CurrentLayer);
public Bitmap GetBackgroundTerrain(int index = -1)
{
return TerrainSprite.GetMapWithBuildings(Map.Terrain, Map.Buildings, (ushort)Map.PlazaX, (ushort)Map.PlazaY, null, 2, index);
return TerrainSprite.GetMapWithBuildings(Map, null, PixelsBackgroundMap1, PixelsBackgroundMapX, BackgroundMap, 2, index);
}
private Bitmap GetLayerAcre(int topX, int topY, int t)
{
var layer = Map.CurrentLayer;
return FieldItemSpriteDrawer.GetBitmapLayerAcre(layer, topX, topY, AcreScale, Scale1, ScaleX, ScaleAcre, t);
return FieldItemSpriteDrawer.GetBitmapItemLayerAcre(layer, topX, topY, AcreScale, PixelsItemAcre1, PixelsItemAcreX, ScaleAcre, t);
}
private Bitmap GetBackgroundAcre(int topX, int topY, Font f, int index = -1)
public Bitmap GetBackgroundAcre(Font f, int index = -1)
{
return TerrainSprite.GetAcre(topX / 2, topY / 2, Map.Terrain, AcreScale * 2, Map.Buildings,
(ushort)Map.PlazaX, (ushort)Map.PlazaY, f, index);
return TerrainSprite.GetAcre(this, f, PixelsBackgroundAcre1, PixelsBackgroundAcreX, BackgroundAcre, index);
}
private Bitmap GetMapWithReticle(int topX, int topY, int t, FieldItemLayer layer)
{
return FieldItemSpriteDrawer.GetBitmapLayer(layer, topX, topY, MapPixels, MapReticle, t);
return FieldItemSpriteDrawer.GetBitmapItemLayer(layer, topX, topY, PixelsItemMap, MapReticle, t);
}
}
}

View File

@@ -16,6 +16,7 @@ protected override void Dispose(bool disposing)
if (disposing && (components != null))
{
components.Dispose();
Map.Dispose();
}
base.Dispose(disposing);
}

View File

@@ -19,6 +19,10 @@ public partial class TerrainEditor : Form
private const int SquareSize = 50;
private const int MapScale = 2;
private readonly int[] Scale1;
private readonly int[] ScaleX;
private readonly Bitmap Map;
public TerrainEditor(MainSave sav)
{
InitializeComponent();
@@ -31,6 +35,10 @@ public TerrainEditor(MainSave sav)
foreach (var acre in MapGrid.Acres)
CB_Acre.Items.Add(acre.Name);
Scale1 = new int[Terrain.MapWidth * Terrain.MapHeight];
ScaleX = new int[Scale1.Length * MapScale * MapScale];
Map = new Bitmap(Terrain.MapWidth * MapScale, Terrain.MapHeight * MapScale);
PG_Tile.SelectedObject = new TerrainTile();
CB_Acre.SelectedIndex = 0;
ReloadMap();
@@ -50,7 +58,7 @@ private void ChangeViewToAcre(int acre)
UpdateArrowVisibility(acre);
}
private void ReloadMap() => PB_Map.Image = TerrainSprite.CreateMap(Terrain, MapScale, X, Y);
private void ReloadMap() => PB_Map.Image = TerrainSprite.CreateMap(Terrain, MapScale, X, Y, Scale1, ScaleX, Map);
private void LoadGrid(int topX, int topY)
{
@@ -251,7 +259,7 @@ private void Menu_SavePNG_Click(object sender, EventArgs e)
}
const string name = "map";
var bmp = TerrainSprite.CreateMap(Terrain);
using var sfd = new SaveFileDialog
{
Filter = "png file (*.png)|*.png|All files (*.*)|*.*",
@@ -260,6 +268,8 @@ private void Menu_SavePNG_Click(object sender, EventArgs e)
if (sfd.ShowDialog() != DialogResult.OK)
return;
var bmp = new Bitmap(Terrain.MapWidth, Terrain.MapHeight);
ImageUtil.SetBitmapData(bmp, Scale1);
bmp.Save(sfd.FileName, ImageFormat.Png);
}