How to load and Unload a level - xna

I'm coding my first game with XNA and i'm a bit confused.
The game is a 2D platform game, in pixel-perfect, NOT Tiles based.
Currently, my code looks like this
public class Game1 : Microsoft.Xna.Framework.Game
{
//some variables
Level currentLevel, level1, level2;
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
//a level contains 3 sprites (background, foreground, collisions)
//and the start position of the player
level1 = new Level(
new Sprite(Content.Load<Texture2D>("level1/intro-1er-plan"), Vector2.Zero),
new Sprite(Content.Load<Texture2D>("level1/intro-collisions"), Vector2.Zero),
new Sprite(Content.Load<Texture2D>("level1/intro-decors-fond"), Vector2.Zero),
new Vector2(280, 441));
level2 = new Level(
new Sprite(Content.Load<Texture2D>("level2/intro-1er-plan"), Vector2.Zero),
new Sprite(Content.Load<Texture2D>("level2/intro-collisions"), Vector2.Zero),
new Sprite(Content.Load<Texture2D>("level2/intro-decors-fond"), Vector2.Zero),
new Vector2(500, 250));
...//etc
}
protected override void UnloadContent() {}
protected override void Update(GameTime gameTime)
{
if(the_character_entered_zone1())
{
ChangeLevel(level2);
}
//other stuff
}
protected override void Draw(GameTime gameTime)
{
//drawing code
}
private void ChangeLevel(Level _theLevel)
{
currentLevel = _theLevel;
//other stuff
}
Every sprites are loaded since the beginning, so it's not a good idea for the computer's RAM.
Well, Here are my questions :
How can i save a level with his own number of sprites, their events and objects ?
How can i load/unload these levels ?

Give each level its own ContentManager, and use that instead of Game.Content (for per-level content).
(Create new ContentManager instances by passing Game.Services to the constructor.)
A single ContentManager will share all instances of content that it loads (so if you load "MyTexture" twice, you will get the same instance of it both times). Due to this fact, the only way to unload content is to unload the entire content manager (with .Unload()).
By using multiple content managers, you can get more granularity with unloading (so you can unload the content for just a single level).
Just note that different instances of ContentManager don't know about each other and won't share content. For example if you load "MyTexture" on two different content managers, you get two separate instances (so you use twice the memory).
The simplest way to deal with this is to load all the "shared" stuff with Game.Content, and all the per-level stuff with the separate level content managers.
If this still doesn't provide enough control, you can derive a class from ContentManager and implement your own load/unload policies (example in this blog post). Although this is rarely worth the effort.
Remember that this is an optimisation (for memory) - so don't spend too much time on it until it becomes an actual issue.
I recommend reading this answer (on the gamedev site) that provides some tips and links to further answers that explain in more depth how ContentManager works.

Related

How to calculate memory size in Ehcache?

import java.util.ArrayList;
import java.util.List;
import net.sf.ehcache.pool.sizeof.UnsafeSizeOf;
public class EhCacheTest {
private List<Double> testList = new ArrayList<Double>();
public static void main(String[] args) {
EhCacheTest test = new EhCacheTest();
for(int i=0;i<1000;i++) {
test.addItem(1.0);
System.out.println(new UnsafeSizeOf().sizeOf(test));
}
}
public void addItem(double a) {
testList.add(a);
}
}
I used UnsafeSizeOf to calculate the size of Object 'test'.
Nomatter how many doubles I add into the list, the size of 'test' is always 16 bytes.
Because of this, the maxBytesLocalHeap paramater is useless for me.
Given your code snippet, this is totally expected.
See the javadoc of the method SizeOf.sizeOf, it clearly states that it sizes the instance without navigating the object graph.
What you want to use is SizeOf.deepSizeOf which will navigate the object graph.
However this test is flawed, cause you risk comparing that specific SizeOf implementation against another one, as Ehcache uses multiple implementations, depending on what's available in a specific environment.
If you really want to confirm the byte sizing on heap works, you are better off filling a cache, finding out the size it reports through statistics and then do a heap dump to see how much memory is effectively used.

SharpDX:How to place SharpDX Window in Winforms Window?

I'm actually tryin to place SharpDX Window in Winforms Window like in the following video:
http://www.youtube.com/watch?v=g-JupOxwB-k
In SharpDX this method doesn't work.Can anyone tell me how to EASILY do this ?
don't think of it as putting a sharpDX window into a winforms window.
instead think of it as how to output SharpDX to the windows handle (sorta)
the key is in the SharpDX.DXGI.SwapChain. when creating this you will need a SwapChainDescription
I like to create mine like
SwapChainDescription scd = new SwapChainDescription()
{
//set other fields
OutputHandle = yourform.Handle,
//set other fields
};
Handle
SwapChainDescription
so when you call SwapChain.Present() it will render to the form.
this is the basic way to do it with straight SharpDX and not the toolkit stuff
EDIT 04222019 LINKS DO NOT WORK --- 01052022 Link fixed
if you want to use the toolkit's GraphicsDevice you will have to set the Presenter property. in almost the same way you set the window handle in the presentation parameters.
https://github.com/sharpdx/Toolkit/tree/master/Documentation
also the toolkit has the RenderForm which plays nice with the Game class
04222019
EDIT (DirectX Example)
here is an example using straight SharpDX (No Toolkit). for complete examples you should refer to the github examples HERE
As stated above all you need to do to render to a WindowsForm window is pass the Handle to the SwapChain
visual studio 2012
add the references: (all other references are default winforms project references)
some using statements to make things easier:
namespace YourNameSpaceHere
{
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
...the rest of the application
}
the Form class: here we make the device, swap chain, render target , and render target view a variable of the Form class we are declaring
public partial class Form1 : Form //default vs2012 declaration
{
Device d; //Direct311
SwapChain sc; //DXGI
Texture2D target; //Direct3D11
RenderTargetView targetveiw;//DIrect3D11
...the rest of the form
}
Initializing the Device and SwapChain: this is what works for me on my system. if you have problems than you need to research your specific implementation and hardware. DirectX (and by extension SharpDX) has methods by which you can detect what the hardware will support.
the main code Example:
using System;
using System.ComponentModel;//needed to overide OnClosing
//I removed useless usings
using System.Windows.Forms;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX;
namespace WindowsFormsApplication2
{
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
public partial class Form1 : Form
{
Device d;
SwapChain sc;
Texture2D target;
RenderTargetView targetveiw;
public Form1()
{
InitializeComponent();
SwapChainDescription scd = new SwapChainDescription()
{
BufferCount = 1, //how many buffers are used for writing. it's recommended to have at least 2 buffers but this is an example
Flags = SwapChainFlags.None,
IsWindowed = true, //it's windowed
ModeDescription = new ModeDescription(
this.ClientSize.Width, //windows veiwable width
this.ClientSize.Height, //windows veiwable height
new Rational(60,1), //refresh rate
Format.R8G8B8A8_UNorm), //pixel format, you should resreach this for your specific implementation
OutputHandle = this.Handle, //the magic
SampleDescription = new SampleDescription(1, 0), //the first number is how many samples to take, anything above one is multisampling.
SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput
};
Device.CreateWithSwapChain(
SharpDX.Direct3D.DriverType.Hardware,//hardware if you have a graphics card otherwise you can use software
DeviceCreationFlags.Debug, //helps debuging don't use this for release verion
scd, //the swapchain description made above
out d, out sc //our directx objects
);
target = Texture2D.FromSwapChain<Texture2D>(sc, 0);
targetveiw = new RenderTargetView(d, target);
d.ImmediateContext.OutputMerger.SetRenderTargets(targetveiw);
}
protected override void OnClosing(CancelEventArgs e)
{
//dipose of all objects
d.Dispose();
sc.Dispose();
target.Dispose();
targetveiw.Dispose();
base.OnClosing(e);
}
protected override void OnPaint(PaintEventArgs e)
{
//I am rendering here for this example
//normally I use a seperate thread to call Draw() and Present() in a loop
d.ImmediateContext.ClearRenderTargetView(targetveiw, Color.CornflowerBlue);//Color to make it look like default XNA project output.
sc.Present(0, PresentFlags.None);
base.OnPaint(e);
}
}
}
this is meant to get you started with using DirectX using ShaprDX in a managed environment, specifically C# on Windows. there is much much more you will need to get something real off the ground. and this is meant as the gateway to rendering on a Winforms window using SharpDX. I don't explain things like vertex/index buffers or rendering Textures/Sprites. because it is out of scope for the question.

What are the best practicies concerning bootstraping and ioc container?

Here is my story :
I'm working on a not so large WPF / C# application implementing (for the first time) inversion of control with the help of Unity Framework. It is mostly finished. My problem come from my "bootstrapper" class, in wich I register my types in the Unity container. With the important number of classes involved, my bootstrapper turned to be much more longer than I'd like and despite the comments/regions, to maintain it would be a pain for anyone else than me. So I was wondering if there was a better way to handle registeration. I was thinking, that maybe :
1. "What are you complaining of ? Every one does it this way" Mmmh, I doubt it
2. I have misunderstood the interest of ioc and too much of my classes need registeration. Well, what would be the interest of ioc ?
3. I simply created a ravioli app with too much different classes, I should merge some I think I did my best to find a balance
4.I should not have one macro bootstrapper, but the main one should call specialized ones, one by librairy for example okay, that begins to sound good. After all, the librairies themselves should know better than others what they contain. But I absolutely don't know how to handle it without having my container tramping in every libraries, these having a dependency over Unity...
So, is one of this points good, or did I just miss the post about the nice way to handle registeration, with comfort of maintainability, that anyone use ?
PS : I did not mentioned the technos in tags, because the question seemed to be pretty common to every app working with an ioc container
Edit : Code Added for the bootstrepper (misnamed bootloader)
It's an old version, it has grow longer by now, something like +15-20%
class Bootloader
{
public void Run()
{
#region SPLASH SCREEN
Sequenceur.IHM.Views.SplashScreen screen = new Sequenceur.IHM.Views.SplashScreen();
SplashScreenViewModel screenVM = new SplashScreenViewModel();
screen.Show();
#endregion
#region CONTAINER INITIALIZATION
UnityContainer container = new UnityContainer();
container.RegisterType<IMainWorker, Overseer>();
#endregion
#region DAL REGISTERATION
container.RegisterType<IManageData<Product>, LazyProductFilesManager>();
container.RegisterType<IManageData<Program>, LazyProgramFilesManager>();
container.RegisterType<IManageData<SequenceResult>, LazyResultFilesManager>();
#endregion
#region BOL REGISTERATION
//Sequence preparation
container.RegisterType<IProvideProducts, EagerCancellableProductProvider>();
container.RegisterType<IProvidePrograms, EagerCancellableProgramProvider>();
container.RegisterType<IPrepareSequence, SequenceInitializer>();
//Sequence processing
container.RegisterType<IManagePlugins, MefPluginManager>(new ContainerControlledLifetimeManager());
//Result Persistence
container.RegisterType<IPersistSequenceResult, SequenceResultPersister>();
container.RegisterType<IManageReport, Reporter>(new ContainerControlledLifetimeManager());
#endregion
#region UPDATE REGISTERATION
container.RegisterType<IManageConnection, SqlConnectionManager>();
container.RegisterType<IUpdateProducts, ProductsUpdater>();
container.RegisterType<IUpdatePrograms, ProgramsUpdater>();
container.RegisterType<IUploadResults, ResultsUploader>();
container.RegisterType<IUpdate, DevelopmentUpdater>(new ContainerControlledLifetimeManager());
#endregion
#region HELPERS REGISTERATION
//Hashing
container.RegisterType<IHashString, Sha256StringHasher>();
//Configuration
container.RegisterType<IPersistConfiguration, ConfigurationPropertiesPersister>();
container.RegisterType<IConfiguration, EditableConfiguration>();
//Logging
container.RegisterType<IManageLoggers, NLoggerManager>();
//Messengers
container.RegisterType<IMessagePublisher<Exception>, SimpleMessenger<Exception>>(new ContainerControlledLifetimeManager());
container.RegisterType<IMessagePublisher<AbortRequest>, SimpleMessenger<AbortRequest>>(new ContainerControlledLifetimeManager());
container.RegisterType<IMessagePublisher<ConfigData>, SimpleMessenger<ConfigData>>(new ContainerControlledLifetimeManager());
container.RegisterType<IMessagePublisher<SequenceAction>, SimpleMessenger<SequenceAction>>(new ContainerControlledLifetimeManager());
container.RegisterType<IMessagePublisher<UpdaterStatus>, SimpleMessenger<UpdaterStatus>>(new ContainerControlledLifetimeManager());
container.RegisterType<IMessageListener<AbortRequest>>();
#endregion
#region IHM REGISTERATION
container.RegisterType<ILoadMenuViews, SimpleMenuViewLoader>();
container.RegisterType<IManageScene, SceneManager>();
container.RegisterType<IProvideOD, WinFormOFDialog>();
#endregion
#region CONVERTERS REGISTERATION
container.RegisterType<IConvertModels<Parameter, dbParameterResult>, ParameterModelsConverter>();
container.RegisterType<IConvertModels<SequenceActionResult, dbActionResult>, ActionModelsConverter>();
container.RegisterType<IConvertModels<Tag, dbTag>, TagModelsConverter>();
container.RegisterType<IConvertModels<Country, dbCountry>, CountryModelsConverter>();
container.RegisterType<IConvertModels<Segment, dbSegment>, SegmentModelsConverter>();
container.RegisterType<IConvertModels<Caracteristic, dbCaracteristic>, CaracteristicModelsConverter>();
container.RegisterType<IConvertModels<Value, dbValue>, ValueModelsConverter>();
container.RegisterType<IConvertModels<Range, dbRange>, RangeModelsConverter>();
container.RegisterType<IConvertModels<Subrange, dbSubrange>, SubrangeModelsConverter>();
container.RegisterType<IConvertModels<Product, dbProduct>, ProductModelsConverter>();
container.RegisterType<IConvertModels<Program, dbProgram>, ProgramModelsConverter>();
container.RegisterType<IConvertModels<Tag, dbTag>, TagModelsConverter>();
#endregion
#region START
ShellView mainView = new ShellView();
mainView.DataContext = container.Resolve<ShellViewModel>();
screen.Close();
mainView.Show();
#endregion
}
}
The famous Mark Seemann has written a blog post explaining when to use a DI container. What he basically says is that the usefulness of a DI container is limited when only use 'Explicit Register', having a line of code per registered type in the container (which is what you are doing). The real benefit starts when you use a Convention over Configuration. With convention over configuration you will be able to register a large amount of types in a single line of code, and you prevent your composition root from becoming this maintenance nightmare.
Although I'm not exactly on the same page and see some use for the 'Explicit Register' model, he is right that you gain the most benefit from using convention over configuration. In your application there are already a few clear spots where you would benefit from convention over configuration and that's when registering your generic abstractions such as IManageData<T>, IConvertModels and IMessagePublisher<TMessage>.
So what you can do is create the following convenient extension method:
public static void RegisterManyForOpenGeneric(this UnityContainer container,
Type openGenericServiceType, params Assembly[] assemblies)
{
container.RegisterTypes(
from type in AllClasses.FromAssemblies(assemblies)
where type.GetInterfaces().Any(i => i.IsGenericType &&
i.GetGenericTypeDefinition() == openGenericServiceType)
select type,
WithMappings.FromMatchingInterface,
WithName.Default);
}
With this extension method you can reduce the registrations of your generic abstractions to the following:
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
container.RegisterManyForOpenGeneric(typeof(IManageData<>), assemblies);
container.RegisterManyForOpenGeneric(typeof(IConvertModels<,>), assemblies);
container.RegisterManyForOpenGeneric(typeof(IMessagePublisher<>), assemblies);

Creating objects with dependencies - dependency injection

Let's say we have class:
public class WithDependencies
{
public WithDependencies(IAmDependencyOne first, IAmDependencyTwo second)
// ...
}
Now the question. How do you create objects of WithDependencies class in an application?
I know there are many ways.
new WithDependencies(new DependencyOne(), new DependencyTwo());
new WithDependencies(IoC.Resolve(IDependencyOne), IoC.Resolve(IDependencyTwo());
// register IDependencyOne, IDependencyTwo implementations at app start
IoC.Resolve(WithDependencies);
// register IDependencyOne, IDependencyTwo implementations at app start
// isolate ourselves from concrete IoC Container
MyCustomWithDependenciesFactory.Create();
and so on...
What do you think is the way to do it?
Edit:
Because I don't get answers or I don't understand them I'll try to ask again. Let's say that on some event (button, timer, whatever) I need new object WithDependencies(). How do I create it? Assume IoC container is already configured.
It depends on the context, so it's impossible to provide a single answer. Conceptually you'd be doing something like this from the Composition Root:
var wd = new WithDependencies(new DependencyOne(), new DependencyTwo());
However, even in the absence of a DI Container, the above code isn't always unambiguously the correct answer. In some cases, you might want to share the same dependency among several consumers, like this:
var dep1 = new DependencyOne();
var wd = new WithDependencies(dep1, new DependencyTwo());
var another = AnotherWithDependencies(dep1, new DependencyThree());
In other cases, you might not want to share dependencies, in which case the first option is more correct.
This is just a small glimpse of an entire dimension of DI concerned with Lifetime Management. Many DI Containers can take care of that for you, which is one excellent argument to prefer a DI Container over Poor Man's DI.
Once you start using a DI Container, you should follow the Register Resolve Release pattern when resolving types, letting Auto-wiring take care of the actual composition:
var wd = container.Resolve<WithDependencies>();
The above example assumes that the container is already correctly configured.
If you need to create a dependency which has its own dependencies, you can either A) do it yourself, or B) ask something else to do it for you. Option A negates the benefits of dependency injection (decoupling, etc.), so I would say option B is a better starting point. Now, we have chosen to use the factory pattern, no matter whether it takes the form of a service locator (i.e. IoC.Resolve), a static factory, or an instance factory. The point is that we have delegated that responsibility to an external authority.
There are a number of trade-offs required for static accessors. (I went over them in another answer, so I won't repeat them here.) In order to avoid introducing a dependency on the infrastructure or the container, a solid option is to accept a factory for creating WithDependencies when we need an instance somewhere else:
public class NeedsWithDependencies
{
private readonly IWithDependenciesFactory _withDependenciesFactory;
public NeedsWithDependencies(IWithDependenciesFactory withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory.Create();
...Use the instance...
}
}
Next, we can create a container-specific implementation of the factory:
public class WithDependenciesFactory : IWithDependenciesFactory
{
private readonly IContainer _container;
public WithDependenciesFactory(IContainer container)
{
_container = container
}
public WithDependencies Create()
{
return _container.Resolve<WithDependencies>();
}
}
Now NeedsWithDependencies is completely isolated from any knowledge of how WithDependencies gets created; it also exposes all its dependencies in its constructor, instead of hiding dependencies on static accessors, making it easy to reuse and test.
Defining all those factories can get a little cumbersome, though. I like Autofac's factory relationship type, which will detect parameters of the form Func<TDependency> and automatically inject a function which serves the same purpose as the hand-coded factory above:
public class NeedsWithDependencies
{
private readonly Func<WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo()
{
var withDependencies = _withDependenciesFactory();
...Use the instance...
}
}
It also works great with runtime parameters:
public class NeedsWithDependencies
{
private readonly Func<int, WithDependencies> _withDependenciesFactory;
public NeedsWithDependencies(Func<int, WithDependencies> withDependenciesFactory)
{
_withDependenciesFactory = withDependenciesFactory;
}
public void Foo(int x)
{
var withDependencies = _withDependenciesFactory(x);
...Use the instance...
}
}
Sometimes I try to get rid of factories or at least not depend directly on them, so Dependency Injection (without factories) is useful of course.
Therefore I use Google Juice, cause its a small little framework using Java Annotations and you can quickly change your injections / dependencies. Just take a look at it:
http://code.google.com/p/google-guice/

MEF - notify when plugins are loaded / unloaded

I have a simple asp mvc app which uses MEF, and there is a route which can be accessed by admins to refresh the directory catalog and compose parts, however one thing I am trying to find out how to do is notify some code when a plugin is loaded / unloaded.
The scenario is that when plugins are loaded they register the routes they need, however when they are unloaded I need them to unload their routes, as subsequent refreshes try to re-register the routes and it bombs.
Are there any events which I can hook into from the MEF objects?
The plugin container is something like:
[ImportMany(typeof(ISomePluginInterface))]
IEnumerable<ISomePluginInterface> Plugins {get; private set;}
Each ISomePluginInterface has something like:
public interface ISomePluginInterface
{
public void PluginLoaded();
public void PluginUnloaded();
}
This is similar in theory to this Stackoverflow question and this was my answer. In your case, you have a similar need, you want to fire an event when the plugin is started, and clean up when it is no longer needed.
Using the same concept, you can use the InterceptingCatalog to register routes, but I wouldn't make it an explicit part of the interface definition to do so, instead, you need to look at how your components fit together as a whole, e.g., if the operations for registering routes won't be used for all plugins, what is the purpose of them existing in the interface definition. You could break out the route registration into a separate interface, the IRouteRegistrar, and use intercepting strategies to automatically call the appropriate registration method when the plugin is used for the first time, e.g., I could break out the interface into:
public interface IPlugin
{
void SomeOperation();
}
public interface IRouteRegistrar : IDisposable
{
void RegisterRoutes();
}
The latter interface does the work of registering routes, and we use the Dispose pattern to ensure that it is cleaned up after it is finished with. Therefore, A sample plugin could resemble:
[Export(typeof(IPlugin))]
public class MyPlugin : IPlugin, IRouteRegistrar
{
public void SomeOperation() { }
public void RegisterRoutes()
{
// Register routes here...
}
protected virtual Dispose(bool disposing)
{
if (disposing)
{
// Unregister routes here...
}
}
void IDisposable.Dispose()
{
Dispose(true);
}
}
I only export as an IPlugin, but I ensure my plugin also implements the IRouteRegistrar. The way we use that, is with a strategy:
public class RouteRegistrarStrategy : IExportedValueInteceptor
{
public object Intercept(object value)
{
var registrar = value as IRouteRegistrar;
if (registrar != null)
registrar.RegisterRoutes();
return value;
}
}
Now, only if the plugin supports that interface will it register routes. This also enables you to apply the route registration interface to other plugins which could be used in a different way. You gain a bit more flexibility. To use that strategy in code, you need to add the MefContrib project to your app, and do a little more wire up:
var catalog = new DirectoryCatalog(".\bin");
var config = new InterceptionConfiguration().AddInterceptor(new RouteRegistrarStrategy());
var interceptingCatalog = new InterceptingCatalog(catalog, configuration);
var container = new CompositionContainer(interceptingCatalog);

Resources