0002: OOP Test Rig Breakdown

Results of this example:
Current example output
Current example output
Current example terminal output
Current example terminal output (click for enlarged view)

When you look at the imperative test rig alongside this OOP version, it becomes quickly apparent that the difference is mostly about code organization.

main()

The changes start in the main() function:

void main(string[] args)
{
	TestRigWindow testRigWindow;
	
	Main.init(args);
	
	testRigWindow = new TestRigWindow();
		
	Main.run();
	
} // main()

On line 2 of main(), the window declaration is quite different because instead of instantiating the MainWindow class directly, there’s a derived class called TestRigWindow. We also move any calls to the TestRigWindow functions to the TestRigWindow class’s constructor which strips main() down to the bare essentials.

quitApp()

quitApp() is no longer a standalone function as it’s been incorporated into the TestRigWindow class which looks like this:

class TestRigWindow : MainWindow
{
	string title = "Test Rig";
	
	this()
	{
		super(title);
		addOnDestroy(&quitApp);

		sayHi();
	
		showAll();
		
	} // this()
	
		
	void quitApp(Widget widget)
	{
		string exitMessage = "Bye.";
		
		writeln(exitMessage);
		
		Main.quit();
		
	} // quitApp()


	void sayHi()
	{
		string message = "Hello GtkD OOP World";
		
		writeln(message);
		
	} // sayHi()

} // class TestRigWindow

The first function is the constructor. D uses this() instead of the class name (like Java) or construct() (like PHP) and inside we:

  • call super(), a shorthand for calling the parent class’s constructor,
  • while passing along the window’s title, and
  • hook up the window’s close button.

Order Matters

It’s important to note here that any call to a function that will decorate the TestRigWindow—or size it or pretty much anything else—must be made after the call to super(). Otherwise, the window won’t exist, the function call goes off into oblivion, and we’ll get an error.

You’ll notice that connecting the onDestroy signal is done differently here. In the imperative version, because quitApp() is external to main(), we have to preserve quitApp’s scope so it doesn’t disappear on us before we can use it. But in the OOP version, the syntax is simplified because we don’t need to worry about scope. As long as the class object exists, everything within it will exist as well. This simplification of syntax makes our job easier, although it’ll get difficult again under certain circumstances. I’ll talk about that in later posts.

Another thing you’ll notice is that TestRigWindow’s sayHi() function has taken the place of a simple writeln() call in the imperative version of main(). We could have left it where it was, but this way all functions are part of the TestRigWindow class and there’s a certain orderliness to that.

As with all examples, to compile:

dmd -de -w -m64 -Lgtkd.lib <filename>.d

Conclusion

So, now we have two test rigs and we’ve looked at how to size a window to exact specifications. That gives us a foundation to build from in the coming posts.

Until next time when we take an initial look at GUI buttons, happy D-coding and may the widgets be with you.

Comments? Questions? Observations?

Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.

You can also subscribe via RSS so you won't miss anything. Thank you very much for dropping by.

© Copyright 2023 Ron Tarrant