Jan
31
2009
0

FYP Technology: Refactoring an Airplane

In our Systems Analysis and Design class we’re studying RUP and not having ever worked in a company big enough to warrant its use, I’m having trouble understanding a lot of the advantages we’re told it has, although I’m sure I’d start to see them in a big enough software project.. maybe.

We’ve been told how immature software engineering is, and how we still have so much to learn from more mature manufacturing industries. Like when building a car (do we really want to take advice from American manufacturers right now?), a blueprint must be created first, and only when you have the entire thing designed, end to end, do you start the actual assembly of the product. I’ve heard this argument quite a few times and it’s frustrating to hear it over and over again, simply because software is not a car. It’s not an airplane either. Nor a house. I would argue that software development is more similar to writing a book than it is to any traditional manufacturing process.

The key is refactoring. With a book you can re-arrange pages and chapters, and rewriting a page isn’t expensive. However, if you’re making a car and you have all the parts in front of you, it’s expensive to change something or reassemble things. Even more so with a house or airplane: just not comparable to software.

Anyway, I’ve been doing a lot of refactoring recently. I guess my style of development is XP-like, if you have to give it a name. I throw something together that works, then clean it up when I have it working, then continue throwing more stuff together until that works and repeat the cleanup. It’s a pretty obvious way of development if you’re doing a solo project, but I just wanted to make note of it as refactoring’s been my focus for a while now. It’s an interesting bit of work to try to help a design fall out out of the mess that’s there. I usually end up with monstrously long functions and then:

  • Restrict scope of parts that seem related. Usually I have these double-spaced out so it’s just a matter of putting braces around them.
  • Break these parts out into functions. This might involve introducing globals, but that’s ok.
  • Group the related functions and globals together and have a good hard think about how classes might be designed with them, and how these classes would work together.

One thing that I keep concentrating on is semantic cohesion. Just looking at the above bullet points alone might put something together that works, but that’s not enough. By thinking of what each class means and what it represents, it becomes much easier to group them together with a super class and use those classes polymorphically, and to extend them in directions that make sense. Right now if you look through my code you might see a lot of “cross-cutting concerns”, where one function is doing something that it really shouldn’t have to be doing. A nice way of spotting these is, for example, when I find code creating rigid bodies and meshes inside my mouse listener. If a mouse event callback wants to do that sort of thing, that’s ok, but it should allow the graphics and physics classes look after it instead of taking on that responsibility itself.

Refactoring code is something I did a bit in Havok for a few weeks. There was one particular project which I was given ownership of, and most of the work I did on it was reducing duplicate code, and removing hard-coded values (and of course, finding flexible, centralised ways of replacing those hard-coded values).

It’s quite enjoyable to sit down with a big mess of code, and spend a few hours moving things around only to have no more apparent functionality, but an altogether better system. Later on in the project it really will help me rewriting code, and if I end up taking a break from it around exams and coming back to it when applying to a Master’s programme, if it’s an intuitive design I should be able to jump right in.

Not wanting to break tradition, here’s a video of Yellow Magic Orchestra playing Rydeen. This TV performance was in 1993, ten years after they broke up. (Thanks Jim!)

No comments »
Written by ダニエル氏 in: University |
Jan
30
2009
2

FYP Report: Wiki Report!

I’ve been filling out the wiki on Yakumo’s Trac page and it’s proving a pretty nice way of collecting information. It might make an interesting appendix for the final report, but there’s plenty in there that I’m sure I can re-use, though mostly as introductions to sections with what I have so far. I hope to get a bit deeper into the tech as I go along though.

I’ve been thinking that it might be an interesting way for an examiner (or who-ever it is that’s looking at it) to learn about the technology and work involved. It’s a long time since I’ve heard anyone preach the merits of hypertext, but it really is a great way to explore a subject, and a great way to create a set of documents. I think Wikipedia is a great example of this, and my point is proven by your browser’s tab bar 30 minute after going to Wikipedia for anything, and the size of the project.

Incidentally, any wikis I’ve ever contributed to seem to have an equilibrium that they finally reach. Depending on the subject, and number of contributers, this level of equilibrium differs from wiki to wiki, but it definitely exists. Let’s hope that if I keep writing mine will get to that state of satisfactory completeness.

I’ve uploaded the original presentation on Yakumo that I gave last semester. I’m pretty sure I had the goals I outlined completed in the first 4 days of development. If only I had been using SVN back then I’d be able to figure out exactly how long…

I’ll leave you with Japanese punk band Blue Hearts’ debut hit, a 1987 track by the name of “Linda Linda”. Always a fun one to sing at karaoke. Gotta love Hiroto’s energy.

2 comments »
Written by ダニエル氏 in: University |
Jan
29
2009
3

BoingBoing slams Ireland

Cory Doctorow just made a couple of posts about Irish companies on BoingBoing, one of the internet’s most read blogs:

Another piece of international (Australian) news about Ireland:

Sometimes it can be quite embarrassing to be Irish. When I was looking for an apartment in San Francisco many landlords were pretty cautious once I told them where I was from. One guy told me how he usually doesn’t take Irish students as tenants because we’re noisy, cause trouble and drink too much and then fill up everyone’s bins with our empty bottles and cans from the night before. Patrick told me of similar experiences with American landlords. Just look at J-1 Summer on RTÉ to see how we carry on, if you haven’t already experienced that sort of carry on first-hand.

If you look at what sort of reporting is going on about Irish tourists, Irish companies, and the Irish government, we look like a bunch of crooks.

3 comments »
Written by ダニエル氏 in: Uncategorized |
Jan
28
2009
2

FYP Technology: SVN

SVN is now set up for the FYP. The Trac page is live from Skynet. As I update my code/content/reports they’ll go in there.

Usually I never make any code I do publicly visible but an experiment with the FYP is to make everything visible as I work on it. As with the blog, which is effectively my journal to help me compile my final report, knowing that people are (or may be) watching is proving to be a great motivator.

Any and all input on the project’s code, content, documents, or blog-commentary is welcome. :)

2 comments »
Written by ダニエル氏 in: University |
Jan
28
2009
0

FYP Technology: Optional Multithreaded Callbacks with Boost

Here’s an abstraction of a class I’m having some fun with. In my own use:

  • init() is called and a pointer to a listener (subclass of SomeClassListener) is passed in. The instance this pointer points to is what handles the callbacks.
  • init() continues to start a socket and start a thread with threadLoop().
  • threadLoop() receives data from the socket, grabs the header, and decides what callback to fire based on that header.

The following code demonstrates how Boost::bind allows the check for whether or not to multithread a callback can be done in one place for every single callback (see fireCallback()).

#include "SomeClassListener.h"
 
class SomeClass
{
public:
	SomeClass();
	int init(SomeClassListener* listener);
	bool isMultithreadingEnabled();
	void setMultithreadedCallbacks(bool enabled);
 
private:
	int threadLoop();
	template <typename T> void fireCallback( T handler );
 
private:
	SomeClassListener *listener;
	bool isMultithreaded;
 
	enum {
		CALLBACK_TYPE_1 = 0,
		CALLBACK_TYPE_2,
		CALLBACK_TYPE_3,
	};
 
	typedef struct DataType1 {
		float x;
		float y;
		float z;
	} DataType1;
 
	typedef struct DataType2 {
		char* foo;
		bool bar;
	} DataType1;
};
 
 
/***************************/
 
SomeClass::SomeClass()
{
	setMultithreadedCallbacks( false );
}
 
int SomeClass::init(SomeClassListener* listener)
{
	/* Various initialisations... */
 
	this->listener = listener;
	new boost::thread(boost::bind(boost::mem_fn(&SomeClass::threadLoop), this));
 
	return 0;
}
 
bool SomeClass::isMultithreadingEnabled()
{
	return isMultithreaded;
}
 
void SomeClass::setMultithreadedCallbacks(bool enabled)
{
	isMultithreaded = enabled;
}
 
template <typename T>
void SomeClass::fireCallback( T handler )
{
	if ( isMultithreadingEnabled() )
		new boost::thread(handler);
	else
		handler();
}
 
int SomeClass::threadLoop()
{	
	printf("Thread starting...\n");
	for ( ;; )
	{
		// void* dataStart = recvSomeData();
		/* Do something to present us with a decision, such as checking data headers. */
 
		switch ( option )
		{
		case CALLBACK_TYPE_1:
		{
			DataType1* d = (DataType1*)dataStart;
			// SomeClassListener::callback1( float, float, float )
			fireCallback(boost::bind(boost::mem_fn(&SomeClassListener::callback1), listener, d->x, d->y, d->z ));
			break;
		}
		case CALLBACK_TYPE_2:
		{
			DataType2* d = (DataType2*)dataStart;
			// SomeClassListener::callback2( char*, bool )
			// (you might want to memcpy() that char* if this will be multithreaded,
			//  as once this thread receives more data, the buffer will be overwritten.
			fireCallback(boost::bind(boost::mem_fn(&SomeClassListener::callback2), listener, d->foo, d->bar ));
			break;
		}
		case CALLBACK_TYPE_3:
		{
			void* d = (void*)dataStart;
			// SomeClassListener::callback3( void* )
			fireCallback(boost::bind(boost::mem_fn(&SomeClassListener::callback3), listener, d ));
			break;
		}
		default:
			printf("***ERROR***\n");
		}
	}
	printf("Thread finished...\n");
	return 0;
}
No comments »
Written by ダニエル氏 in: University |
Jan
28
2009
0

FYP Technology: Mutexes to the rescue!!

After spending half the day trying to figure out why my application was crashing randomly while processing the accelerometer data, I fixed it at 00:00 on the dot.

I kept getting random crashes once the callback for accelerometer data receipt was fired a few dozen times. The errors I was getting were so totally random I knew it had to be a memory trashing problem, but I couldn’t figure out where it was. All my code looked great, but of course, I wasn’t fully taking multithreading into account, and I’m multithreading this thing like you can’t imagine.

All the callback was doing was drawing a vector to the screen… how could that possibly cause a problem? Well it suddenly hit me that I was using the Ogre scene-manager to draw the vector, and since Ogre’s main loop was working away in another thread, it was very likely that I was mucking things up by throwing in a new line without waiting my turn on the scene manager data.

To fix it, I created a mutex, locked the Ogre world in the frameStarted() callback and unlocked in the frameEnded() callback. I also locked and unlocked the mutex within the scope of my accelerometerUpdated() callback. And it works!

It was horrible trying to fix such an tricky bug for so long but getting it solved is really rewarding. In fact, to celebrate, I’m going to watch more B’z videos. Here’s OH! GIRL. This involves the guitarist playing back-to-back with a chick playing a Keytar:

No comments »
Written by ダニエル氏 in: University |
Jan
27
2009
0

FYP Report: Interim Report writing

My pace of development has been broken with lectures, an interim report due on Thursday, our first university assignment, and helping Sean with his PS3 stuff (though I think he’s actually got the hang of Linux right about now and won’t be needing much more from me). With all that going on, all I’ve done is a bit more refactoring.

I wish I remembered how much of my FYP mark is going for the interim report. I have a feeling it’s 10% but I don’t have the marking scheme handy. I guess I’ll just have to do my best with it!

I’ll leave you with some more oldschool Japanese music. ALONE is a 1991 B’z track, re-released in 2003. I sang the English backing vocals at the end while Ayumi’s dad sang the rest of the last time I was in karaoke in Japan. This video features a cigarette-smoking lead guitarist playing on top of a grand piano so don’t miss it!

No comments »
Written by ダニエル氏 in: University |
Jan
26
2009
0

FYP Technology: UDP to the rescue! and generalising communications

After all my TCP troubles I decided to put aside my pride and the coolness of a well-designed TCP data stream, I decided to go with UDP, which is admittedly obviously better suited to my uses. For example, I don’t need to specify how much data to read from a stream, as one datagram will hold everything I need: no need for paranoia about the data stream losing sync! It’s working perfectly as of last night.

Today I had some time between lectures so I generalised my accelerometer-input to work for touches as well, so dragging a finger across the iPod’s screen is sent as well as 60 datagrams/second of accelerometer data.

I’m reaching the stage where I’m starting to refactor code now, and some of it is starting to look pretty neat. As I go along, I keep asking myself how I can keep concerns separate and refactor classes accordingly.

Interim report on Thursday so that’s my next objective!

Until the next post, enjoy L’arc~en~ciel’s Blurry Eyes from 1994!

No comments »
Written by ダニエル氏 in: University |
Jan
25
2009
0

FYP Technology: SO_RCVBUF

I spent all day yesterday trying to get the jerky movement out my accelerometer->PC graphics data stream. First I changed out the standard winsock code on the PC with Boost’s ASIO stream sockets. Didn’t change anything… and building the Boost libraries took a long time: I had to uninstall the VS2008 compiler so it would use the VS2005 compiler as environment setting scripts weren’t changing anything, so I ended up building everything 3 times.

Next I changed out the NSNetService streams on the iPod with standard unix sockets… still the same problems.

What made me figure out how to get it working was when I made a dummy server in Xcode and it worked fine… it must be a Windows thing. Sure enough, it was. I enabled TCP_NODELAY and changed SO_RCVBUF to 128 bytes and it’s working! I think I might be getting a buffer underrun though, as even though I ask for 12 bytes, I get 10 and everything falls apart after a hundred or so recv() calls. SO_RCVLOWAT is 1 by default, which means that if 12 bytes are requested, but only 1 is available, you’ll only get 1. The lower of SO_RCVLOWAT and the requested amount is what you get. So, I set SO_RCVLOWAT pretty high (over 100), but the problem didn’t go away. I think I’ll try changing the send buffer size (SO_SNDBUF) on the iPod and see how that affects things.

Until then, I shall leave you with a song by Japanese 80s hit sensation, BOOWY:

No comments »
Written by ダニエル氏 in: University |
Jan
24
2009
2

FYP Technology: Identity/Multithreaded Network IO/more iPhone SDK

I finally decided on a name for the software I’m developing for my FYP, and it’s Yakumo. Sounds cute, silly and abstract… perfect for a modern technology.

One of my most admired authors is Patrick Lafcadio Hearn, a man born in 1850 to an Irishman and Greek woman, and who spent much of his life in one of the most exciting eras of Japanese history, writing passionately all the while about his experiences of Japanese society. He married a Samurai’s daughter, Setsu Koizumi, and changed his name to Yakumo Koizumi when he received his naturalised citizenship. It literally means “Eight Clouds” and is also the name of a couple of small villages in Japan.

Yakumo iconThe temporary icon that I threw together today is the top two thirds of a white “8″ on a deep blue background. You should be able to see it beside this paragraph. This is the auto-prettified version that the SDK kindly fixed up for me. The gloss and rounded corners are not my own doing. I don’t think I’ll take advantage of this functionality in the end, as lots of apps use it and I think it might stand out a little more if I make it a bit different.

Yesterday I was a bit worried about the lag I was seeing on the input from the iPod but I set up some basic multithreading today and the lag is no longer very noticeable. Unfortunately, it’s not quite jerky. It feels like it’s only getting updated four times a second instead of sixty. I have the problem narrowed down to two possible locations anyway (either side of the communication between the the local socket and game input on the PC).

I spent a bit more time today with UIKit, the iPhone/iPod’s UI library. Apart from the apparent but in UIViewController’s hidesBottomBarWhenPushed method, it’s been an entirely pleasant and encouraging experience! Coming from the world of PHP, of course I’m going to find documentation lacking, but that’s made up for by the intuitiveness of the various frameworks available and, of course, the named parameter lists. Hate to keep picking on the fat, unpopular, oh-so-easy-to-bully kid, but when I start a thread on Windows, 4 of the 6 parameters I enter are 0 or NULL.

Also, a gripe with C++ that the dynamicness (is that a work?) of Objective-C has amplified: I can’t define the entry-point of the thread to be a non-static class member. Why this is is obvious to anyone who knows their C++, and they might sent a superior snort my way for complaining about it… but I do understand the benefits of such a static environment, and my frustration isn’t from a lack of understanding or familiarity with C++, it’s from seeing how easy it is when I can just say @selector(threadEntryPoint). Here’s my compromise:

  • Since we’re going static, and then calling an instance member from there, create a ThreadPayload struct to contain both pointers:
    struct ThreadPayload {
    	YkRemote* self;
    	AccelerationData **accel;
    };
  • Change the call to dynamically allocate and popular the struct. (Anyone know how to initialise a dynamically allocated struct immediately? i.e., dynamic equivalent of struct myStruct s = { 1, 2, 3 } syntax)
    	struct ThreadPayload *payload = new struct ThreadPayload;
    	payload->self =  this;
    	payload->accel = accel;
    	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) YkRemote::startThread, payload, 0, NULL);
  • Set up a static entry-point which calls the instance’s non-static member, then frees the memory when it’s no longer needed:
    DWORD YkRemote::startThread (void *payload)
    {
    	struct ThreadPayload *p = (struct ThreadPayload*)payload;
    	((YkRemote*)(p->self))->threadLoop(p->accel);
    	delete p;
    	return TRUE;
    }

Update: Boost threads/bind to the rescue! I replaced all the code above with this:

boost::thread newThread(boost::bind(boost::mem_fn(&YkRemote::threadLoop), this, accel));
2 comments »
Written by ダニエル氏 in: University |

Powered by WordPress | Theme: Aeros 2.0 by TheBuckmaker.com