diff --git a/ClassicalSharp/2D/Screens/HudScreen.cs b/ClassicalSharp/2D/Screens/HudScreen.cs
index 594ca774e..23d45b613 100644
--- a/ClassicalSharp/2D/Screens/HudScreen.cs
+++ b/ClassicalSharp/2D/Screens/HudScreen.cs
@@ -15,9 +15,10 @@ namespace ClassicalSharp.Gui {
PlayerListWidget playerList;
Font playerFont;
- public void Init( Game game ) { Init(); }
-
+ public void Init( Game game ) { Init(); }
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
public override void Render( double delta ) {
if( game.HideGui ) return;
diff --git a/ClassicalSharp/Audio/AudioPlayer.cs b/ClassicalSharp/Audio/AudioPlayer.cs
index 77e1bcae1..a89b9ffd4 100644
--- a/ClassicalSharp/Audio/AudioPlayer.cs
+++ b/ClassicalSharp/Audio/AudioPlayer.cs
@@ -27,6 +27,8 @@ namespace ClassicalSharp.Audio {
}
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
public void SetMusic( bool enabled ) {
if( enabled )
diff --git a/ClassicalSharp/Commands/CommandManager.cs b/ClassicalSharp/Commands/CommandManager.cs
index 3c7a56ef3..3d138fe6c 100644
--- a/ClassicalSharp/Commands/CommandManager.cs
+++ b/ClassicalSharp/Commands/CommandManager.cs
@@ -26,6 +26,8 @@ namespace ClassicalSharp.Commands {
}
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
public void Register( Command command ) {
command.game = game;
diff --git a/ClassicalSharp/Commands/DefaultCommands.cs b/ClassicalSharp/Commands/DefaultCommands.cs
index 8bfaa33bc..8bbf7598e 100644
--- a/ClassicalSharp/Commands/DefaultCommands.cs
+++ b/ClassicalSharp/Commands/DefaultCommands.cs
@@ -141,14 +141,10 @@ namespace ClassicalSharp.Commands {
void SetNewRenderType( bool legacy, bool minimal ) {
game.MapBordersRenderer.UseLegacyMode( legacy );
if( minimal ) {
- game.EnvRenderer.Dispose();
- game.EnvRenderer = new MinimalEnvRenderer( game );
- game.EnvRenderer.Init();
+ game.ReplaceComponent( ref game.EnvRenderer, new MinimalEnvRenderer() );
} else {
- if( !( game.EnvRenderer is StandardEnvRenderer ) ) {
- game.EnvRenderer.Dispose();
- game.EnvRenderer = new StandardEnvRenderer( game );
- game.EnvRenderer.Init();
+ if( !(game.EnvRenderer is StandardEnvRenderer) ) {
+ game.ReplaceComponent( ref game.EnvRenderer, new StandardEnvRenderer() );
}
((StandardEnvRenderer)game.EnvRenderer).UseLegacyMode( legacy );
}
diff --git a/ClassicalSharp/Game/ChatLog.cs b/ClassicalSharp/Game/ChatLog.cs
index eb17cf33e..a703b7e99 100644
--- a/ClassicalSharp/Game/ChatLog.cs
+++ b/ClassicalSharp/Game/ChatLog.cs
@@ -19,6 +19,8 @@ namespace ClassicalSharp {
}
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
/// List of chat messages received from the server and added by client commands.
/// index 0 is the oldest chat message, last index is newest.
diff --git a/ClassicalSharp/Game/Game.Properties.cs b/ClassicalSharp/Game/Game.Properties.cs
index cd974e79c..674cc2a68 100644
--- a/ClassicalSharp/Game/Game.Properties.cs
+++ b/ClassicalSharp/Game/Game.Properties.cs
@@ -28,8 +28,14 @@ namespace ClassicalSharp {
/// Called when the game has loaded.
void Init( Game game );
- /// Called to reset the state when the user is reconnecting to a server.
+ /// Called to reset the component's state when the user is reconnecting to a server.
void Reset( Game game );
+
+ /// Called to update the component's state when the user begins loading a new map.
+ void OnNewMap( Game game );
+
+ /// Called to update the component's state when the user has finished loading a new map.
+ void OnNewMapLoaded( Game game );
}
public partial class Game {
diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs
index 027af7bf3..8174f06f7 100644
--- a/ClassicalSharp/Game/Game.cs
+++ b/ClassicalSharp/Game/Game.cs
@@ -62,6 +62,8 @@ namespace ClassicalSharp {
LoadOptions();
LoadGuiOptions();
Chat = AddComponent( new Chat() );
+ WorldEvents.OnNewMap += OnNewMapCore;
+ WorldEvents.OnNewMapLoaded += OnNewMapLoadedCore;
BlockInfo = new BlockInfo();
BlockInfo.Init();
@@ -89,8 +91,8 @@ namespace ClassicalSharp {
width = Width;
height = Height;
MapRenderer = new MapRenderer( this );
- MapBordersRenderer = new MapBordersRenderer( this );
- EnvRenderer = new StandardEnvRenderer( this );
+ MapBordersRenderer = AddComponent( new MapBordersRenderer() );
+ EnvRenderer = AddComponent( new StandardEnvRenderer() );
if( IPAddress == null ) {
Network = new Singleplayer.SinglePlayerServer( this );
} else {
@@ -117,8 +119,6 @@ namespace ClassicalSharp {
fpsScreen.Init();
hudScreen = AddComponent( new HudScreen( this ) );
Culling = new FrustumCulling();
- EnvRenderer.Init();
- MapBordersRenderer.Init();
Picking = AddComponent( new PickedPosRenderer() );
AudioPlayer = AddComponent( new AudioPlayer() );
AxisLinesRenderer = AddComponent( new AxisLinesRenderer() );
@@ -136,11 +136,6 @@ namespace ClassicalSharp {
Network.Connect( IPAddress, Port );
}
- public T AddComponent( T obj ) {
- Components.Add( (IGameComponent)obj );
- return obj;
- }
-
void LoadOptions() {
ClassicMode = Options.GetBool( "mode-classic", false );
ClassicHacks = Options.GetBool( OptionsKey.AllowClassicHacks, false );
@@ -200,6 +195,37 @@ namespace ClassicalSharp {
}
}
+ void OnNewMapCore( object sender, EventArgs e ) {
+ foreach( IGameComponent comp in Components )
+ comp.OnNewMap( this );
+ }
+
+ void OnNewMapLoadedCore( object sender, EventArgs e ) {
+ foreach( IGameComponent comp in Components )
+ comp.OnNewMapLoaded( this );
+ }
+
+ public T AddComponent( T obj ) where T : IGameComponent {
+ Components.Add( obj );
+ return obj;
+ }
+
+ public bool ReplaceComponent( ref T old, T obj ) where T : IGameComponent {
+ for( int i = 0; i < Components.Count; i++ ) {
+ if( !object.ReferenceEquals( Components[i], old ) ) continue;
+ old.Dispose();
+
+ Components[i] = obj;
+ old = obj;
+ obj.Init( this );
+ return true;
+ }
+
+ Components.Add( obj );
+ obj.Init( this );
+ return false;
+ }
+
public void SetViewDistance( int distance, bool save ) {
ViewDistance = distance;
if( ViewDistance > MaxViewDistance )
@@ -485,6 +511,8 @@ namespace ClassicalSharp {
ModelCache.Dispose();
ParticleManager.Dispose();
Players.Dispose();
+ WorldEvents.OnNewMap -= OnNewMapCore;
+ WorldEvents.OnNewMapLoaded -= OnNewMapLoadedCore;
foreach( IGameComponent comp in Components )
comp.Dispose();
diff --git a/ClassicalSharp/Game/Inventory.cs b/ClassicalSharp/Game/Inventory.cs
index 7e0fc061a..f868c7673 100644
--- a/ClassicalSharp/Game/Inventory.cs
+++ b/ClassicalSharp/Game/Inventory.cs
@@ -23,6 +23,8 @@ namespace ClassicalSharp {
}
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
public void Dispose() { }
diff --git a/ClassicalSharp/Network/Utils/AsyncDownloader.cs b/ClassicalSharp/Network/Utils/AsyncDownloader.cs
index c51e609c4..2f33e7a90 100644
--- a/ClassicalSharp/Network/Utils/AsyncDownloader.cs
+++ b/ClassicalSharp/Network/Utils/AsyncDownloader.cs
@@ -42,6 +42,8 @@ namespace ClassicalSharp.Network {
requests.Clear();
handle.Set();
}
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
/// Asynchronously downloads a skin. If 'skinName' points to the url then the skin is
/// downloaded from that url, otherwise it is downloaded from the url 'defaultSkinServer'/'skinName'.png
diff --git a/ClassicalSharp/Rendering/BlockHandRenderer.cs b/ClassicalSharp/Rendering/BlockHandRenderer.cs
index f1f86d3c5..12a011cf2 100644
--- a/ClassicalSharp/Rendering/BlockHandRenderer.cs
+++ b/ClassicalSharp/Rendering/BlockHandRenderer.cs
@@ -31,6 +31,8 @@ namespace ClassicalSharp.Renderers {
}
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
public void Render( double delta, float t ) {
if( game.Camera.IsThirdPerson || !game.ShowBlockInHand ) return;
diff --git a/ClassicalSharp/Rendering/EnvRenderer.cs b/ClassicalSharp/Rendering/EnvRenderer.cs
index 3501805b9..2f414ea7f 100644
--- a/ClassicalSharp/Rendering/EnvRenderer.cs
+++ b/ClassicalSharp/Rendering/EnvRenderer.cs
@@ -6,28 +6,26 @@ using ClassicalSharp.Map;
namespace ClassicalSharp.Renderers {
- public abstract class EnvRenderer : IDisposable {
+ public abstract class EnvRenderer : IGameComponent {
protected World map;
protected Game game;
protected IGraphicsApi graphics;
- public virtual void Init() {
+ public virtual void Init( Game game ) {
+ this.game = game;
+ map = game.World;
graphics = game.Graphics;
- game.WorldEvents.OnNewMap += OnNewMap;
- game.WorldEvents.OnNewMapLoaded += OnNewMapLoaded;
game.WorldEvents.EnvVariableChanged += EnvVariableChanged;
- }
-
- public virtual void OnNewMap( object sender, EventArgs e ) {
}
- public virtual void OnNewMapLoaded( object sender, EventArgs e ) {
- }
+ public virtual void Reset( Game game ) { OnNewMap( game ); }
+
+ public abstract void OnNewMap( Game game );
+
+ public abstract void OnNewMapLoaded( Game game );
public virtual void Dispose() {
- game.WorldEvents.OnNewMap -= OnNewMap;
- game.WorldEvents.OnNewMapLoaded -= OnNewMapLoaded;
game.WorldEvents.EnvVariableChanged -= EnvVariableChanged;
}
diff --git a/ClassicalSharp/Rendering/MapBordersRenderer.cs b/ClassicalSharp/Rendering/MapBordersRenderer.cs
index d292f9c8d..a071c17f2 100644
--- a/ClassicalSharp/Rendering/MapBordersRenderer.cs
+++ b/ClassicalSharp/Rendering/MapBordersRenderer.cs
@@ -9,18 +9,12 @@ using OpenTK;
namespace ClassicalSharp.Renderers {
- public unsafe sealed class MapBordersRenderer : IDisposable {
+ public unsafe sealed class MapBordersRenderer : IGameComponent {
World map;
Game game;
IGraphicsApi graphics;
- public MapBordersRenderer( Game game ) {
- this.game = game;
- map = game.World;
- graphics = game.Graphics;
- }
-
int sidesVb = -1, edgesVb = -1;
int edgeTexId, sideTexId;
int sidesVertices, edgesVertices;
@@ -31,9 +25,11 @@ namespace ClassicalSharp.Renderers {
ResetSidesAndEdges( null, null );
}
- public void Init() {
- game.WorldEvents.OnNewMap += OnNewMap;
- game.WorldEvents.OnNewMapLoaded += OnNewMapLoaded;
+ public void Init( Game game ) {
+ this.game = game;
+ map = game.World;
+ graphics = game.Graphics;
+
game.WorldEvents.EnvVariableChanged += EnvVariableChanged;
game.Events.ViewDistanceChanged += ResetSidesAndEdges;
game.Events.TerrainAtlasChanged += ResetTextures;
@@ -74,8 +70,6 @@ namespace ClassicalSharp.Renderers {
}
public void Dispose() {
- game.WorldEvents.OnNewMap -= OnNewMap;
- game.WorldEvents.OnNewMapLoaded -= OnNewMapLoaded;
game.WorldEvents.EnvVariableChanged -= EnvVariableChanged;
game.Events.ViewDistanceChanged -= ResetSidesAndEdges;
game.Events.TerrainAtlasChanged -= ResetTextures;
@@ -87,7 +81,9 @@ namespace ClassicalSharp.Renderers {
sidesVb = edgesVb = -1;
}
- void OnNewMap( object sender, EventArgs e ) {
+ public void Reset( Game game ) { OnNewMap( game ); }
+
+ public void OnNewMap( Game game ) {
graphics.DeleteVb( sidesVb );
graphics.DeleteVb( edgesVb );
sidesVb = edgesVb = -1;
@@ -96,7 +92,7 @@ namespace ClassicalSharp.Renderers {
MakeTexture( ref sideTexId, ref lastSideTexLoc, map.SidesBlock );
}
- void OnNewMapLoaded( object sender, EventArgs e ) {
+ public void OnNewMapLoaded( Game game ) {
CalculateRects( game.ViewDistance );
RebuildSides( map.SidesHeight, legacy ? 128 : 65536 );
RebuildEdges( map.EdgeHeight, legacy ? 128 : 65536 );
diff --git a/ClassicalSharp/Rendering/MinimalEnvRenderer.cs b/ClassicalSharp/Rendering/MinimalEnvRenderer.cs
index 2f8addb7b..a61325ce0 100644
--- a/ClassicalSharp/Rendering/MinimalEnvRenderer.cs
+++ b/ClassicalSharp/Rendering/MinimalEnvRenderer.cs
@@ -8,25 +8,19 @@ namespace ClassicalSharp.Renderers {
/// (no fog, clouds, or proper overhead sky)
public class MinimalEnvRenderer : EnvRenderer {
- public MinimalEnvRenderer( Game game ) {
- this.game = game;
- map = game.World;
+ public override void Init( Game game ) {
+ base.Init( game );
+ graphics.Fog = false;
+ graphics.ClearColour( map.SkyCol );
}
public override void Render( double deltaTime ) {
graphics.ClearColour( map.SkyCol );
}
- public override void Init() {
- base.Init();
- graphics.Fog = false;
- graphics.ClearColour( map.SkyCol );
- }
+ public override void OnNewMap( Game game ) { }
- public override void OnNewMap( object sender, EventArgs e ) {
- }
-
- public override void OnNewMapLoaded( object sender, EventArgs e ) {
+ public override void OnNewMapLoaded( Game game ) {
graphics.ClearColour( map.SkyCol );
}
diff --git a/ClassicalSharp/Rendering/StandardEnvRenderer.cs b/ClassicalSharp/Rendering/StandardEnvRenderer.cs
index b6c326c86..37a3a49fb 100644
--- a/ClassicalSharp/Rendering/StandardEnvRenderer.cs
+++ b/ClassicalSharp/Rendering/StandardEnvRenderer.cs
@@ -8,11 +8,6 @@ namespace ClassicalSharp.Renderers {
public unsafe class StandardEnvRenderer : EnvRenderer {
- public StandardEnvRenderer( Game game ) {
- this.game = game;
- map = game.World;
- }
-
int cloudsVb = -1, cloudVertices, skyVb = -1, skyVertices;
bool legacy;
@@ -58,25 +53,25 @@ namespace ClassicalSharp.Renderers {
}
}
- public override void OnNewMap( object sender, EventArgs e ) {
+ public override void Init( Game game ) {
+ base.Init( game );
+ graphics.Fog = true;
+ ResetAllEnv( null, null );
+ game.Events.ViewDistanceChanged += ResetAllEnv;
+ }
+
+ public override void OnNewMap( Game game ) {
graphics.Fog = false;
graphics.DeleteVb( skyVb );
graphics.DeleteVb( cloudsVb );
skyVb = cloudsVb = -1;
}
- public override void OnNewMapLoaded( object sender, EventArgs e ) {
+ public override void OnNewMapLoaded( Game game ) {
graphics.Fog = true;
ResetAllEnv( null, null );
}
- public override void Init() {
- base.Init();
- graphics.Fog = true;
- ResetAllEnv( null, null );
- game.Events.ViewDistanceChanged += ResetAllEnv;
- }
-
void ResetAllEnv( object sender, EventArgs e ) {
ResetFog();
ResetSky();
diff --git a/ClassicalSharp/Rendering/WeatherRenderer.cs b/ClassicalSharp/Rendering/WeatherRenderer.cs
index 44e422f1f..53d7cd754 100644
--- a/ClassicalSharp/Rendering/WeatherRenderer.cs
+++ b/ClassicalSharp/Rendering/WeatherRenderer.cs
@@ -19,11 +19,7 @@ namespace ClassicalSharp.Renderers {
graphics = game.Graphics;
info = game.BlockInfo;
weatherVb = graphics.CreateDynamicVb( VertexFormat.P3fT2fC4b, vertices.Length );
- game.WorldEvents.OnNewMap += OnNewMap;
- game.WorldEvents.OnNewMapLoaded += OnNewMapLoaded;
- }
-
- public void Reset( Game game ) { }
+ }
int weatherVb;
short[] heightmap;
@@ -98,12 +94,14 @@ namespace ClassicalSharp.Renderers {
}
int length, width, maxY, oneY;
- void OnNewMap( object sender, EventArgs e ) {
+ public void Reset( Game game ) { OnNewMap( game ); }
+
+ public void OnNewMap( Game game ) {
heightmap = null;
lastPos = new Vector3I( Int32.MaxValue );
}
- void OnNewMapLoaded( object sender, EventArgs e ) {
+ public void OnNewMapLoaded( Game game ) {
length = map.Length;
width = map.Width;
maxY = map.Height - 1;
@@ -118,8 +116,6 @@ namespace ClassicalSharp.Renderers {
}
public void Dispose() {
- game.WorldEvents.OnNewMap -= OnNewMap;
- game.WorldEvents.OnNewMapLoaded -= OnNewMapLoaded;
graphics.DeleteDynamicVb( weatherVb );
}
diff --git a/ClassicalSharp/Selections/AxisLinesRenderer.cs b/ClassicalSharp/Selections/AxisLinesRenderer.cs
index 875399065..c79be5a5c 100644
--- a/ClassicalSharp/Selections/AxisLinesRenderer.cs
+++ b/ClassicalSharp/Selections/AxisLinesRenderer.cs
@@ -16,6 +16,8 @@ namespace ClassicalSharp.Selections {
}
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
public void Dispose() {
game.Graphics.DeleteDynamicVb( vb );
diff --git a/ClassicalSharp/Selections/PickedPosRenderer.cs b/ClassicalSharp/Selections/PickedPosRenderer.cs
index 7df614036..0e08030c0 100644
--- a/ClassicalSharp/Selections/PickedPosRenderer.cs
+++ b/ClassicalSharp/Selections/PickedPosRenderer.cs
@@ -18,6 +18,8 @@ namespace ClassicalSharp.Renderers {
}
public void Reset( Game game ) { }
+ public void OnNewMap( Game game ) { }
+ public void OnNewMapLoaded( Game game ) { }
FastColour col = FastColour.Black;
int index;
diff --git a/ClassicalSharp/Selections/SelectionManager.cs b/ClassicalSharp/Selections/SelectionManager.cs
index fa02e57ec..c08249cc6 100644
--- a/ClassicalSharp/Selections/SelectionManager.cs
+++ b/ClassicalSharp/Selections/SelectionManager.cs
@@ -16,12 +16,11 @@ namespace ClassicalSharp.Selections {
public void Init( Game game ) {
this.game = game;
Graphics = game.Graphics;
- game.WorldEvents.OnNewMap += OnNewMap;
}
- public void Reset( Game game ) {
- selections.Clear();
- }
+ public void Reset( Game game ) { selections.Clear(); }
+ public void OnNewMap( Game game ) { selections.Clear(); }
+ public void OnNewMapLoaded( Game game ) { }
List selections = new List( 256 );
public void AddSelection( byte id, Vector3I p1, Vector3I p2, FastColour col ) {
@@ -71,10 +70,7 @@ namespace ClassicalSharp.Selections {
Graphics.AlphaBlending = false;
}
- public void Dispose() {
- OnNewMap( null, null );
- game.WorldEvents.OnNewMap -= OnNewMap;
-
+ public void Dispose() {
if( lineVb <= 0 ) return;
Graphics.DeleteDynamicVb( vb );
Graphics.DeleteDynamicVb( lineVb );
@@ -87,9 +83,5 @@ namespace ClassicalSharp.Selections {
vb = Graphics.CreateDynamicVb( VertexFormat.P3fC4b, vertices.Length );
lineVb = Graphics.CreateDynamicVb( VertexFormat.P3fC4b, lineVertices.Length );
}
-
- void OnNewMap( object sender, EventArgs e ) {
- selections.Clear();
- }
}
}
\ No newline at end of file