Updated Using raylib with Cpp (markdown)

master
Jeffery Myers 1 year ago
parent
commit
e5e8343097
1 changed files with 62 additions and 0 deletions
  1. +62
    -0
      Using-raylib-with-Cpp.md

+ 62
- 0
Using-raylib-with-Cpp.md

@ -25,3 +25,65 @@ This change needs to be made for code that is pulled from the raylib C examples.
```cpp
DrawText(my_string.c_str(),0,0,20,RED);
```
# Shared GPU resources in constructors and destructors.
It is a common Object Oriented pattern to use Resource Acquisition Is Initialization (RAII). It may seem obvious to use this pattern with textures and models in raylib. This is possible to do, but the developer must be ware of the object lifetime, and when copies are made. For shared resources you need to follow the rule of 5 (https://en.cppreference.com/w/cpp/language/rule_of_three).
It is very common for new developer to make a class like this to automatically load an unload textures when things are created or go out of scope.
```
class MySprite
{
private:
Texture2D m_texture = { 0 };
public:
MySprite(Texture2D texture)
:m_texture(texture);\
{
}
~MySprite()
{
UnloadTexture(m_texture);
}
};
```
The problem is when you use that class in code like this.
```
std::vector<MySprite> sprites;
MySprite aSprite(LoadTexture("Somefile.png"));
sprites.push_back(aSprite);
```
Push_back on the vector will make a copy of aSprite in the vector and then aSprite will go out of scope.
The copy constructor for MySprite does not load a new texture, it just copies the ID values from the source texture.
So then you have (for a short time) two objects that point to the same texture. When aSprite goes out of scope, it will call UnloadTexture and remove the texture ID from the GPU. So now you have a copy of the sprite in the container that points to an unloaded texture. This will not work for drawing.
If you want to use this pattern, you need to ensure that you don't make copies of things that contain shared resources. The simplest way to handle this is to remove the assignment and copy constructor operators and use std::move or emplace features to ensue that the container owns the data and manages the lifetime.
```
class MySprite
{
private:
Texture2D m_texture = { 0 };
public:
MySprite(Texture2D texture)
: m_texture(texture)
{
}
MySprite(const MySprite&) = delete;
MySprite& operator = (const MySprite&) = delete;
~MySprite()
{
UnloadTexture(m_texture);
}
};
std::vector<MySprite> sprites;
sprites.emplace_back(LoadTexture("SomeFile.png"));
```
Scope and object lifetime are very important when dealing with this pattern.

Loading…
Cancel
Save