Skip to content

Implementation

Chuck Walbourn edited this page Mar 26, 2019 · 45 revisions

Naming conventions

While the DirectX Tool Kit design is heavily influenced by the XNA Game Studio framework C# object design, it uses C++ conventions consistent with modern Win32 APIs rather than the strict .NET use of PascalCase as enforced by FXCop.

  • PascalCase for class names, methods, functions, and enums.
  • camelCase for class member variables, struct members
  • UPPERCASE for preprocessor defines (and nameless enums)

The library does not generally make use of Hungarian notation which as been deprecated for Win32 C++ APIs for many years, with the exception of a few uses of p for pointers and sz for strings.

SAL annotation

The DirectX Toolkit library makes extensive use of SAL2 annotations (_In_, _Outptr_opt_, etc.) which greatly improves the accuracy of the Visual C++ static code analysis (also known as PREFAST). The standard Windows headers #define them all to empty strings if not building with /analyze, so they have no effect on code-generation.

The pImpl idiom

DirectXTK's implementation makes extensive use of the pImpl idiom. This keeps the public headers slim and minimizes inter-module dependencies.

// SpriteBatch.h public header
class SpriteBatch
{
public:
    SpriteBatch(...);
    SpriteBatch(SpriteBatch&& moveFrom);
    SpriteBatch& operator= (SpriteBatch&& moveFrom);

    SpriteBatch(SpriteBatch const&) = delete;
    SpriteBatch& operator=(SpriteBatch const&) = delete;

    virtual ~SpriteBatch();
    ...

private:
    // Private implementation.
    class Impl;

    std::unique_ptr<Impl> pImpl;
};

This also allows use to allocate the pImpl class internally using _aligned_malloc(x,16); so that we can use the DIrectXMath aligned XMVECTOR and XMMATRIX types directly in the implementation across all architectures.

Calling-conventions

The std::function is used for callbacks as a general pattern so that client code can provide function pointers, lambdas, functors, etc. To support building with a mix of calling conventions, we need to annotate the std::function correctly.

    HRESULT __cdecl SaveWICTextureToFile( /*...*/,
        std::function<void __cdecl(IPropertyBag2*)> setCustomProps
            = nullptr );

Default constructors/assignment operators

The C++11 standard includes a more efficient =default and =delete construct for dealing with special constructors and operators.

To declare a standard copy constructor and copy assignment operators, we use:

Rectangle(const Rectangle&) = default;
Rectangle& operator=(const Rectangle&) = default;

To prevent copying we use:

// Prevent copying.
SpriteBatch(SpriteBatch const&) = delete;
SpriteBatch& operator= (SpriteBatch const&) = delete;

Note that use of =default can improve codegen for derived types as well.

DirectXMath Parameter Conventions

The library uses the DirectXMath calling convention types to improve parameter passing of XMVECTOR and XMMATRIX types.

Further Reading

Dual-use Coding Techniques for Games
C++ Core Guidelines

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Windows 8.1
  • Xbox One

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v20
  • MinGW 12.2, 13.2
  • CMake 3.21

Related Projects

DirectX Tool Kit for DirectX 12

DirectXMesh

DirectXTex

DirectXMath

Win2D

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

Clone this wiki locally