Graphics Animations & Renaming

This commit is contained in:
IlushaShurupov 2023-07-23 22:11:14 +03:00
parent 3a68e70f03
commit 5f186164a0
15 changed files with 718 additions and 318 deletions

View file

@ -16,7 +16,7 @@ file(GLOB HEADERS "./public/*.hpp")
add_library(${PROJECT_NAME} STATIC ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
target_include_directories(${PROJECT_NAME} PRIVATE ${BINDINGS_INCLUDE})
target_link_libraries(${PROJECT_NAME} PUBLIC Strings)
target_link_libraries(${PROJECT_NAME} PUBLIC Strings Math Utils)
target_link_libraries(${PROJECT_NAME} PRIVATE ${BINDINGS_LIBS})
### -------------------------- Examples -------------------------- ###

View file

@ -1,8 +1,8 @@
#include "Graphics.hpp"
#include "Window.hpp"
int main() {
tp::ModuleManifest* deps[] = { &tp::gModuleAllocators, nullptr };
tp::ModuleManifest* deps[] = { &tp::gModuleGraphics, nullptr };
tp::ModuleManifest testModule("Example", nullptr, nullptr, deps);
if (!testModule.initialize()) {

View file

@ -0,0 +1,104 @@
#include "Animations.hpp"
using namespace tp;
bool AnimValue::gInTransition = false;
halnf AnimValue::interpolate() const {
if (!mTimeAnim) {
return mVal;
}
auto dt = gCurrentTime - mTimeStart;
if (dt > mTimeAnim) dt = mTimeAnim;
auto t = (halnf)dt / (halnf)mTimeAnim;
t = (halnf)(0.511 + atan((t - 0.36) * 28) / 2.9);
t = clamp(t, 0.f, 1.f);
auto out = mValPrev + (mVal - mValPrev) * t;
return out;
}
AnimValue::AnimValue() = default;
void AnimValue::setAnimTime(halni time) {
mTimeAnim = time;
}
AnimValue::AnimValue(halnf val) {
mVal = val;
mValPrev = mVal;
mTimeStart = gCurrentTime;
}
bool AnimValue::inTransition() const {
auto timePassed = gCurrentTime - mTimeStart >= mTimeAnim;
return !timePassed;
}
void AnimValue::set(halnf val) {
if (!inTransition()) mValPrev = mVal;
if (val == mVal) return;
mValPrev = get();
mVal = val;
if (!inTransition()) mTimeStart = (halni)gCurrentTime;
}
halnf AnimValue::getTarget() const {
return mVal;
}
void AnimValue::setNoTransition(halnf val) {
mValPrev = val;
mVal = val;
mTimeStart -= mTimeStart;
}
halnf AnimValue::get() const {
if (inTransition()) {
gInTransition = true;
}
return interpolate();
}
AnimValue::operator halnf() const {
return get();
}
RectF AnimRect::get() const {
return { x.get(), y.get() , z.get(), w.get() };
}
RectF AnimRect::getTarget() const {
return { x.getTarget(), y.getTarget() , z.getTarget(), w.getTarget() };
}
void AnimRect::setNoTransition(RectF rec) {
x.setNoTransition(rec.x);
y.setNoTransition(rec.y);
z.setNoTransition(rec.z);
w.setNoTransition(rec.w);
}
void AnimRect::setAnimTime(const halni time) {
x.setAnimTime(time);
y.setAnimTime(time);
z.setAnimTime(time);
w.setAnimTime(time);
}
void AnimRect::set(const RectF& in) {
x.set(in.x);
y.set(in.y);
z.set(in.z);
w.set(in.w);
}
RGBA AnimColor::get() const {
auto col = mColor.get();
return {col.x, col.y, col.z, col.w};
}
void AnimColor::set(const RGBA& col) {
mColor.set(RectF(col.r, col.g, col.b, col.a));
}

View file

@ -0,0 +1,6 @@
#include "GraphicsCommon.hpp"
namespace tp {
static ModuleManifest* deps[] = { &gModuleStrings, &gModuleMath, nullptr };
ModuleManifest gModuleGraphics = ModuleManifest("Graphics", nullptr, nullptr, deps);
}

View file

@ -0,0 +1,59 @@
#include "Window.hpp"
// -------- OpenGL -------- //
#include <GL/glew.h>
#include "WindowContext.hpp"
// -------- Canvas -------- //
#define NANOVG_GL3_IMPLEMENTATION
#include <nanovg.h>
#include <nanovg_gl.h>
namespace tp {
class Graphics::Canvas::Context {
public:
NVGcontext* vg;
};
}
using namespace tp;
Graphics::Canvas::Canvas() {
mContext = new Context();
}
Graphics::Canvas::~Canvas() {
delete mContext;
}
void Graphics::Canvas::init() {
mContext->vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
}
void Graphics::Canvas::deinit() {
// Cleanup
nvgDeleteGL3(mContext->vg);
}
void Graphics::Canvas::proc() {
auto width = 600;
auto height = 600;
// Start NanoVG rendering
nvgBeginFrame(mContext->vg, width, height, 1.0);
// Draw a rectangle
nvgBeginPath(mContext->vg);
nvgRect(mContext->vg, 50, 50, 50, 50);
nvgFillColor(mContext->vg, nvgRGBf(0.8f, 0.4f, 0.1f));
nvgFill(mContext->vg);
// End NanoVG rendering
nvgEndFrame(mContext->vg);
}
void Graphics::Canvas::draw() {
// End NanoVG rendering
nvgEndFrame(mContext->vg);
}

View file

@ -0,0 +1,57 @@
#include "Window.hpp"
#include "WindowContext.hpp"
// -------- Debug UI -------- //
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
namespace tp {
class Graphics::GUI::Context {
public:
ImGuiIO* io{};
ImGuiContext* ctx{};
};
}
using namespace tp;
Graphics::GUI::GUI() {
mContext = new Context();
}
Graphics::GUI::~GUI() {
delete mContext;
}
void Graphics::GUI::init(Window* window) {
IMGUI_CHECKVERSION();
mContext->ctx = ImGui::CreateContext();
mContext->io = &ImGui::GetIO();
// Initialize ImGui with GLFW and OpenGL
ImGui_ImplGlfw_InitForOpenGL(window->getContext()->window, true);
ImGui_ImplOpenGL3_Init("#version 330");
}
void Graphics::GUI::deinit() {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void Graphics::GUI::proc() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// ImGui code goes here
ImGui::Begin("Window");
ImGui::End();
}
void Graphics::GUI::draw() {
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

View file

@ -1,262 +0,0 @@
#include "Graphics.hpp"
#include "Allocators.hpp"
// -------- OpenGL -------- //
#include <GL/glew.h>
// -------- Window Context -------- //
#include <GLFW/glfw3.h>
// -------- Debug UI -------- //
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
// -------- Canvas -------- //
#define NANOVG_GL3_IMPLEMENTATION
#include <nanovg.h>
#include <nanovg_gl.h>
#include <cstdio>
namespace tp {
class ShowoffGlContext {
public:
// Showoff data
GLuint vao{};
GLuint vbo{};
GLfloat vertices[9] = {
-0.0f, -0.0f, 0.0f, // Left vertex
1.0f, 0.0f, 0.0f, // Right vertex
0.5f, 1.0f, 0.0f // Top vertex
};
};
class ShowoffGUIContext {
public:
ImGuiIO* io{};
ImGuiContext* ctx{};
};
class ShowoffCanvasContext {
public:
NVGcontext* vg;
};
class WindowContext {
friend Showoff::GL;
friend Showoff::GUI;
friend Showoff::Canvas;
public:
GLFWwindow* window;
};
}
using namespace tp;
Showoff::GL::GL() {
mContext = new ShowoffGlContext();
}
Showoff::GL::~GL() {
delete mContext;
}
void Showoff::GL::init() {
// Create a Vertex Array Object (VAO)
glGenVertexArrays(1, &mContext->vao);
glBindVertexArray(mContext->vao);
// Create a Vertex Buffer Object (VBO)
glGenBuffers(1, &mContext->vbo);
glBindBuffer(GL_ARRAY_BUFFER, mContext->vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(mContext->vertices), mContext->vertices, GL_STATIC_DRAW);
// Set up vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*) nullptr);
glEnableVertexAttribArray(0);
}
void Showoff::GL::deinit() {
glDeleteBuffers(1, &mContext->vbo);
glDeleteVertexArrays(1, &mContext->vao);
}
void Showoff::GL::beginDraw() {
glClear(GL_COLOR_BUFFER_BIT);
}
void Showoff::GL::endDraw() {
glDrawArrays(GL_TRIANGLES, 0, 3);
}
Showoff::GUI::GUI() {
mContext = new ShowoffGUIContext();
}
Showoff::GUI::~GUI() {
delete mContext;
}
void Showoff::GUI::init(Window* window) {
IMGUI_CHECKVERSION();
mContext->ctx = ImGui::CreateContext();
mContext->io = &ImGui::GetIO();
// Initialize ImGui with GLFW and OpenGL
ImGui_ImplGlfw_InitForOpenGL(window->getContext()->window, true);
ImGui_ImplOpenGL3_Init("#version 330");
}
void Showoff::GUI::deinit() {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void Showoff::GUI::beginDraw() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// ImGui code goes here
ImGui::Begin("Window");
ImGui::End();
}
void Showoff::GUI::endDraw() {
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
Showoff::Canvas::Canvas() {
mContext = new ShowoffCanvasContext();
}
Showoff::Canvas::~Canvas() {
delete mContext;
}
void Showoff::Canvas::init() {
mContext->vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
}
void Showoff::Canvas::deinit() {
// Cleanup
nvgDeleteGL3(mContext->vg);
}
void Showoff::Canvas::beginDraw() {
auto width = 600;
auto height = 600;
// Start NanoVG rendering
nvgBeginFrame(mContext->vg, width, height, 1.0);
// Draw a rectangle
nvgBeginPath(mContext->vg);
nvgRect(mContext->vg, 50, 50, 50, 50);
nvgFillColor(mContext->vg, nvgRGBf(0.8f, 0.4f, 0.1f));
nvgFill(mContext->vg);
// End NanoVG rendering
nvgEndFrame(mContext->vg);
}
void Showoff::Canvas::endDraw() {
// End NanoVG rendering
nvgEndFrame(mContext->vg);
}
void Showoff::init(Window* window) {
gl.init();
gui.init(window);
canvas.init();
}
void Showoff::deinit() {
canvas.deinit();
gui.deinit();
gl.deinit();
}
void Showoff::draw() {
gl.beginDraw();
canvas.beginDraw();
gui.beginDraw();
gl.endDraw();
canvas.endDraw();
gui.endDraw();
}
Window::Window(int width, int height, const char* title) {
mContext = new WindowContext();
// Create a window and OpenGL context
mContext->window = glfwCreateWindow(width, height, title, nullptr, nullptr);
if (!mContext->window) {
printf("Failed to create GLFW window\n");
return;
}
glfwMakeContextCurrent(mContext->window);
// Initialize GLEW
if (glewInit() != GLEW_OK) {
printf("Failed to initialize GLEW\n");
return;
}
showoff.init(this);
}
Window::~Window() {
showoff.deinit();
glfwDestroyWindow(mContext->window);
delete mContext;
}
Window* Window::createWindow(int width, int height, const char* title) {
static int count = 1;
if (!count) {
printf("Window class is a singleton\n");
return nullptr;
}
count--;
// Initialize GLFW
if (!glfwInit()) {
printf("Failed to initialize GLFW\n");
return nullptr;
}
// Set the GLFW error callback
glfwSetErrorCallback([] (int error, const char* description) {
printf("GLFW Error: %i %s\n", error, description);
});
return new Window(width, height, title);
}
void Window::destroyWindow(Window* window) {
delete window;
glfwTerminate();
}
void Window::renderLoop() {
while (!glfwWindowShouldClose(mContext->window)) {
showoff.draw();
// Swap buffers and poll events
glfwSwapBuffers(mContext->window);
glfwPollEvents();
}
}
WindowContext* Window::getContext() { return mContext; }

View file

@ -0,0 +1,150 @@
#include "Window.hpp"
// -------- OpenGL -------- //
#include <GL/glew.h>
#include "WindowContext.hpp"
#include <cstdio>
namespace tp {
class Graphics::GL::Context {
public:
// Showoff data
GLuint vao{};
GLuint vbo{};
GLfloat vertices[9] = {
-0.0f, -0.0f, 0.0f, // Left vertex
1.0f, 0.0f, 0.0f, // Right vertex
0.5f, 1.0f, 0.0f // Top vertex
};
};
}
using namespace tp;
Graphics::GL::GL() {
mContext = new Context();
}
Graphics::GL::~GL() {
delete mContext;
}
void Graphics::GL::init() {
// Create a Vertex Array Object (VAO)
glGenVertexArrays(1, &mContext->vao);
glBindVertexArray(mContext->vao);
// Create a Vertex Buffer Object (VBO)
glGenBuffers(1, &mContext->vbo);
glBindBuffer(GL_ARRAY_BUFFER, mContext->vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(mContext->vertices), mContext->vertices, GL_STATIC_DRAW);
// Set up vertex attributes
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*) nullptr);
glEnableVertexAttribArray(0);
}
void Graphics::GL::deinit() {
glDeleteBuffers(1, &mContext->vbo);
glDeleteVertexArrays(1, &mContext->vao);
}
void Graphics::GL::proc() {
glClear(GL_COLOR_BUFFER_BIT);
}
void Graphics::GL::draw() {
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void Graphics::init(Window* window) {
mGl.init();
mGui.init(window);
mCanvas.init();
}
void Graphics::deinit() {
mCanvas.deinit();
mGui.deinit();
mGl.deinit();
}
void Graphics::draw() {
mGl.proc();
mCanvas.proc();
mGui.proc();
mGl.draw();
mCanvas.draw();
mGui.draw();
}
Window::Window(int width, int height, const char* title) {
mContext = new Context();
// Create a window and OpenGL context
mContext->window = glfwCreateWindow(width, height, title, nullptr, nullptr);
if (!mContext->window) {
printf("Failed to create GLFW window\n");
return;
}
glfwMakeContextCurrent(mContext->window);
// Initialize GLEW
if (glewInit() != GLEW_OK) {
printf("Failed to initialize GLEW\n");
return;
}
mGraphics.init(this);
}
Window::~Window() {
mGraphics.deinit();
glfwDestroyWindow(mContext->window);
delete mContext;
}
Window* Window::createWindow(int width, int height, const char* title) {
static int count = 1;
if (!count) {
printf("Window class is a singleton\n");
return nullptr;
}
count--;
// Initialize GLFW
if (!glfwInit()) {
printf("Failed to initialize GLFW\n");
return nullptr;
}
// Set the GLFW error callback
glfwSetErrorCallback([] (int error, const char* description) {
printf("GLFW Error: %i %s\n", error, description);
});
return new Window(width, height, title);
}
void Window::destroyWindow(Window* window) {
delete window;
glfwTerminate();
}
void Window::renderLoop() {
while (!glfwWindowShouldClose(mContext->window)) {
mGraphics.draw();
// Swap buffers and poll events
glfwSwapBuffers(mContext->window);
glfwPollEvents();
}
}
auto Window::getContext() -> Context* { return mContext; }

View file

@ -0,0 +1,16 @@
#pragma once
// -------- Window Context -------- //
#include <GLFW/glfw3.h>
namespace tp {
class Window;
class Window::Context {
friend Graphics::GL;
friend Graphics::GUI;
friend Graphics::Canvas;
public:
GLFWwindow* window;
};
}

View file

@ -0,0 +1,53 @@
#pragma once
#include "GraphicsCommon.hpp"
namespace tp {
class AnimValue {
halnf mValPrev = 0;
halnf mVal = 0;
time_ms mTimeStart = 0;
halni mTimeAnim = 250;
static bool gInTransition;
private:
[[nodiscard]] halnf interpolate() const;
public:
AnimValue();
explicit AnimValue(halnf val);
[[nodiscard]] halnf prev() const { return mValPrev; }
void set(halnf val);
void setNoTransition(halnf);
void setAnimTime(halni time);
[[nodiscard]] halnf get() const;
[[nodiscard]] halnf getTarget() const;
[[nodiscard]] bool inTransition() const;
explicit operator halnf() const;
void operator=(halnf val);
};
class AnimRect : Rect<AnimValue> {
public:
AnimRect() {
set({ 0, 0, 0, 0 });
setAnimTime(450);
}
[[nodiscard]] RectF get() const;
[[nodiscard]] RectF getTarget() const;
void setNoTransition(RectF);
void set(const RectF&);
void setAnimTime(halni time_ms);
};
class AnimColor {
AnimRect mColor;
public:
[[nodiscard]] RGBA get() const;
void set(const RGBA&);
};
};

View file

@ -1,77 +1,76 @@
#include "Strings.hpp"
#pragma once
#include "GraphicsCommon.hpp"
namespace tp {
class ShowoffGlContext;
class ShowoffGUIContext;
class ShowoffCanvasContext;
class Window;
class WindowContext;
class Showoff {
class Graphics {
public:
class GL {
ShowoffGlContext* mContext;
public:
class Context;
Context* mContext;
private:
friend Graphics;
GL();
~GL();
void init();
void deinit();
static void beginDraw();
static void endDraw();
static void proc();
static void draw();
public:
// TODO : API
};
class GUI {
ShowoffGUIContext* mContext;
public:
class Context;
Context* mContext;
private:
friend Graphics;
GUI();
~GUI();
void init(Window* window);
void deinit();
void beginDraw();
void endDraw();
void proc();
void draw();
public:
// TODO : API
};
class Canvas {
ShowoffCanvasContext* mContext;
public:
class Context;
Context* mContext;
private:
friend Graphics;
Canvas();
~Canvas();
void init();
void deinit();
void beginDraw();
void endDraw();
};
void proc();
void draw();
public:
Showoff() = default;
// TODO : API
};
private:
friend Window;
Graphics() = default;
void init(Window* window);
void deinit();
void draw();
private:
GUI gui;
GL gl;
Canvas canvas;
};
class Window {
Window(int width, int height, const char* title);
~Window();
public:
static Window* createWindow(int width, int height, const char* title);
static void destroyWindow(Window* window);
public:
void renderLoop();
WindowContext* getContext();
private:
WindowContext* mContext;
Showoff showoff;
GUI mGui;
GL mGl;
Canvas mCanvas;
};
}

View file

@ -0,0 +1,10 @@
#pragma once
#include "Strings.hpp"
#include "Rect.hpp"
#include "Color.hpp"
#include "Timing.hpp"
namespace tp {
extern ModuleManifest gModuleGraphics;
}

View file

@ -0,0 +1,166 @@
#pragma once
namespace tp {
// basically copy of glfw keys
enum class Keycode {
/* Printable keys */
SPACE = 32,
APOSTROPHE = 39, /* ' */
COMMA = 44, /* , */
MINUS = 45, /* - */
PERIOD = 46, /* . */
SLASH = 0xBF, /* \ */
N0 = 48,
N1 = 49,
N2 = 50,
N3 = 51,
N4 = 52,
N5 = 53,
N6 = 54,
N7 = 55,
N8 = 56,
N9 = 57,
SEMICOLON = 59, /* ; */
EQUAL = 61, /* = */
A = 65,
B = 66,
C = 67,
D = 68,
E = 69,
F = 70,
G = 71,
H = 72,
I = 73,
J = 74,
K = 75,
L = 76,
M = 77,
N = 78,
O = 79,
P = 80,
Q = 81,
R = 82,
S = 83,
T = 84,
U = 85,
V = 86,
W = 87,
X = 88,
Y = 89,
Z = 90,
LEFT_BRACKET = 91, /* [ */
BACKSLASH = 92, /* \ */
RIGHT_BRACKET = 93, /* ] */
GRAVE_ACCENT = 96, /* ` */
WORLD_1 = 161, /* non-US #1 */
WORLD_2 = 162, /* non-US #2 */
/* function keys */
ESCAPE = 256,
ENTER = 257,
TAB = 258,
BACKSPACE = 259,
INSERT = 260,
DELETE = 261,
RIGHT = 262,
LEFT = 263,
DOWN = 264,
UP = 265,
PAGE_UP = 266,
PAGE_DOWN = 267,
HOME = 268,
END = 269,
CAPS_LOCK = 280,
SCROLL_LOCK = 281,
NUM_LOCK = 282,
PRINT_SCREEN = 283,
PAUSE = 284,
F1 = 290,
F2 = 291,
F3 = 292,
F4 = 293,
F5 = 294,
F6 = 295,
F7 = 296,
F8 = 297,
F9 = 298,
F10 = 299,
F11 = 300,
F12 = 301,
F13 = 302,
F14 = 303,
F15 = 304,
F16 = 305,
F17 = 306,
F18 = 307,
F19 = 308,
F20 = 309,
F21 = 310,
F22 = 311,
F23 = 312,
F24 = 313,
F25 = 314,
KP_0 = 320,
KP_1 = 321,
KP_2 = 322,
KP_3 = 323,
KP_4 = 324,
KP_5 = 325,
KP_6 = 326,
KP_7 = 327,
KP_8 = 328,
KP_9 = 329,
KP_DECIMAL = 330,
KP_DIVIDE = 331,
KP_MULTIPLY = 332,
KP_SUBTRACT = 333,
KP_ADD = 334,
KP_ENTER = 335,
KP_EQUAL = 336,
LEFT_SHIFT = 340,
LEFT_CONTROL = 341,
LEFT_ALT = 342,
LEFT_SUPER = 343,
RIGHT_SHIFT = 344,
RIGHT_CONTROL = 345,
RIGHT_ALT = 346,
RIGHT_SUPER = 347,
MENU = 348,
INV_SLASH = 0xDC,
BRA = 0xDB,
KET = 0xDD,
TILDA = 0xC0,
DOUBLE_DOT = 0xBA,
QUOTES = 0xDE,
MOUSE1 = 501,
MOUSE2 = 502,
MOUSE3 = 503,
MOUSE4 = 504,
MOUSE5 = 505,
MOUSE_UP = 506,
MOUSE_DOWN = 507,
};
enum class KeyState {
PRESSED,
RELEASED,
HOLD,
REPEAT,
NONE,
};
struct KeyEvent {
Keycode code;
enum class EventState {
RELEASED = 0,
PRESSED = 1,
REPEAT = 2,
} event_state;
};
};

View file

@ -0,0 +1,39 @@
#pragma once
#include "Graphics.hpp"
#include "Buffer.hpp"
#include "Keycodes.hpp"
namespace tp {
class Window {
class Context;
public:
struct Event {
enum Type {
KEY,
MOUSE,
};
};
private:
Window(int width, int height, const char* title);
~Window();
public:
static Window* createWindow(int width, int height, const char* title);
static void destroyWindow(Window* window);
public:
void renderLoop();
auto getContext() -> Context*;
private:
Context* mContext;
Graphics mGraphics;
Buffer<Event> mEvents;
};
}

27
TODO
View file

@ -1,24 +1,27 @@
Storage:
Implement
CommandLineParser:
Implement
Testing !
Serialization !
Objects:
Implement
Implement !
TextEditor:
Implement
Storage:
Finish networking
Enable preloads
Graphics:
Window event system
Graphics API
FPS count & Performance control
Utils:
Stack trace fixes
Containers:
Add variant size buffer
Buffer improvements
Add mem leakage tests
Add check copy times
AVL dont copy data just swap
Testing !
Serialization
TextEditor:
Implement