I am getting a little confused about class instances and I tried to search the internet for my specific question but I could not find an answer.
Assume I have a parent class Screen and child classes GameplayScreen and SettingsScreen.
If inside my main game class I do the following:
Screen currentScreen = new Screen();
Then each time the user wants to change screen:
if (gameplay)
currentScreen = new GameplayScreen();
else
currentScreen = new SettingsScreen();
Is this a good approach considering performance? Is there a better way to do this like unloading resources?
The answer could depend on what kind of resources do the Screen child types hold, whether their initialization takes a long time and whether they hold a lot of resources (or a “precious” resource).
But the most likely answer is that your code is just fine, and that you shouldn't worry about creating new object when a screen changes (and let the garbage collector take care of the old one).
Related
Anyway, my code looks like this:
SystemOutput systemOutput = null;
SystemCL system = null;
WindowsForm wf = null;
wf = new WindowsForm(system);
systemOutput = new SystemOutput(wf);
system = new SystemCL(systemOutput, wf);
The rest of the code doesn't really matter for the matter of solving my problem (I think?)
So as you can see the objects reference each other, which means that if the other objects hasn't been initialized yet, it will give me an error. So I tried first making them null, but now the first object get a nullreferencepointer, because the object is null.
How do I fix this puzzle? Is there a better way to do this?
Note What is a NullReferenceException, and how do I fix it? does not cover this case.
The answer is to not create the puzzle in the first place. Don't create circular references, like where WindowsForm depends on SystemCL, SystemOutputdepends on WindowsForm, and then SystemCL depends on both of them.
Don't think of it as a puzzle in terms of how to make these classes work as they were designed. The puzzle is how to design them differently so that they don't depend on each other that way.
That's as detailed as I can get without knowing what the classes actually do.
Most of the complexity in object oriented programming comes determining how classes will depend on other classes. Or if you're working on someone else's code, it's figuring out which classes depend on which other classes. Getting this right is IMO one of the most important aspects of OOP.
I think you're on the right track by passing objects into the constructors of other objects when one class depends on another. That's a good practice. The next step is to figure out what belongs in each class so that they don't need to depend on each other circularly.
First - it is better to redesign your classes to avoid circular references. See https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references for discussion.
If you must have such references (i.e. building tree with parent/child relationships) than one of the objects have to provide a way to delay setting one of the relationship references.
Most straightforward - expose property and set it later after other objects are constructed:
wf = new WindowsForm(/*nothing*/);
systemOutput = new SystemOutput(wf);
system = new SystemCL(systemOutput, wf);
wf.SetSystem(system); // method to make it less tempting to set later
There are also multiple ways to make it safer (factories, constructing object when adding,..) including even immutable trees.
I am an old delphi programmer, I am used to creating objects and using them entire time for efficient memory usage. But in c# (maybe all the tutorials I've ever seen), you are creating stuffs with new every time (thanks to garbage collector!!, let me do the coding)..
Anyway, I am trying to create a designing software which has lots of drawing.
My question is: do I have to create a graphics object, or use the protected override void OnPaint(PaintEventArgs e) e.Graphics every painting event.. because when I create a graphic object and then resize the control that I draw on, the graphic object that I created, has that clipping problem and only draws old rectangle region..
thanks
Caching objects makes sense when the object is expensive to create, cheap to store and relatively simple to keep updated. A Graphics object is unique in that none of these conditions are true:
It is very cheap to create, takes well less than a microsecond.
It is very expensive to store, the underlying device context is stored in the desktop heap of a session. The number of objects that can be stored is small, no more than 65535. All programs that run in the session share that heap.
It is very hard to keep updated, things happen behind your back that invalidates the device context. Like the user or your program changing the window size, invalidating the Graphics.ClipBounds property. You are wasting the opportunity to use the correct Graphics object, the one passed to you in a Paint event handler. Particularly a bug factory when you use double-buffering.
Caching a Graphics object is a bug.
If you want to draw on the surface always use the Graphics object from the Paint event!
If you want to draw into a Bitmap you create a Graphics object and use it as long as you want.
For the Paint event to work you need to collect all drawing in a List of graphic actions; so you will want to make a nice class to store all parameters needed.
In your case you may want to consider a mixed approach: Old graphic actions draw into a bitmap, which is the e.g. BackgroundImage or Image of your control
Current/ongoing drawing are done on the surface. This amounts to using the bitmap as a cache, so you don't have to redraw lots of actions on every little change etc
This is closely related to your undo/redo implementation. You could set a limit and draw those before into a Btimap and those after onto the surface..
PS: You also should rethink your GC attitude. It is simple, efficient and a blessing to have around. (And, yes, I have done my share of TP&Delphi, way back when they were affordable..) - Yes, we do the coding, but GC is not about coding but about house keeping. Boring at best.. (And you can always design to avoid it, but not with a Graphics object in a windows system.)
A general rule for every class that implements IDisposable is to Dispose() it, as soon as possible. Make sure you know about the using(...){} statement.
For drawing in WinForms (GDI+) the best practice is indeed to use the Graphics object from PaintEventArgs. And because you didn't create that one, do not Dispose() it. Don't stash it either.
I have to completely disagree with other more experienced members here who say it's no big deal or in fact better to recreate the Graphics object over and over.
The HDC is a pointer to a HDC__ struct, which is a struct with one member, "int unused". It's an absolute waste and stupidity to create another instance/object every time drawing needs to be done. The HDC is NOT large, it's either 4 or 8 bytes, and the struct it points to is in nearly all cases 4 bytes. Furthermore, on the point that one person made, it doesn't help that the graphics object be made with the "static" keyword at the beginning of the WndProc() before the switch, because the only way to give the Graphics object a device context or handle to paint on is by calling its constructor, so "static" does nothing to save you from creating it over and over again.
On top of that Microsoft recommends that you create a HDC pointer and assign it to the same value PAINTSTRUCT already has, every, single WM_PAINT message it sends.
I'm sorry but the WinAPI in my opinion is very bad. Just as an example, I spent all day researching how to make a child WS_EX_LAYERED window, to find out that in order to enable Win 8 features one has to add code in XML with the OS's ID number to the manifest. Just ridiculous.
Ok, I want to do the following to me it seems like a good idea so if there's no way to do what I'm asking, I'm sure there's a reasonable alternative.
Anyways, I have a sparse matrix. It's pretty big and mostly empty. I have a class called MatrixNode that's basically a wrapper around each of the cells in the matrix. Through it you can get and set the value of that cell. It also has Up, Down, Left and Right properties that return a new MatrixNode that points to the corresponding cell.
Now, since the matrix is mostly empty, having a live node for each cell, including the empty ones, is an unacceptable memory overhead. The other solution is to make new instances of MatrixNode every time a node is requested. This will make sure that only the needed nodes are kept in the memory and the rest will be collected. What I don't like about it is that a new object has to be created every time. I'm scared about it being too slow.
So here's what I've come up with. Have a dictionary of weak references to nodes. When a node is requested, if it doesn't exist, the dictionary creates it and stores it as a weak reference. If the node does already exist (probably referenced somewhere), it just returns it.
Then, if the node doesn't have any live references left, instead of it being collected, I want to store it in a pool. Later, when a new node is needed, I want to first check if the pool is empty and only make a new node if there isn't one already available that can just have it's data swapped out.
Can this be done?
A better question would be, does .NET already do this for me? Am I right in worrying about the performance of creating single use objects in large numbers?
Instead of guessing, you should make a performance test to see if there are any issues at all. You may be surprised to know that managed memory allocation can often outperform explicit allocation because your code doesn't have to pay for deallocation when your data goes out of scope.
Performance may become an issue only when you are allocating new objects so frequently that the garbage collector has no chance to collect them.
That said, there are sparse array implementations in C# already, like Math.NET and MetaNumerics. These libraries are already optimized for performance and will probably avoid performance issues you will run into if you start your implementation from stratch
An SO search for c# and sparse-matrix will return many related questions, including answers pointing to commercial libraries like ILNumerics (has a community edition), NMath and Extreme Optimization's libraries
Most sparse matrix implementations use one of a few well-known schemes for their data; I generally recommend CSR or CSC, as those are efficient for common operations.
If that seems too complex, you can start using COO. What this means in your code is that you will not store anything for empty members; however, you have an item for every non-empty one. A simple implementation might be:
public struct SparseMatrixItem
{
int Row;
int Col;
double Value;
}
And your matrix would generally be a simple container:
public interface SparseMatrix
{
public IList<SparseMatrixItem> Items { get; }
}
You should make sure that the Items list stays sorted according to the row and col indices, because then you can use binary search to quickly find out if an item exists for a specific (i,j).
The idea of having a pool of objects that people use and then return to the pool is used for really expensive objects. Objects representing a network connection, a new thread, etc. It sounds like your object is very small and easy to create. Given that, you're almost certainly going to harm performance pooling it; the overhead of managing the pool will be greater than the cost of just creating a new one each time.
Having lots of short lived very small objects is the exact case that the GC is designed to handle quickly. Creating a new object is dirt cheap; it's just moving a pointer up and clearing out the bits for that object. The real overhead for objects comes in when a new garbage collection happens; for that it needs to find all "alive" objects and move them around, leaving all "dead" objects in their place. If your small object doesn't live through a single collection it has added almost no overhead. Keeping the objects around for a long time (like, say, by pooling them so you can reuse them) means copying them through several collections, consuming a fair bit of resources.
Does anyone have any hard and fast rules about what kind of code the form object should handle as opposed to letting the object itself handle it? For example, if there is a race, should the object that is racing say, horses, handle the race as part of being a horse, or is it better to place that inside the form object? I guess what I'm asking is how one decides what goes into an object like a horse as say a method, and what goes into a form object instead of a horse. Are there any rules you use to figure out where code is best abstracted in this case?
This is called "separation of concerns". Let the form handle the display and user interaction. Let the Racer handle racing.
I try to develop my software so that core functionality that is not UI dependent is abstracted into classes that bear responsibility for their tasks.
Try to think:
How could I write this so I could have both a GUI interface and a console interface without duplicating any code.
The UI should only handle visuals & user interaction. Everything else should be organized based on its role.
Not sure there is absolutely a right answer here. But agreed with John Saunders. A "Form's" job is primarily responsible to display data to the user and accept data input. The closer you keep it to that, and that alone. Think about when there's another place for this type of data to be used, if the code is elsewhere, it can be reused.
Have a "Business Object" or a "Facade" handle the logic of the race, and the form to display it.
Try to represent things the way they are in the real world. Anything that describes the properties or actions of a horse, belongs in a horse object. Anything that describes the properties or actions of a race (including, perhaps, a collection of horse objects), belongs in a race object. A form is not a real world object, but just a gadget for displaying information from horses/races/whatever. So don't store anything with the form except as needed to present the real data on the screen.
Since the form is part of the UI I would apply my UI hard and fast rule:
UI = formating, sorting and displaying data plus accepting and verifying input
I am making sims like game and right now I am trying to figure out how I will structure my objects.
Right now I am thinking to create a class called GameObject, the psuedo is below
public class GameObject {
name:String
width:int
height:int
}
This way I could create objects like bushes, trees, and buildings. But then I began to think. what if I wanted to create multiple buildings and trees of the same type ?? I would have to keep making instances of GameObject and giving it a new name and height and width. The properties would have to be the same values in order for me to duplicate one object. That seems a little tedious. Then I figure , maybe that isnt the right way to go. So I was thinking, I would have to extend GameObject like below
public class Tree extends GameObject{
birdHouse:Boolean
}
public class Building extends GameObject{
packingGarage:Boolean
stories:Number
}
public class House extends GameObject{
garage:Boolean
stories:Number
}
Now this way, I can just create multiple instances of house, or tree, without creating properties that specify that it is indeed a house or tree. This seems more logical, but at the same time it seems it allocates more memory because I am creating more classes.
I just need to know what the best practices for dealing with objects like this. If anyone can help me out with this. also if you know any resources for best practices of reducing loading on games or any application at that. I also want to use Interfaces. the second concept seems more reasonable and I was thinking about having the parent implement a interface like below
public class GameObject implement IGameObject {
name:String
width:int
height:int
}
Now this way I can create a class that has a method that loosely accept accepts any type that inherits GameObject.
Selector.loadObject(gObject:IGameObject);
Depending on what type it is (i.e tree, building, house) I can use a case statement to figure out which type it is and evaluate it accordingly.
I also created a Tile Class that will pass through the loadObject method. It also will be a child of the GameOject class. if the case statement finds that it is type Tile, it will highlight whatever Tile depending on what tile my mouse is over.
My second question is if a class inherits a class that implements a interface, is that class child class considered to be a IGameObject as well. or does it have to implement that interface directly.
does all this sound like I am going in the right directions lol, as far as organization is concerned.
Thanks for all of your help, thanks guys!
One thing you could think about is using Composition of objects over inheritance. This sort of goes along with the Flyweight answer. Rather than having all your GameObjects inherit properties from GameObject; instead, have each game object just have a reference or pointer to an object or interface that has the properties it needs. For example, all your game objects probably have some sort of "size" property - rather than inheriting this from a base class, just have each game object reference or point to a "Size" class, so that the size object can potentially be shared among similar objects.
You should look into the Flyweight pattern
From wikipedia:
Flyweight is a software design
pattern. A flyweight is an object that
minimizes memory use by sharing as
much data as possible with other
similar objects; it is a way to use
objects in large numbers when a simple
repeated representation would use an
unacceptable amount of memory.
As for your second question, the answer is yes. All Subclasses of a Class can be said to implement all interfaces that the parent class implements.
This seems more logical, but at the
same time it seems it allocates more
memory because I am creating more
classes.
Creating new classes doesn't use a significant amount of memory. It's creating instances that uses memory - but again, the amount will be negligible compared to the memory used by loading in your graphics etc. Don't worry about memory. Your only concern at this stage should be good code organisation.
You should have separate classes when they have different behaviour. If they have the same behaviour but different properties, then you use the same class and set the properties accordingly.
In this case, you don't appear to have significantly different behaviour, but if separating it into Tree, Building, and House makes life easier for you when managing which items can be included in others etc, do it.