TouK na WGK 2012TouK on WGK 2012

W tym roku wzięliśmy udział w konferencji Wytwarzania Gier Komputerowych. Konferencja odbyła się na Politechnice Gdańskiej w dniach od 31 sierpnia do 2 września. Wróciliśmy stamtąd z nagrodami.

Na konferencji Michał Trzaskowski wygłosił referat „Od (web)aplikacji biznesowych po (web)game dev. Testowanie i spełnianie oczekiwań”. W konkursie Developers Showcase II-gie miejsce zajęła gra Gizarma, autorski projekt Michała Rokickiego z TouK. Gizarma to MMORTS inspirowany głównie strategiami z lat 90, obecnie istnieje grywalna wersja alfa.This year TouK was taking part in the National Conference on Computer Games Development. The conference took place on Gdańsk University of Technology on 31 August – 2 September. We came back from there with prizes.

We have given a lecture titled „From business (web)applications to (web)game dev. Testing and meeting expectations”. In the Developers Showcase contest the Gizarma project won the second place. Gizarma is a MMORTS inspired mostly by the strategies from the ’90, currently there is a playable alfa version, the project is developed by Michał Rokicki.

You May Also Like

Simple trick to DRY your Grails controller

Grails controllers are not very DRY. It's easy to find duplicated code fragments in default generated controller. Take a look at code sample below. It is duplicated four times in show, edit, update and delete actions:

class BookController {
def show() {
def bookInstance = Book.get(params.id)
if (!bookInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
return
}
[bookInstance: bookInstance]
}
}

Why is it duplicated?

There is a reason for that duplication, though. If you move this snippet to a method, it can redirect to "list" action, but it can't prevent controller from further execution. After you call redirect, response status changes to 302, but after method exits, controller still runs subsequent code.

Solution

At TouK we've implemented a simple trick to resolve that situation:

  1. wrap everything with a simple withStoppingOnRender method,
  2. whenever you want to render or redirect AND stop controller execution - throw EndRenderingException.

We call it Big Return - return from a method and return from a controller at once. Here is how it works:

class BookController {
def show(Long id) {
withStoppingOnRender {
Book bookInstance = Book.get(id)
validateInstanceExists(bookInstance)
[bookInstance: bookInstance]
}
}

protected Object withStoppingOnRender(Closure closure) {
try {
return closure.call()
} catch (EndRenderingException e) {}
}

private void validateInstanceExists(Book instance) {
if (!instance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
throw new EndRenderingException()
}
}
}

class EndRenderingException extends RuntimeException {}

Example usage

For simple CRUD controllers, you can use this solution and create some BaseController class for your controllers. We use withStoppingOnRender in every controller so code doesn't look like a spaghetti, we follow DRY principle and code is self-documented. Win-win-win! Here is a more complex example:

class DealerController {
@Transactional
def update() {
withStoppingOnRender {
Dealer dealerInstance = Dealer.get(params.id)
validateInstanceExists(dealerInstance)
validateAccountInExternalService(dealerInstance)
checkIfInstanceWasConcurrentlyModified(dealerInstance, params.version)
dealerInstance.properties = params
saveUpdatedInstance(dealerInstance)
redirectToAfterUpdate(dealerInstance)
}
}
}

Tomcat: Problemy z requestami zawierającymi polskie znaki diakrytyczne


Jeśli jest problem z pobieraniem plików z polskimi znakami diakrytycznymi, to trzeba dopisać kodowanie do connectora w tomcat/conf/server.xml

URIEncoding="UTF-8"

Typowa konfiguracja connectora będzie wyglądała tak

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8" />