bookmark_borderRTS Game: Incubator week started!

Today I have begun an ‘Incubator week’. This means I have allocated a whole week to work on my game. One week without any distractions, at a separate location. Focussed to work on the game.

And even more awesome, I have some help from Arjen van der Ende for a few days.

In this week we’re going to work on:

  • Merging the Harvester logic
  • Minimap
  • Power Resource
  • AI

A lot of the things to get the Minimal Playable Game finished!

 

I am very grateful that my family supports me to chase my dream and give me the opportunity to work on my game like this! Thanks! Also, thanks Arjen for helping me out!

bookmark_borderMy answer for – What’s ‘wrong’ with this code ? #01

I asked what was ‘wrong’ in the following code. I had put ‘wrong’ in quotes, because it is an ambigious term. Here is the code:

	if (null == sessionProxy.getShoppingCart()) {
		throw new IllegalStateException("ShoppingCart may not be null");
	}

One thing that we find here, is the use of a session proxy object. This is convenient, because it can do things for us at a centralized place.

So what is wrong?
In my opinion there are several things wrong with this code:
– violation of the Single Responsibility Principle
– dealing with null

How to fix this?
Fixing this may not be as obvious as how to detect flaws. This is existing code we are talking about, and you can’t just make changes without making sure you don’t introduce regression.

Solving the violation of the Single Responsibility Principle
We are reading the state of the sessionProxy to execute business logic. We are actually only concerned if the shoppingCart is set on the session. This could be via a null reference, but it could also be done in a different way. What we want is this:

if (!sessionProxy.isShoppingCartSet()) {
	throw new IllegalStateException("ShoppingCart may not be null");
}

The method isShoppingCartSet() returns true or false. The implementation will look like this:

public boolean isShoppingCartSet() {
	return getShoppingCart() != null;
}

The subtle difference is that we now have delegated the question “is the shopping cart set on session” to the class that is responsible for knowing, the sessionProxy.

Solving: Dealing with null
Another advantage by using the isShoppingCartSet method is that we minimize the amount we have to deal with null. We don’t need to check for null explicitly everywhere, we have centralized in one class.

Dealing with null can cause problems, the sooner you don’t have to worry about things being null, the better.

Instead of using a isShoppingCartSet method we could throw a checked exception in the getShoppingCart method. I like checked exceptions, because it forces you to deal with these exceptional situations. It also solves the null problem, as you know it always returns a value or throws an exception when it is (but should not be) null.

There is on caveat here: what if there is existing code relying on the value being null?

The real question is: What does the null value mean? Often it is abused as a status. Some people even use null as a “third boolean” (ie Boolean is ‘true’, ‘false’, or null for ‘unknown’).

As I see it you have an ideal path you want to execute, and then there are things that can go wrong and must be dealt with. In this case, we would expect a shoppingCart so we can do stuff with it. But, if it is not there, we catch the exception and execute other business logic we would otherwise have done with a ‘is null’ check. Ie:

ShoppingCart cart = sessionProxy.getShoppingCart();
if (cart == null) {
	// do some business logic where cart is null
} else {
	// other logic
	cart.getSomeProperty();
}

turns into:

try {
	ShoppingCart cart = sessionProxy.getShoppingCart();
	cart.getSomeProperty();
} catch (NoShoppingCartSetException e) {
	// do some business logic where cart is null
}

The second example clearly defines a ‘happy path’ (within the try). If you use checked exceptions consistently, you will notice your code will become easier to understand. Try it!

What if I don’t want to add an exception to the getShoppingCart method in my current proxy class?
In these cases I would suggest to create a child class of the sessionProxy, which does throw an exception. In the cases where you are absolutely sure that the shoppingCart may never be null, you can use this stricter version of the sessionProxy and deal with exceptions.

Another way of dealing with null – upon construction?
It is also possible to check for null in the constructor(s) of the sessionProxy class. In the case of a http session proxy, it would mean you have to make it immutable to make this work. The reason is that the http session is mutable, even once you have created a sessionProxy. Checking for null values at construction will not guarentee the values are not set on null later on. To fix this, you should create a ‘snapshot’ of the http session at time of construction of the sessionProxy. You read out properties, check for null and set values in private final fields. When you access the fields, you retrieve the fields themselves, and not access them via the http session.

Ie, this:

private final HttpSession httpSession;

public SessionProxy(HttpSession) {
	this.httpSession = httpSession;
}

public String getProperty() {
	String value = (String)httpSession.getAttribute("PROPERTY_KEY");
	if (value == null) throw new PropertyNotOnSessionException("property was not set on session.");
	return value;
}

turns into:


private final String property;

public SessionProxy(HttpSession) {
	this.property = (String)httpSession.getAttribute("PROPERTY_KEY");
	if (this.property == null) throw new PropertyNotOnSessionException("property was not set on session.");	
}


public String getProperty() {
	return property;
}

Concluding
A few lines of code, and yet so much to improve. We have found that:

– We can push the null check into a method of the responsible class. Making the class itself able to answer this business logic.
– We should throw an exception when we want to return null. Dealing with null is hard. When you don’t have to deal with null, your code will get much easier.
– When throwing an exception has too much impact, create a child class which can throw exceptions to reduce impact on current code.
– Checking for null upon construction, for a session proxy, is not possible. Only if you create a DTO out of it (but not a proxy).

bookmark_borderGotcha’s showing error messages with Spring forms (form:errors)

(I have recently encountered this with Spring 3.1)

Want to validate your forms using Spring? Are you using the form tag and bind it with an object? Got the validator working? But still you just can’t seem to get these error messages showing up? Here is a gotcha that might help you out!

Consider this controller:

@Controller
public class FormController {

    @RequestMapping("/form")
    public ModelAndView handleGet(@Valid TellAFriendForm backingForm, BindingResult bindingResult) {
        ModelAndView modelAndView = new ModelAndView("backingForm");
        modelAndView.addObject("backingForm", backingForm);
        modelAndView.addObject("result", bindingResult);
        return modelAndView;
    }

}

With this jsp:

<form:form method="POST" commandName="myForm" action="?">
    <div>
        <label for="name">Name*</label>
        <form:input path="name" id="name"/>
        <form:errors path="name"/>
    </div>
    <div>
        <input type="submit" value="Send"/>
    </div>
</form:form>

When the user submits this form, the form should be validated. Whenever a field does not validate, it should inform the user about this.

This is done by using:

        <form:errors path="name"/>

Where ‘path’ refers to a field in the bound form object, in this case myForm. In this example, I have named my form “myForm”. The theory is that when the form is being validated, the BindingResult (put as “result” on the model), contains all fields that have validation errors. Using the form:errors tag you can make use of that and show error messages.

Although this works often, sometimes it does not and you spend some time figuring out why. A common gotcha is that you forget to put the bindingResult on your model (as “result”).

But there is another less intuitive gotcha.

When your given commandName in the form:form tag does not represent the camelcased, name of the type of the form, the form:errors tag will *not* work. So don’t make up your own name. Make sure it is the same as the type, and make sure it is camelcased correctly. I figured this out the hard way.

Solution: The form object is of type: BackingForm, the expected name would then be backingForm. Change the commandName into backingForm and you will see the form error messages showing up.

bookmark_borderA (C++) makefile using a maven like directory structure

When you’re used to Java, you build your software using the comforting build-tools. Popular examples are Ant and Maven. Personally I love Maven.

When you’re writing an application in C++ it seems like a big step backwards build-tools wise. If you’re an Ant God you might feel a bit more comfortable with using Make. However, writing makefiles (the ‘equivalent’ of the Ant’s build.xml) are a more tough.

Since I am used to Maven, there are some tasks I want to perform, like:

– clean
– compile
– compile tests
– package

To start with. I have set up a little makefile that does this for me and for those who just want to get started, share the makefile with you. But what will you get? It won’t be exactly like Maven

It took a little while, and I bet it is far from perfect for real C++ developers who eat makefiles for breakfast. But I am happy with it for now.

The directory structure that needs to be in your project is like this (cpp vs mavenized):

CPP 					Mavenized
------------------------------------------
srcmain 				srcmainjava
srcmainresources 		srcmainresources
srcinclude			none
srctest 				srctestjava
binmain 				target
bintest 				targettest-classes
lib 					srcmainresources

When you run ‘make’ you will be doing all tasks. Meaning you will clean, compile everything (your ‘normal’ code and test code) and then copy any libraries, resources and binaries.

Caveats:
– I am compiling without using the -c flag, this simplifies a lot of stuff for me (it works). But, the larger your project the longer it will take to compile, since it will compile everything all the time. So even though you change one file, everything will be recompiled.
– You need to specify sub-dirs when you use them, when there are no files in those dirs the compilation fails (atleast using G++)

The makefile:

CC=g++
CFLAGS=-Wall

# MAIN properties
SRC=src/main
INCLUDE=src/include
BIN=bin/main
RESOURCES=src/main/resources
LIB=lib

# TEST properties
SRC_TEST=src/test
BIN_TEST=bin/test
RESOURCES_TEST=src/test/resources

all: clean compile compile-test copy-resources copy-libraries

bin: clean compile copy-resources copy-libraries

copy-libraries:
	cp $(LIB)/*.* $(BIN)

copy-resources:
	cp -R $(RESOURCES)/ $(BIN)

compile: clean-main prepare-main
	$(CC) $(SRC)/*.cpp $(SRC)/domain/*.cpp -I$(INCLUDE) -I$(INCLUDE)/domain -o $(BIN)/d2tm -lmingw32 -lSDLmain -lSDL $(CFLAGS)

compile-test: clean-test prepare-test
	$(CC) $(SRC_TEST)/*.cpp -I$(INCLUDE) -o $(BIN_TEST)/tests $(CFLAGS)

clean:	clean-main	clean-test

clean-main:
	rm -rf binmain

prepare-main:
	mkdir binmain

clean-test:
	rm -rf bintest

prepare-test:
	mkdir bintest

Want to see how it is used in a project? Look here.

bookmark_borderHow stackoverflow helps me to solve problems, without posting questions…

I really love stackoverflow. It brings developers, good ones, together. And because of the community active there, many questions I had where answered.

However, I dare to say half of my questions where answered by not posting any question

The reason why? Its simple. In order to get the answer you seek, you need to specify the problem precisely. Just posting “it does not work” with some vague description is not enough. It really helps to tell how you stepped through the problem, post snippets of code and so forth. If you are able to specify your problem like that, chances are high (at least with me) that the solution comes along with it. A so called “aha” moment. To me it is like Rubber Ducking. By the time you are half-way through writing down the exact problem you probably figured out the problem yourself.

The good news:

  • You probably found 9 out of 10 ‘doh ofcourse its so obvious’ issues. Preventing you to post ‘stupid’ questions…
  • You end up posting really hard questions (making you look so smart).

The better news:

  • There are people out there who are even smarter than you! And make you smarter in return!
  • You do not have to talk to a real rubber duck at your desk, just type your question at stackoverflow. (your co-workers will stop worrying about your mental state, talking to that duck all the time).

Its a win win win!

In other words…

Answer answer = null;
try {
Question question = formulateQuestionPrecisely();
answer = stackOverFlowService.postQuestionAndGetAnswer(question);
} catch (AhaMomentException ame) {
// never mind, found the solution myself!
answer = ame.getAnswer();
}

Thanks stackoverflow!

(don’t forget to credit those who give the best answers.. it’s highly appreciated)

Now I just read that posting your question, while you know the answer already, is a good thing. So the next time… consider that (but make sure your question has not been asked for already :)).