How do I draw things differently depending on the case in XNA? - c#

I have a StatBarView class that holds a Stat, an int named percentage and two Colors. In the Update() method I smoothly change around the percentage value of the bar, how full it has to be. Next up I have four Draw() methods, one for drawing the bar small, one for medium, one for large, and one for drawing it as text instead of graphically.
It works, but.. I feel like this will become a mess if I want to implement more drawing cases.
I could turn the 'text view' into it's own StatTextView, but that only moves the problem elsewhere. I also want to avoid having to pass along all kinds of parameters to the draw method, it would make me run all over the place if I want to change the sizes of a few things. I'd also like to avoid some massive method using switch statements, that feels even worse.
I considered passing along an IStatBarContext that has a Draw(int percentage), which would work, but feels very complicated.
Would I have to call Stat.Draw(spriteBatch, position, new StatBarLarge()) on every iteration of Draw()? That's a load of useless new objects per second. Besides, new StatBarString() would make no use of that percentage stat. I think I went wrong with my design somewhere.
That said, I don't know how to actually -do- make this code cleaner. Would someone help me out?

It sounds like your last example/choice is spot on. It even has a name, the Strategy pattern.
In the class based version of this pattern, you would normally just pass in a new object every time (as in your example) but because this is in the Draw method, I would just have a sample of each strategy stored in your class and pass the existing reference.
Another way to implement this pattern is by using delegates. To do so you would have the Draw method take a delegate with the information you need. Something like:
public void Draw(SpriteBatch spriteBatch, Vector3 position, Action<int> drawStrategy)
{
...
drawStrategy(percentage);
}
You would then pass the function for large, small, text, etc. to this function. Action<int> was just an example of course, you can have it return values or take additional parameters as needed.
If the text-version doesn't use percentage, that is a code-smell, but you may not need to worry about it to much. Strategy is definitely the way to go here.

Related

c# Should I store a copy of a field for convenience?

I have developed a habit of sometimes doing this particular thing and I'm wondering why am I doing it, is there any advantage?
Heres an example from a Unity3d game..
In my class I want to do various calculations and so forth with a float ThingYposition which is a field stored somewhere in Thing.transform.position.y. Rather than be writing Thing.transform.position.y so many times I just make a copy of the float I want at the beginning of the program.
public GameObject Thing;
private float ThingYposition;
public Start()
{
ThingYposition = Thing.transform.position.y
}
public Update()
{
//Do stuff every frame with ThingYposition
}
So this way means my lines of code will be a little less cluttered but the program will use a little bit more memory as I'm storing that float twice now. But will it be any faster? Does accessing a deeply embedded field like Thing.transform.position.y actually use any more processing power than accessing my float field?
Do you think this is harmless habit or should I stop?
Also please note in this example I dont care if the original changes at all and I dont want to change it.
You already stated you don't care if the original changes, so I'll skip that part. The only advantage I can see is in a multi-threaded environment. You don't have to worry about another thread mucking with Thing, since you have a private copy of ThingYposition.
In terms of efficiency, you're well into micro optimizing here. If you're having a problem, profile it and experiment with alternatives. But I can't imagine this is something you really need to worry about.
Since you don't care whether or not the original position changes and will not change it yourself, then this is probably the best approach for the use-case you described.
The answer to the other part of your question, is it faster to access a local vs a "deeply embedded field" depends on how Thing.transform.position.y is implemented. If it just a member field, then the access times would be essentially the same for a local copy or the "deeply embedded field". If Thing.transform.position.y is calculated on every access then the local copy would be faster.

Property of one class is another class, and vice-versa

I'm programming a board game in C# where the two most important classes are Piece and Square. Typically every instance of Piece has a Square (as a property) and every instance of Square may have a Piece (also as a property) or may be empty.
I placed code in the set methods of Square.Piece and Piece.Square to ensure that this relationship was maintained (e.g. when a piece is moved from one square to another) and to avoid the obvious danger of the linked properties calling each other's set methods in an endless loop.
But when a piece is removed from the board and its square set to 'null' I seem to have too many if statements to avoid null exceptions and what seemed a very simple pattern conceptually becomes far too complex and error-prone in practice.
I'm wondering whether my whole approach is wrong. Should a piece have a square as a property when Square also has Piece as a property? Have I in fact started coding an anti-pattern? A Piece's Square may be null on creation, and a Square's Piece is frequently null (representing empty). Should I use another way to represent empty Squares and Pieces which are not on the board?
I'm assuming there are preferred, robust solutions to the more general case of when one class is linked to another in a two-way relationship such as this.
Many thanks for any ideas.
Use an higher level abstraction, with methods like
move(piece, originalSquare, destinationSqueare)
place(piece, square)
remove(piece)
promote(originalPiece, finalPiece)
...
these methods will use your basic methods from Piece and Square, and will be the ones used by your main logic
It seems to me that you're overthinking the process of removing a Piece from the Board.
The game is going to be centered on the Board class. Once you remove a Piece from the Board, that piece is gone; you're not going to do anything with it anymore. You won't be calling any of its methods or anything. That object is now dead -- unreachable. So there's not actually any reason to change the Piece's state to null out its Board reference.
This is indeed a very common pattern, and the usual practice is to just let it go. Once nobody references the Piece anymore, you're done; it no longer matters that the Piece still happens to reference the Board. Let it keep its reference; it won't cause any harm (since nobody will be doing anything with that Piece anymore), and it'll be garbage collected soon anyway.

Storing a reference to an outside variable within an object

I'm programming for a game in XNA and attempting to create a universal math object with a stored output location supplied during construction.
My plan was to use ref in the constructor, but I'm not sure how to hold/store that reference in the object beyond the initial call...
public MathObject(ref float OutParam)
{
Out = OutParam; // This obviously won't do what I want... But it's where I'd like to do it.
}
In the update I'd like to state the input and have the product modify the stored output location:
foreach (MathObject MatOb in MathList)
{
MatOb.Update(time);
}
The idea was to create a modular math tool to use throughout the code and direct it on creation to a pre-existing object parameter elsewhere ("output") that it will modify in the update (without re-referencing). The hope was that this would allow a single loop to direct every instance of the tool to modify it's given output.
As I understand it, in c++ this is possible through storing the address of the parameter to be modified within the math object, then using this in the update to point to and modify the memory at that location.
Is something similar possible in c# without the use of unsafe code?
Should unsafe code always be avoided?
Edit:
-- Intended Use --
I'd like to be able to create objects with an adjustable "set and forget" output location.
For instance, I've built a simple bezier curve editor that works within the game interface. I can set the output locations in the code so that a given curve always adjusts specific parameters(character position for example), but It would be nice to modify what the output is connected to within the interface also.
The specific applications would be mostly for in-game editing. I understand editors are most practical when self-contained but this would be for limited, game console friendly editing functionality (less robust, but similar in principle to the editing capablities of Little Big Planet).
My background is in 3D design and animation so I'm used to working with many node-based editing systems - Creating various utility nodes and adjusting inputs and outputs to drive parameters for shading, rigging models, etc. I'm certainly not attempting to re-create this in game, but I'm curious about carrying over and applying certain principles to limited in-game editing functionality. Just troubleshooting best to go about it.
Thanks for the replies!
The way to do this in C# is to use a pair of get/set delegates. You could use this handy-dandy helper struct to store them:
public struct Ref<T>
{
Func<T> get;
Action<T> set;
public Ref(Func<T> get, Action<T> set)
{
this.get = get;
this.set = set;
}
public T Value { get { return get(); } set { set(value); } }
}
Given some class like this:
class Foo { public float bar; }
Use it like this:
Foo myFoo = new Foo();
Ref<float> barRef = new Ref<float>(() => myFoo.bar, (v) => myFoo.bar = v);
// Ta-Da:
barRef.Value = 12.5f;
Console.WriteLine(barRef.Value);
(Please note that I haven't actually tested the code here. The concept works and I've successfully used it before, but I might have messed up my syntax by typing this up off the top of my head.)
Because this question is tagged with XNA, I should briefly talk about performance:
You'll probably find this performs about an order of magnitude or so slower than the equivalent memory access - so it's not suitable for tight loops.
Creating these things allocates memory. This is very bad for performance for a number of reasons. So avoid creating these inside your draw/update loop. During loading is fine, though.
And, finally, this is uglier than simply accessing the property directly - so be sure that you're doing what you can to avoid using this where possible.
I wouldn't know how to do this in C# without unsafe code, but.. if you absolutely must tackle your problem with this solution and without using unsafe code then maybe memory mapped files are your friend. even so, these haven't been around for .NET development until .NET 4.0 and I'm not sure how this option compares to unsafe code performance-wise.
I think what you need is the observer design pattern. Item interested in the update of math object will register the avent ( ie MathObjectChange ) and react properly.

Which kind of method signature do you prefer and why?

Ok, this is probably highly subjective but here it comes:
Let's assume I'm writing a method that will take a printscreen of some region of the screen. Which method signature would you prefer and why?
Bitmap DoPrintScreen(int x, int y, int width, int height);
Bitmap DoPrintScreen(Rectangle rect);
Bitmap DoPrintScreen(Point point, Size size);
Other
Why?
I keep seeing myself repeatedly implementing both 1) and 2) (redirecting one of them to the other) but I end up usually just using one of them, so there really is no point in having both. I can't decide which would be better. Maybe I should use the signature that looks the most with the method I'll be calling to make the printscreen?
It depends. If this is a library for general use, by all means add all three. The .NET framework, especially GDI+, is full of examples of this. If the conversion is trivial, it's not much effort, and your users will be thankful.
If it's just an internal class, I'd go for the option that is easiest to use from the call site. For example, if the caller already has a Rectangle available, the Rectangle overload is better. If there are multiple call sites with different preferences, it's probably better to add multiple overloads as well.
Rectangle best describes the behavior of the function (at least I hope it does!) The X & Y associate with width & height so as to define a rectangle; they are not arbitrary unrelated variables.
I would go with 2)
Bitmap DoPrintScreen(Rectangle rect);
As mark said the parameters can be swapped in the following:
Bitmap DoPrintScreen(int x, int y, int width, int height);
I wouldn't choose this as it is not as explicit as 2) to someone else reading it. Whereas there is no ambiguity to someone read 2)
Bitmap DoPrintScreen(Point point, Size size);
Of course that's just my opinion of course!!!
If you only end up calling one of these overloads, then there's really no point in having the other two sitting around. There's nothing I hate more than having to sift through 27 overloads of some method, hoping that a) I find the right one for my purposes, and b) the person who wrote this mess actually ran and tested the overload I'm using even once.
In the specific case of a screen-capture method, the overload with the Rectangle parameter would probably be the most handy, since forms always have a rectangle associated with them. Also, if you need to grab the same screen area repeatedly, it's easier to save one variable (a Rectangle) than four (x, y, width and height).
The best one is
Bitmap DoPrintScreen(Rectangle screenArea);
If you think about the method parameters as being part of a "concept", in this case the concept of a screen area, then the other options don't abstract that concept nicely enough.
Also, use a good name for the parameter, because it might make calling code even more clear by the use of named parameters in C# 4.0.
I would personally include the three of them, letting the user choose which one she/he prefers to use, all to offer the most freedom of use possible to the user. No one likes to be handcuffed. Well, not in programming! ;)
Rectangle is probably the most clear because the argument does not depend on the position. It would be easy for a user to accidentally swap x and y or width and height.
Point/Size is also better than x-y-width-height, and sometimes the extra explicitness can be a little more clear to read.
But ultimately, there's no good reason to not use all three overloads.
I think you should select the version that maps best to the other methods that would be used in conjunction with your code. I am referring to .Net methods and methods from other standard or common 3-rd party libraries. In that way the code looks uniform and the same objects can be passed to other methods directly.
I would provide all 3 if it would be convenient for the consumer. After all, your actual implementation will (or should) only exist in one place. All of the other overloaded methods will simply extract the appropriate parameters and pass them to the local method with the actual code.
...so it's a convenience for your users with little to no effort on your part. Win/Win.
Both - 1 and 2.
And also one without params for full-screen =)
Some times you have separated x,y,width, height,
some times you already have rectangle.
Varian 3 - IMHO is very rare =)
But user always can convert values to rectangle, or break apart rectangle to values)
I think this is philosophical question.
So make them all or pick random one )))
All 3. Like you said, you're going to redirect them to 2 any who so, why not keep all three? I do think you should change the Rectangle parameter name to something more meaningful - like printArea.
cheers.

Approach to side-effect-free setters

I would like to get your opinion on as how far to go with side-effect-free setters.
Consider the following example:
Activity activity;
activity.Start = "2010-01-01";
activity.Duration = "10 days"; // sets Finish property to "2010-01-10"
Note that values for date and duration are shown only for indicative purposes.
So using setter for any of the properties Start, Finish and Duration will consequently change other properties and thus cannot be considered side-effect-free.
Same applies for instances of the Rectangle class, where setter for X is changing the values of Top and Bottom and so on.
The question is where would you draw a line between using setters, which have side-effects of changing values of logically related properties, and using methods, which couldn't be much more descriptive anyway. For example, defining a method called SetDurationTo(Duration duration) also doesn't reflect that either Start or Finish will be changed.
I think you're misunderstanding the term "side-effect" as it applies to program design. Setting a property is a side effect, no matter how much or how little internal state it changes, as long as it changes some sort of state. A "side-effect-free setter" would not be very useful.
Side-effects are something you want to avoid on property getters. Reading the value of a property is something that the caller does not expect to change any state (i.e. cause side-effects), so if it does, it's usually wrong or at least questionable (there are exceptions, such as lazy loading). But getters and setters alike are just wrappers for methods anyway. The Duration property, as far as the CLR is concerned, is just syntactic sugar for a set_Duration method.
This is exactly what abstractions such as classes are meant for - providing coarse-grained operations while keeping a consistent internal state. If you deliberately try to avoid having multiple side-effects in a single property assignment then your classes end up being not much more than dumb data containers.
So, answering the question directly: Where do I draw the line? Nowhere, as long as the method/property actually does what its name implies. If setting the Duration also changed the ActivityName, that might be a problem. If it changes the Finish property, that ought to be obvious; it should be impossible to change the Duration and have both the Start and Finish stay the same. The basic premise of OOP is that objects are intelligent enough to manage these operations by themselves.
If this bothers you at a conceptual level then don't have mutator properties at all - use an immutable data structure with read-only properties where all of the necessary arguments are supplied in the constructor. Then have two overloads, one that takes a Start/Duration and another that takes a Start/Finish. Or make only one of the properties writable - let's say Finish to keep it consistent with Start - and then make Duration read-only. Use the appropriate combination of mutable and immutable properties to ensure that there is only one way to change a certain state.
Otherwise, don't worry so much about this. Properties (and methods) shouldn't have unintended or undocumented side effects, but that's about the only guideline I would use.
Personally, I think it makes sense to have a side-effect to maintain a consistent state. Like you said, it makes sense to change logically-related values. In a sense, the side-effect is expected. But the important thing is to make that point clear. That is, it should be evident that the task the method is performing has some sort of side-effect. So instead of SetDurationTo you could call your function ChangeDurationTo, which implies something else is going on. You could also do this another way by having a function/method that adjusts the duration AdjustDurationTo and pass in a delta value. It would help if you document the function as having a side-effect.
I think another way to look at it is to see if a side-effect is expected. In your example of a Rectangle, I would expect it to change the values of top or bottom to maintain an internally-consistent state. I don't know if this is subjective; it just seems to make sense to me. As always, I think documentation wins out. If there is a side-effect, document it really well. Preferably by the name of the method and through supporting documentation.
One option is to make your class immutable and have methods create and return new instances of the class which have all appropriate values changed. Then there are no side effects or setters. Think of something like DateTime where you can call things like AddDays and AddHours which will return a new DateTime instance with the change applied.
I have always worked with the general rule of not allowing public setters on properties that are not side-effect free since callers of your public setters can't be certain of what might happen, but of course, people that modify the assembly itself should have a pretty good idea as they can see the code.
Of course, there are always times where you have to break the rule for the sake of either readability, to make your object model logical, or just to make things work right. Like you said, really a matter of preference in general.
I think it's mostly a matter of common-sense.
In this particular example, my problem is not so much that you've got properties that adjust "related" properties, it's that you've got properties taking string values that you're then internaly parsing into DateTime (or whatever) values.
I would much rather see something like this:
Activity activity;
activity.Start = DateTime.Parse("2010-01-01");
activity.Duration = Duration.Parse("10 days");
That is, you explicity note that you're doing parsing of strings. Allow the programmer to specify strong-typed objects when that is appropriate as well.

Categories

Resources