Jump to content

[OOP] OOP-Light - yet-another preprocessor-based OOP implementation for SQF

Recommended Posts

This is an OOP implementation for SQF which is hugely inspired by a similar project, OOP.h .

Why another one? I like OOP.h but as I found out, it has a big impact on performance, which lies deep in how it is done. I don't mean to say that OOP.h is bad, it just has one limitation which I was forced to work around. Then it's better to share code than not, right?


So, I decided to reinvent it, but with the aim of minimizing performance impact, and here is what we have:

  1. Based on SQF preprocessor, so you need to #include a single file.
  2. Supports member variables, methods, static variables, static methods and class inheritance(no multiple inheritance yet).
  3. With a single preprocessor flag (#define OOP_ASSERT in OOP_Light.h) you can enable or disable run-time error checks, which verify most common errors, like attempts to access a non-existent member or class. If enabled, it will output errors in a human-readable way.
  4. Good performance. Really, with debug disabled, a macro like GETV(_veh, "varName"); gets expanded into "missionNamespace getVariable (_veh+"_"+"varName");", which is typically not such a great performance loss.
  5. No support for public/private/protected keywords yet, so all members are public.


Currently it is in 'beta' state. It seems to work and I don't see any major game-breaking issues with it as I have tried to do a little development with it. Also there is no documentation but you can examine the example files and classes and see how it works.


As an example, the project contains a few useful classes written with OOP-Light: MessageLoop, MessageReceiver and Timer. An example of how to use them is located in Example.sqf file.

MessageLoop and MessageReceiver can help you easily create a message loop, a useful construction which lets you manage processing of some events in a fixed amount of SQF threads, or helps you pass data between threads.

Timer class just generates messages at fixed time intervals and sends them to the specified MessageReceiver.


Github link:



I hope someone finds this useful!

  • Like 1
  • Thanks 2

Share this post

Link to post
Share on other sites
On 10/31/2018 at 12:48 AM, Sparker said:

a macro like GETV(_veh, "varName"); gets expanded into "missionNamespace getVariable (_veh+"_"+"varName");",

I would have thought it expanded into 

_veh getVariable "varName"


Share this post

Link to post
Share on other sites

Hi KK!

An object in my OOP isn't represented in a separate namespace, but instead with a unique prefix for all object's variables in the existing namespace: missionNamespace or uiNamespace or an existing namespace (although only missionNamespace is supported now, but implementing others is not so hard).
OOP objects could have been internally implemented with their own namespaces such as createVehicle or createLocation. Then in order to pass a one OOP object's reference to some other script, I would pass the createVehicle's return value. It's fine for the run time of the mission, but to implement some saving of OOP objects into profileNamespace, OOP object references must be savable into profileNamespace. It gets even worse if there are multiple OOP objects all pointing at each other!


So instead the reference to an OOP object is just a unique string, auto generated when the object is constructed. It's perfectly storable in profileNamepsace.


Also I suppose that implementing every OOP object as a separate arma object is more heavy on memory usage than just adding more entries into the existing missionNamespace hash map, it can hold thousands of variables very well.

Share this post

Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in

Sign In Now