I have made two different posts the last couple of days about we going from XNA to MonoGame and how the application increase in memory and no input from keyboard is detected after the first time it has been launched.
Using WinForms with a button to start a MonoGame.
private void button1_Click(object sender, EventArgs e)
{
viThread = new Thread(Demo);
viThread.Priority = ThreadPriority.Highest;
viThread.Start();
}
private void Demo()
{
using(Demo d = new Demo())
d.Run();
}
Since Monogame are using SharpDX (XNA did not) I call for a function when i Exit the application with Game.Exit() which look like:
SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects().Length;
The number is always above 600. How can I Dispose/Remove all resources? I think that will solve both problems (memory leak for sure). Greetings
Both MonoGame and your code should dispose all objects and it will ultimately dispose SharpDX resources, but you should not having to dispose SharpDX resources directly. As MonoGame is a facade to SharpDX, it is usually considered as the owner of SharpDX objects. I don't know the details about MonoGame implementation, so I don't know if they are handling the whole Dispose process correctly but you should check this with them (A dispose of a Game class should call dispose on all GameComponent including the ContentManager... etc.)
Related
In this Flambe guide it says:
"This dispose function removes this component from its owning entity. You should override the dispose-function in order to dispose objects yourself, to prevent memory leaks."
I have 3 questions:
How should I override the dispose function?
How to properly use the dispose function?
Is there a way to check for memory leaks in Flambe?
1 If you're using Component
override public function dispose() {
myReferences = null;
myDisposable.dispose();
super.dispose();
}
If you are not using a Component:
You can implement Disposable and dispose when needed in another dispose function.
2 You need to clear references to objects, that means set it to null.
You need to close signal connections that are created in that context.
You need to dispose the Disposables.
3 If you use the JavaScript (html) target, you can use the chrome debug inspector / devtools. You can collect memory profiles, observe the cpu usage etc. Really useful! https://developer.chrome.com/devtools/docs/profiles
From my few years of experience programming in graphics, one thing that I have learned is that you should never pass in a reference to a graphics context to an object and operate on it for the duration of the program (JOGL explicitly states this). A context can be invalidated when something such as the graphics device (GPU) is reset, turned off, or some other weird thing happens.
I have recently delved back into programming in XNA 4.0, and one of my projects involves objects needing to know about the size of the window/viewport, when the window is resized, and when dynamic buffers have lost their content (requiring the buffers to be rebuilt on a possibly invalidated GraphicsDevice). Instead of passing in the GraphicsDevice and GameWindow to numerous methods in the update phase or for Disposal, I have opted to pass them into constructors. For example:
public Camera(GameWindow w, GraphicsDeviceManager m) {
// ... Yada-yada matrices
gdm = m;
window = w;
window.ClientSizeChanged += OnWindowResize;
}
public void Dispose() {
window.ClientSizeChanged -= OnWindowResize;
window = null;
gdm = null;
}
// Control Logic ...
public void OnWindowResize(object Sender, EventArgs args) {
Vector2 s = new Vector2(gdm.GraphicsDevice.Viewport.TitleSafeArea.Width, gdm.GraphicsDevice.Viewport.TitleSafeArea.Height);
// Recalculate Projection ...
}
Is it safe to do something like this, or is something happening in the background that I need to be aware of?
I solved this problem in my current game project by running the game as a singleton, which makes it available in a static context within the namespace. Game.Instance.graphicsDevice will always point to the current graphics device object, even if the context has changed. XNA raises various events when the context is invalidated/changed/reset/etc., and you can reload/re-render things and resize buffers as needed by hooking in to these events.
Alternatively, you could pass GraphicsDevice with the ref keyword, which might be a quick, drop-in fix by simply being the same reference as the original caller, assuming that caller that instantiated your objects either has the original reference object or had the GraphicsDevice passed to it with ref as well.
Hi noticed some code in our application when I first started Java programming. I had noticed it created a dialog from a separate thread, but never batted an eye lid as it 'seemed to work'. I then wrapped this method up through my code to display dialogs.
This is as follows:
public class DialogModalVisibleThread
extends Thread {
private JDialog jDialog;
public DialogModalVisibleThread(JDialog dialog, String dialogName) {
this.setName("Set " + dialogName + " Visable");
jDialog = dialog;
}
#Override
public void run() {
jDialog.setVisible(true);
jDialog.requestFocus();
}
}
Usage:
WarnUserDifferenceDialog dialog = new WarnUserDifferenceDialog( _tableDifferenceCache.size() );
DialogModalVisibleThread dmvt = new DialogModalVisibleThread( dialog, "Warn User About Report Diffs");
dmvt.start();
Now, as far as I am now aware, you should never create or modify swing components from a separate thread. All updates must be carried out on the Event Dispatch Thread. Surely this applies to the above code?
EDT on WikiPedia
However, the above code has worked.
But lately, there have been countless repaint issues. For example, click on a JButton which then calls DialogModalVisibleThread to display a dialog. It caused buttons alongside the clicked button not to redraw properly.
The repaint problem is more frequent on my machine and not the other developers machine. The other developer has a laptop with his desktop extended onto a 21" monitor - the monitor being his main display. He is running Windows 7 with Java version 1.6.0_27.
I am running on a laptop with Windows 7 and Java version 1.6.0_24. I have 2 additional monitors with my desktop extended onto both.
In the meantime I am going to upgrade to Java 1.6 update 27.
I wondered if the above code could cause repaint problems or are there any other people out there with related paint issues?
Are there any easy ways to diagnose these problems?
Thanks
So, you're breaking a rule, having problems, and wondering if these problems could be cause by the fact that you broke the rule. The answer is Yes. Respect the rules!
To detect the violations, you might be interested by the following page: http://weblogs.java.net/blog/2006/02/16/debugging-swing-final-summary
The easiest way to check if your problems are being caused by breaking the rules is to fix them (You should fix them anyway :-)
Just use SwingWorker.invokeLater() from the thread you want to update to UI from to easily adhere to Swing's contract. Something like this should do the trick:
#Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
jDialog.setVisible(true);
jDialog.requestFocus();
}
});
}
EDIT: You should make the 'jDialog' variable final for this to work.
I'm having issues with my Application Object. I am currently using a Service to simulate incoming data from an electronic game board. This data is represented as a 2D boolean array. Every five seconds the Service uses a method of the Application Object to update the array (setDetectionMap()). This array is being read by a Thread in my main Activity using another method (getDetectionMap()). After some debugging I am almost positive that the main Activity is not seeing the changes. Here is the code for my Application Object:
public class ChessApplication extends Application{
private static ChessApplication singleton;
private boolean[][] detectionMap;
public static ChessApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton=this;
detectionMap=new boolean[8][8];
}
public boolean[][] getDetectionMap(){
return detectionMap;
}
public void setDetectionMap(boolean[][] newMap){
detectionMap=newMap;
Log.d("Chess Application","Board Changed");
}
}
I've checked my Manifest, I've rewritten my object declaration a dozen times, I've added LogCat tags to make sure that the code is executing when I think it should be, and I've even implemented the supposedly redundant Singleton code. Any ideas what could be causing this? Incidentally can anyone tell me how to view variable states as the activity is running? Thanks in advance.
Is your Activity calling getDetectionMap() to get the new map after the update occurs?
Because otherwise, it's holding onto a reference to the old boolean[][] array, wheras setDetectionMap(...) isn't actually updating the current data structure, it's just updating the "detectionMap" variable to point to a different one. As such, your main activity won't be aware of the swapout until the next time it calls getDetectionMap.
Easy fix: in setDetectionMap, manually copy values from newMap into detectionMap. Or, update the Activity's reference so it's looking at the right map.
One other observation entirely unrelated to the original question: It's quite unusual to override Application during Android development, and is usually considered a "code smell" unless you have a really good reason for doing so. In this case I imagine it's so that you can communicate between your service and Activity, but you create a middle-man where one isn't entirely necessary. Here's a useful SO thread on how to communicate directly between the two :)
How can you make a background web request and then update the UI, but have all the code that does the web requesting/parsing in a separate class so you can use it in multiple places? I thought I could use the classes methods as event handlers for a BackgroundWorker class, like
APIHelper mHelper = new APIHelper("http://example.com?foo=bar");
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork +=new DoWorkEventHandler(mHelper.GetResponse);
bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(mHelper.HandleResponse);
bw.RunWorkerAsync();
where APIHelper has the method
public void GetResponse(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker) sender;
WebRequest request = HttpWebRequest.Create(this.URL);
IAsyncResult result = (IAsyncResult)
request.BeginGetResponse(ResponseCallback, request);
}
but then I don't know how to access the worker thread from ResponseCallback and, anyway, HandleResponse gets called first (obviously). (I tried putting in result.AsyncWaitHandle.WaitOne(); but I get a NotSupportedException error.) Yet I can't work out how to make the web request call synchronously. I'm clearly trying to go about this the wrong way, but I have no idea what the right way is.
ETA:
My aim is to be able to go:
user clicks (a) button(s) (on various pages)
a "working" message is displayed on the UI thread (and then input is blocked)
in a background thread my APIHelper class makes the relevant API call, gets the response, and passes it back to the UI thread; I only seem to be able to do this by starting another thread and waiting for that to return, because there's no synchronous web requests
the UI thread updates with the returned message (and input continues as before)
I can do the first two bits, and if I have the response, I can do the last bits, but I can't work out how to do the middle bit. Hopefully that made it clearer!
It took me several tried before I found there is a Dispatcher.
During the BackgroundWorker's dowork and complete methods you can call:
this.Dispatcher.BeginInvoke(() =>
{
// UPDATE UI BITS
});
I think the Dispatcher is only available in the view. So I'm not sure if the methods can exist outside of the xaml.cs
Put whatever you want to update in your UI; when updating an ObservableCollection you must do the update of you items in the Dispatcher.BeginInvoke too
This link might be a good read too:
http://www.windowsphonegeek.com/articles/All-about-Splash-Screens-in-WP7-ndash-Creating-animated-Splash-Screen
Update to assist notes
This is just a rough idea mind you...
bw.DoWork +=new DoWorkEventHandler(DoWork);
bw.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(Complete)
// At least I think the EA is DoWork....
public void DoWork(object sender, DoWorkEventArgs e)
{
mHelper.GetResponse();
this.Dispatcher.BeginInvoke(() =>
{
UIObject.Visibility Collapse.
});
// Wait and do work with response.
});
}
public void Complete(object sender, RunWorkerCompleteEventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
UIObject.Visible ....
});
}
I'd put all this logic in a viewmodel that the viewmodel of each page inherits from.
Have the pages bind to properties on the viewmodel (such as ShowLoading, etc.) which the model updates appropriately. i.e. before making the webrequest and in the callback.
As you won't be running the viewmodel code in the UI thread you also wouldn't need to run in a separate BackgroundWorker and you'll be able to access the properties of the viewmodel without issue.
It might be useful if you use a helper class that I have developed for WebDownload purposes during WP7 development.
I'm using it in 2-3 WP7 apps and no problem so far. Give it a go to see if it helps. You can get the class from the my blog linked bellow:
http://www.manorey.net/mohblog/?p=17#content
[NOTE] When working with this class you don't need to run anything in a background worker or new thread; it handles it all asynchronously.