0xc3 1 月之前
父節點
當前提交
0ca875d026

+ 70 - 5
src/saura/cmd/sandbox/sandbox.cpp

@@ -1,5 +1,6 @@
 #include <cstring>
 #include <fmt/format.h>
+#include <memory>
 #include <saura/core/app_base/app_base.hpp>
 
 #include <spdlog/spdlog.h>
@@ -11,6 +12,8 @@
 #include "saura/cmd/sandbox/client/client.hpp"
 #include "saura/cmd/sandbox/folder/folder.hpp"
 #include "saura/cmd/sandbox/user/user.hpp"
+#include "saura/core/base/types.hpp"
+#include "saura/core/memory/arena.hpp"
 #include "server/server.hpp"
 
 namespace saura {
@@ -23,10 +26,15 @@ struct SandboxApp : AppBase {
   std::vector<ClientInfo> clients;
   std::vector<UserInfo> users;
   Folder category_root;
+  std::unique_ptr<MemoryArena> default_memory_arena;
 
   void start() override {
     spdlog::info("Sandbox start!");
 
+    // TODO: FIX FATAL
+    this->default_memory_arena =
+        std::make_unique<MemoryArena>(MemoryArena(Megabytes(256)));
+
     this->server_api_ctx = std::make_shared<ServerAPI>();
     this->clients = server_api_ctx->fetch_clients(10, 0);
     this->users = server_api_ctx->fetch_users(10, 0);
@@ -206,13 +214,60 @@ struct SandboxApp : AppBase {
         }
 
         if (ImGui::Button("Создать клиента")) {
-          ImGui::OpenPopup("Test");
+          ImGui::OpenPopup("CreateClientPopup");
         }
 
-        if (ImGui::BeginPopupModal("Test", NULL,
+        if (ImGui::BeginPopupModal("CreateClientPopup", NULL,
                                    ImGuiWindowFlags_AlwaysAutoResize)) {
-          ImGui::Text("This is the modal content!");
-          ImGui::Separator();
+          // Тип
+          {
+            static const char *items[] = {"Вариант 1", "Вариант 2",
+                                          "Вариант 3"};
+            static int current_item = 0;
+
+            if (ImGui::BeginCombo("Тип", items[current_item])) {
+              for (int n = 0; n < IM_ARRAYSIZE(items); n++) {
+                bool is_selected = (current_item == n);
+
+                if (ImGui::Selectable(items[n], is_selected)) {
+                  current_item = n;
+                }
+
+                if (is_selected) {
+                  ImGui::SetItemDefaultFocus();
+                }
+              }
+              ImGui::EndCombo();
+            }
+          }
+
+          // Теги
+          {
+            static const char *items[] = {"Вариант 1", "Вариант 2",
+                                          "Вариант 3"};
+            static int current_item = 0;
+
+            if (ImGui::BeginCombo("Теги", items[current_item])) {
+              for (int n = 0; n < IM_ARRAYSIZE(items); n++) {
+                bool is_selected = (current_item == n);
+
+                if (ImGui::Selectable(items[n], is_selected)) {
+                  current_item = n;
+                }
+
+                if (is_selected) {
+                  ImGui::SetItemDefaultFocus();
+                }
+              }
+              ImGui::EndCombo();
+            }
+          }
+
+          // ФИО
+          {
+            uint8_t *buf = this->default_memory_arena->push_zero(1024);
+            ImGui::InputText("ФИО", (char *)buf, sizeof(buf));
+          }
 
           if (ImGui::Button("Close", ImVec2(120, 0))) {
             ImGui::CloseCurrentPopup();
@@ -282,7 +337,9 @@ struct SandboxApp : AppBase {
             ImGui::TableNextColumn();
             ImGui::PushID(fmt::format("{}Delete", idx).c_str());
             if (ImGui::Button("Delete")) {
-              if (server_api_ctx->send_delete(fmt::format("http://api.localhost:8090/v1/example/client?id={}", client.id))) {
+              if (server_api_ctx->send_delete(fmt::format(
+                      "http://api.localhost:8090/v1/example/client?id={}",
+                      client.id))) {
                 if (idx < clients.size()) {
                   clients.erase(clients.begin() + idx);
                 }
@@ -295,6 +352,9 @@ struct SandboxApp : AppBase {
         }
         ImGui::EndTabItem();
       }
+      if (ImGui::IsItemActivated()) {
+        this->clients = server_api_ctx->fetch_clients(10, 0);
+      }
 
       if (ImGui::BeginTabItem("Пользователи")) {
         ImGuiTableFlags flags =
@@ -377,6 +437,9 @@ struct SandboxApp : AppBase {
         }
         ImGui::EndTabItem();
       }
+      if (ImGui::IsItemActivated()) {
+        this->users = server_api_ctx->fetch_users(10, 0);
+      }
 
       if (ImGui::BeginTabItem("Настройки")) {
         ImGui::Text("Hello");
@@ -389,6 +452,8 @@ struct SandboxApp : AppBase {
     ImGui::End();
 
     ImGui::ShowDemoWindow();
+
+    this->default_memory_arena->clear();
   }
 
   void stop() override { spdlog::info("Sandbox stop!"); }

+ 1 - 0
src/saura/core/app_base/app_base.hpp

@@ -12,6 +12,7 @@ extern AppBase *g_app_base_instance;
 
 struct AppBase {
   virtual ~AppBase() = default;
+
   virtual void start() {}
   virtual void update(double dt) {}
   virtual void stop() {}

+ 12 - 0
src/saura/core/base/types.hpp

@@ -0,0 +1,12 @@
+#ifndef SAURA_BASE_TYPES_HPP_
+#define SAURA_BASE_TYPES_HPP_
+
+#include <cstdint>
+
+#define Bytes(value) (value)
+#define Kilobytes(value) (value << 10)
+#define Megabytes(value) (value << 20)
+#define Gigabytes(value) ((uint64_t)(value) << 30)
+#define Terabytes(value) ((uint64_t)(value) << 40)
+
+#endif

+ 72 - 0
src/saura/core/memory/arena.cpp

@@ -0,0 +1,72 @@
+#include "arena.hpp"
+
+#include <spdlog/spdlog.h>
+
+#include <SDL3/SDL_stdinc.h>
+
+namespace saura {
+MemoryArena::MemoryArena() {
+  this->data = (uint8_t *)SDL_malloc(DEFAULT_ARENA_SIZE);
+  this->size = DEFAULT_ARENA_SIZE;
+  this->offset = 0;
+}
+
+MemoryArena::MemoryArena(uint64_t size) {
+  this->data = (uint8_t *)SDL_malloc(size);
+  this->size = size;
+  this->offset = 0;
+}
+
+MemoryArena::~MemoryArena() { std::free(this->data); }
+
+uint8_t *MemoryArena::push(uint64_t size) {
+  if (this->offset + size > this->size) {
+    spdlog::critical("Handle out-of-memory");
+  }
+  uint8_t *pos = (uint8_t *)this->data + this->offset;
+  this->offset += size;
+  return pos;
+}
+
+uint8_t *MemoryArena::push_zero(uint64_t size) {
+  uint8_t *memory = this->push(size);
+  if (memory == 0) {
+    return 0;
+  }
+  std::memset(memory, 0, size);
+  return memory;
+}
+
+uint8_t *MemoryArena::pop(uint64_t size) {
+  if (this->offset == 0) {
+    spdlog::critical("Handle out-of-memory");
+  }
+  this->offset -= size;
+  uint8_t *pos = (uint8_t *)this->offset - size;
+  return pos;
+}
+
+void MemoryArena::clear() { this->offset = 0; }
+
+uint64_t MemoryArena::get_offset() { return this->offset; }
+
+MemoryArenaTemp MemoryArenaTemp::begin(MemoryArena *arena) {
+  MemoryArenaTemp result;
+  std::memset(&result, 0, sizeof(result));
+  result.arena = arena;
+  result.offset = arena->offset;
+  return result;
+}
+
+void MemoryArenaTemp::end(MemoryArenaTemp temp) {
+  temp.arena->offset = temp.offset;
+}
+
+MemoryArenaTemp MemoryArenaTemp::get_scratch(MemoryArena *arena) {
+  MemoryArenaTemp temp;
+  std::memset(&temp, 0, sizeof(temp));
+  temp.arena = arena;
+  temp.offset = arena->offset;
+  return temp;
+}
+} // namespace saura

+ 57 - 0
src/saura/core/memory/arena.hpp

@@ -0,0 +1,57 @@
+#ifndef SAURA_MEMORY_ARENA_HPP_
+#define SAURA_MEMORY_ARENA_HPP_
+
+#include "saura/core/base/types.hpp"
+
+/*
+ - Permanent Allocation
+ - Transient Allocation
+ - Scratch/Temporary Allocation
+*/
+
+#define DEFAULT_ARENA_SIZE Gigabytes(4)
+#define DEFAULT_ALIGNMENT (8 * sizeof(void *))
+
+namespace saura {
+class MemoryArena {
+ public:
+  uint8_t *data;
+  uint64_t size;
+  uint64_t offset;
+
+public:
+  MemoryArena();
+  MemoryArena(uint64_t size);
+  ~MemoryArena();
+
+  uint8_t *push(uint64_t size);
+  uint8_t *push_zero(uint64_t size);
+  uint8_t *pop(uint64_t size);
+  void clear();
+  uint64_t get_offset();
+};
+
+// Helpers
+
+// #define push_array(arena, type, count) \
+//   (type *)arena_push(arena, sizeof(type) * count)
+// #define push_array_zero(arena, type, count) \
+//   (type *)arena_push_zero(arena, sizeof(type) * count)
+// #define push_struct(arena, type) (type *)push_array(arena, type, 1)
+// #define push_struct_zero(arena, type) (type *)push_array_zero(arena, type, 1)
+// #define pop_array(arena, type, count) \
+//   (type *)arena_pop(arena, sizeof(type) * count)
+
+class MemoryArenaTemp {
+ public:
+  MemoryArena *arena;
+  uint64_t offset;
+
+public:
+  MemoryArenaTemp begin(MemoryArena *arena);
+  void end(MemoryArenaTemp temp);
+  MemoryArenaTemp get_scratch(MemoryArena *arena);
+};
+} // namespace saura
+
+#endif