-
Notifications
You must be signed in to change notification settings - Fork 0
Design
Infinity uses a hidden entry point to abstract the game loop away. This entry point can be found in EntryPoint.h, but should be included as follows:
Make sure to include the entry point in a file which is NOT included by any other files (a .cpp file is a good choice). To include the entry point, simply define INFINITY_ENTRY_POINT before include Infinity.h. This is all you need to get a functional entry point!
At the heart of the Infinity game engine lies a state machine which allows the easy encapsulation and execution of sequential code. To use the engine, the client must override the Infinity::State class and implement the four functions described below. To start the chain of states however, the client must implement Infinity::SetClientStartState, where Infinity::SetStartState</name of start state/>() should be executed.
Currently the user has no control over the window. This is likely due to change. The client has control over the context (Not the creation or destruction) and any models and shaders that are created. All transactions are performed using an event system, so client code is more encapsulated.
There are four types of user-events: Infinity::StateEnteredEvent -> Sent once when the state is entered, after the last state terminated Infinity::StateUpdatedEvent -> Sent in a loop (speed varies depending on if vsync is enabled), only contains time delta Infinity::StateRenderedEvent -> Rendering should be done here Infinity::StateExitedEvent -> Sent once after the window was successfully closed, or when the state requests termination. Here the state can specify which state should be transitioned to
There exist many other useful events as well, described in the Events section.
The Infinity::State class provides the user with some helper functions to make the capturing of these events easier.
State::RequestExit() -> just pushes an Infinity::StateExitedEvent behind the scenes.
To simplify the process of rendering rectangles onto the screen (Any kind of 2D rendering), the Renderer2D class has been created as a utility. This class only uses code available to the client and is therefore not necessarily more efficient than client code. Additionally, the client has access to a simple math library (without SIMD support, hard to maintain cross-platform) and a camera class (OrthoCamera, PerpectiveCamera).
Almost every polymorphic class/resource has the following structure:
namespace Infinity
{
class ResourceName
{
public:
ResourceName(/* params on rare occasion */) {} // default constructor
virtual ~ResourceName() {} // virtual default destructor
virtual bool Init(/* params here */) = 0; // Init function returns true if successful, logs message otherwise
static Resource<ResourceName> CreateResourceName(/* params for constructor */); // implemented in platform-specific code
};
}
So following code will be very common in the client:
void ClientState::OnStateEntered(Infinity::StateEnteredEvent &event)
{
Resource<Model> model = Model::CreateModel();
if (!model->Init())
{
INFINITY_CLIENT_ERROR("Error creating model");
RequestExit();
return;
}
}
void ClientState::OnStateExited(Infinity::StateExitedEvent &event)
{
// clean up is performed internally
}
That's it for the design page!