Google
 

Tuesday, June 29, 2010

Java Callbacks using java.lang.reflect

Java does not have callbacks. Most commonly, I see people working around this by implementing the Observer Pattern, or simply having an interface for each method they need to use as a callback.

On a recent project, I felt the need for more direct callbacks in my Java code. Java's reflection package seemed to hold my answer. Given a Class, a method name, and (in the case of overloaded methods) a list of parameter types, you can retrieve an instance of the Method class. Then, given a list of arguments to pass to the method, it can be invoked via reflection.

Java reflection isn't particularly fast, so I recommend against this approach in applications where performance is important. But reflection works, so I present my Callback class here: package com.bs; import java.lang.reflect.*; /** * Implements callback functionality for Java. * Callbacks are implemented using reflection, so should * be avoided if possible. * * @author Brian Shields <http://clockworkgear.blogspot.com/> */ public class Callback { private Object parentObj; private Method method; private Class<?>[] parameters; public Callback(Class<?> clazz, String methodName, Object parentObj) { // Find a method with the matching name Method[] allMethods; try { allMethods = clazz.getMethods(); } catch(SecurityException se) { allMethods = new Method[0]; } int count = 0; Method single = null; for(Method m : allMethods) { if(m.getName().equals(methodName)) { single = m; count++; } // Can't have more than one instance if(count > 1) throw new IllegalArgumentException(clazz.getName() + " has more than one method named " + methodName); } if(count == 0) // No instances found throw new IllegalArgumentException(clazz.getName() + " has no method named " + methodName); this.parentObj = parentObj; this.method = single; this.parameters = single.getParameterTypes(); } public Callback( Class<?> clazz, String methodName, Object parentObj, Class<?>...parameters) { try { this.method = clazz.getMethod(methodName, parameters); } catch(NoSuchMethodException nsme) { nsme.printStackTrace(); } catch(SecurityException se) { se.printStackTrace(); } this.parentObj = parentObj; this.parameters = parameters; } public Object call(Object...vals) { if(parameters.length != vals.length) throw new IllegalArgumentException( "Wrong number of method parameters given. Found " + vals.length + ", expected " + parameters.length); Object ret = null; try { ret = method.invoke(parentObj, vals); } catch(IllegalAccessException iae) { iae.printStackTrace(); } catch(InvocationTargetException ite) { ite.printStackTrace(); } return ret; } }

Tuesday, April 20, 2010

The Tao of Game Features

This quote was taken from "Arcanaville" on the City of Heroes forums, with regard to adding new features to the game. The quote is lovely, and I think it applies to just about any update to any game, or software in general.

It's never as hard as the developers say it is, it's never as easy as the players think it is, and the best way to do it is most likely to be a way both groups would initially think is insane.

Tuesday, March 30, 2010

My Art Professor Sucks

This post is likely to get emotional, empassioned, and have strong language. You have been warned: here be dragons.

So, Rice university requires a certain number of credit hours in three distributions: D1 (literature, languages, art, etc.), D2 (philosophy, sociology, psychology, etc.), and D3 (math, science, engineering, etc.). This semester, I'm finishing my D1 requirements by taking an American Literature class, and a Drawing class.

I am not an artist. This has been painfully clear to me since elementary school.

However, "Drawing I" should be a gimme class; an easy B, if not an easy A. Right?

Well, it would be right, if my professor didn't suck. To be PC, I shouldn't speak ill of her: she's got Parkinson's disease, so I should be nice. Right? But she still sucks.

For our final project, we're supposed to pick a subject that interests us. There are several steps to the project, so far we've needed to submit a clip file (clippings from various sources which interest us or appear similar to our interests), and a few preliminary sketches. My chosen subject in the general case was Exalted. I had lots of sources to pull from. Hell, I've got over 100 artists which have worked directly on the book themselves! No problem making a clip file. Right

When I submitted it for feedback, she says I need wider diversity of sources. Of course, every picture in my clip file comes from a different artist! Some of my pictures weren't even directly part of the Exalted series, they just fit the theme.

The next part was a preliminary sketch. I selected a very dramatic picture of the Ebon Dragon flying over an area of Malfeas, blocking out Ligier the Green Sun as inspiration for my sketch. When I submitted my sketch for review, she told me that the image was too literal. When she asked me to describe the image, I mentioned that I didn't invent the character &mdash; an obvious mistake. Because I didn't invent the character, because I drew the character from a game, my sketch wasn't worthwhile. Worse, she then told me to use Greek and Christian dragon myths to make my drawing.

So, using a dragon that I could write a small book about is not sufficient... but using dragons that I could only write an essay about if I filled the essay with BS is a good idea? Who fucking cares if source A was written 9 years ago and source B was written 900 years ago, if source A is richer and more developed?

"Here be dragons," huh? This fucking dragon is larger, more deadly, and has a personality along with a rich and full backstory. He's not some fucking vauge threat looming in the shadows of the world. He's a very real and present threat to Creation.

The Ebon Dragon was trapped for eternity in hell. But he's patient, and he lives longer than eternity.

(Oh, and let's not forget his upcoming wedding, plus the "Return of the Scarlet Empress" book that's coming out this summer)