The Intricacies of Building a Window Class in a C++ Game Engine

Welcome back, dear friends! Today, we embark on a new adventure in our journey through C++ game engine infrastructure. In our previous video, we delved into the intricacies of air handling in the Windows API. Now, let’s shift our focus to the creation of a window class—an essential component that represents actual window interfaces.

Building a window class is no small feat. It requires careful architecture and engineering. To ensure our undivided attention to this task, we will first prepare the necessary utilities in this video before diving into the creation of the window class. And to add a sprinkle of excitement, we’ll also have a guest appearance by our friend, Chat GPT!

The Intricacies of Building a Window Class in a C++ Game Engine
The Intricacies of Building a Window Class in a C++ Game Engine

The Spa of Spatial Structures

To lay a solid foundation for our window class, we need to set up some essential utilities. We’ll begin with the Spa—short for spatial—folder. Here, we’ll place various data structures that will come in handy for spatial operations. We’ll start with vect2.h, a simple vector class that acts as a point template. It supports different numeric types and provides basic arithmetic operations like addition, subtraction, and scaling. Additionally, it includes shortcuts for float and integer versions of the class.

Next up is the dimensions class, which defines the width and height of a rectangle. This class will allow us to specify the size of the client region when creating a window.

Further reading:  The Power of Events and Event Dispatchers

Lastly, we’ll add the versatile rectangle type. This spatial structure contains useful functions to retrieve the top left, bottom right, and dimensions of a rectangle. It also includes a check to determine if one rectangle contains another.

It’s worth mentioning that all these structures are made as public structures rather than classes, as there is no need for encapsulation or additional getters and setters.

Windows Utilities to Support Spatial Structures

Now that we have our spatial structures in place, we need to integrate them with the Windows API. To facilitate this integration, we’ll create a set of Windows utility functions.

First, we’ll define conversion functions that allow us to easily convert between our advanced rectangle type and the Windows rectangle type. These functions will wrap around Windows functions and will be crucial for calculating the size of a window based on the desired client area size.

To keep our abstract structures separate from Windows-specific functionality, we’ll implement these conversion functions in a Windows utility file called utilities.cpp. Here, we’ll handle the conversions between our rectangle type and the Windows rectangle type.

Preparing for the Creation of a Window Class

Before we jump into creating the window class, let’s take care of a few more steps to set the stage for our final endeavor.

To keep our codebase clean and organized, we’ll create a separate project specifically for GUI applications. We’ll name it windowapp.h. This project will serve as the main foundation for our window class.

Within this project, we’ll add a basic shell that initializes the logging and window-related functionality. Additionally, we’ll create a log message and a test message box to ensure everything is running smoothly.

Further reading:  Polishing the UIButton: A Guide to Game Programming

Don’t worry if you noticed that we haven’t added tests for the window-related functionality yet. Testing Windows interactions can be tricky, but we’ll cover that in a future video. For now, we’ll focus on testing the simple utilities that we’ve developed.

A Generic Task Queue for Windows Threads

To enable the execution of tasks by Windows threads, we’ll create a generic task queue within the Credence Clearwater Revival (CCR) namespace. This task queue will allow us to queue up tasks and track their completion using futures.

The task queue is designed as a class with a deck protected by a mutex. It supports pushing tasks and popping/executing them within a multi-threaded environment. To ensure flexibility, tasks can be any invocable object that returns void or a value. The task queue will handle wrapping the tasks and executing them in a thread-safe manner.

While some error messages may appear during the testing phase, they can be resolved by defining the necessary specializations and exception handling.

Testing the Utilities and Task Queue

With the utilities and task queue in place, it’s time to test them to ensure their functionality and reliability. For convenience, we’ll use the Microsoft CPP Unit Test framework and multiple threads to validate the utilities and task queue.

By writing tests for our code, we can catch potential issues early on and prevent avoidable mistakes. The tests will cover a wide range of scenarios, including multiple threads and asynchronous execution.

Thanks to the help of Chat GPT, we generated a basic suite of tests. We also took advantage of GitHub Co-Pilot to generate additional test cases. Although there were a few hiccups along the way, we managed to create and run tests successfully.

Further reading:  C++ Multithreading: Unleashing Chaos

Moving Forward

With the necessary utilities and task queue tested and ready to go, we are now fully prepared to create our window class. This next step will be architecturally rich and truly exciting! Join us in the upcoming video as we dive deep into building a window class within our C++ game engine infrastructure.

As always, thank you for your continued support. If you enjoyed this video, please don’t forget to give it a thumbs up. Your support means the world to us. Until next time, stay curious and keep exploring!

This article does not provide direct links. For more information, visit Techal.

YouTube video
The Intricacies of Building a Window Class in a C++ Game Engine