bugs and perfomance cleanup.
This commit is contained in:
+10
-4
@@ -39,9 +39,7 @@ struct Element {
|
||||
struct EImage : Element {
|
||||
uint64_t animation_id = UINT64_MAX;
|
||||
|
||||
EImage(uint64_t animation_id) : Element(Type::IMAGE), animation_id(animation_id) {
|
||||
animation_pool.use(animation_id);
|
||||
}
|
||||
EImage(uint64_t animation_id) : Element(Type::IMAGE), animation_id(animation_id) {}
|
||||
|
||||
~EImage() {
|
||||
if (animation_id != UINT64_MAX)
|
||||
@@ -86,6 +84,13 @@ struct EText : Element {
|
||||
return window.get_text_size(text_id);
|
||||
}
|
||||
|
||||
void reload_text() {
|
||||
if (text_id != UINT64_MAX) {
|
||||
text_pool.release(text_id);
|
||||
text_id = UINT64_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void render(Window &window, uint64_t) override {
|
||||
if (
|
||||
last_language != Localization::current_language
|
||||
@@ -93,13 +98,14 @@ struct EText : Element {
|
||||
|| last_color != color
|
||||
|| params_changed
|
||||
) {
|
||||
std::string localized_str = Localization::get(Ruby::mrb, key, params);
|
||||
std::string localized_str = Localization::get(key, params);
|
||||
if (text_id != UINT64_MAX)
|
||||
text_pool.release(text_id);
|
||||
text_id = window.create_text(font_id, localized_str.c_str(), localized_str.size(), color);
|
||||
last_language = Localization::current_language;
|
||||
last_key = key;
|
||||
last_color = color;
|
||||
params_changed = false;
|
||||
}
|
||||
window.write(text_id, position, z, rotation, pivot, scale, alpha);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ static mrb_value params_set(mrb_state *mrb, mrb_value self) {
|
||||
app::EText *element = (app::EText *)app::element_pool[id];
|
||||
|
||||
element->params[mrb_sym2name(mrb, key)] = mrb_str_to_cstr(mrb, mrb_obj_as_string(mrb, value));
|
||||
element->reload_text();
|
||||
|
||||
return mrb_nil_value();
|
||||
}
|
||||
@@ -509,7 +510,7 @@ static mrb_value element_text_inspect(mrb_state *mrb, mrb_value self) {
|
||||
static mrb_value element_text_to_s(mrb_state *mrb, mrb_value self) {
|
||||
uint64_t id = get_id_ElementText(mrb, self);
|
||||
app::EText *element = (app::EText *)app::element_pool[id];
|
||||
std::string localized_text = Localization::get(Ruby::mrb, element->key, element->params);
|
||||
std::string localized_text = Localization::get(element->key, element->params);
|
||||
return mrb_str_new_cstr(mrb, localized_text.c_str());
|
||||
}
|
||||
|
||||
@@ -1173,6 +1174,7 @@ static mrb_value ElementImage_init(mrb_state *mrb, mrb_value self) {
|
||||
}
|
||||
|
||||
uint64_t id = get_id_Animation(mrb, animation_val);
|
||||
animation_pool.use(id);
|
||||
|
||||
app::EImage *element = new app::EImage(id);
|
||||
element->position = {x, y};
|
||||
@@ -1572,7 +1574,7 @@ static mrb_value scene_elements_at(mrb_state *mrb, mrb_value self) {
|
||||
mrb_value position_val;
|
||||
mrb_get_args(mrb, "o", &position_val);
|
||||
|
||||
float x, y;
|
||||
float x = 0, y = 0;
|
||||
HASH_FLOAT(position_val, x, x);
|
||||
HASH_FLOAT(position_val, y, y);
|
||||
Vec2<float> position = {x, y};
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
out = mrb_float(v); \
|
||||
else if (mrb_fixnum_p(v)) \
|
||||
out = (float)mrb_fixnum(v); \
|
||||
else \
|
||||
out = 0; \
|
||||
} while (0)
|
||||
|
||||
#define HASH_BOOL(h, key, out) \
|
||||
|
||||
@@ -71,7 +71,7 @@ inline void set(LanguageCode lang_code, Key key, const std::string &text) {
|
||||
localized_strings[join_keys(lang_code, key)] = parse_localized(text);
|
||||
}
|
||||
|
||||
inline std::string get(mrb_state *mrb, Key key, const std::unordered_map<std::string, std::string> ¶ms) {
|
||||
inline std::string get(Key key, const std::unordered_map<std::string, std::string> ¶ms) {
|
||||
auto it = localized_strings.find(join_keys(current_language, key));
|
||||
if (it == localized_strings.end())
|
||||
return "Localization not set!";
|
||||
|
||||
+5
-1
@@ -163,6 +163,10 @@ struct Rect {
|
||||
|
||||
template <typename T = void *>
|
||||
struct Pool {
|
||||
uint32_t size() const {
|
||||
return slots.size() - free_indices.size();
|
||||
}
|
||||
|
||||
T *operator[](uint64_t index) {
|
||||
if (!is_valid(index)) {
|
||||
fprintf(stderr, "Invalid pool index: %lu\n", (uint64_t)index);
|
||||
@@ -191,7 +195,7 @@ struct Pool {
|
||||
slots.push_back({});
|
||||
}
|
||||
slots[id].ptr = item;
|
||||
slots[id].refcount = 1;
|
||||
slots[id].refcount = 0;
|
||||
slots[id].alive = true;
|
||||
slots[id].generation++;
|
||||
uint64_t index = ((uint64_t)slots[id].generation << 32) | id;
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
App.run 720, 480, "Stress Test", fps: 120
|
||||
|
||||
scene = Scene.new
|
||||
|
||||
font = Font.new "assets/fonts/charybdis.ttf", 24, pixel_art: true
|
||||
|
||||
# primary factor in slowing teh system down is number of gpu textures
|
||||
# i.e if we increase images or unique texts, we will see a significant drop in fps,
|
||||
# but if we just increase number of elements with same image, the engine should be able to handle it much better
|
||||
|
||||
# --- Generate images ---
|
||||
images = []
|
||||
1.times do |i|
|
||||
images << Image.new("assets/images/menu_bg.png", pixel_art: true)
|
||||
end
|
||||
|
||||
# --- Animation pool stress ---
|
||||
animations = []
|
||||
1.times do |i|
|
||||
anim = Animation.new(images.sample(5), fps: 5 + (i % 30))
|
||||
animations << anim
|
||||
end
|
||||
|
||||
# --- Massive element pool ---
|
||||
elements = []
|
||||
|
||||
App.language = :en
|
||||
|
||||
App.localize(:en, :btn_text, "Stress Test %{count}")
|
||||
|
||||
App.localize(:en, :text, "Random Text")
|
||||
|
||||
1.times do |i|
|
||||
elements << ElementText.new(
|
||||
:text,
|
||||
font,
|
||||
rand(0xFFFFFF),
|
||||
{},
|
||||
position: { x: rand(0..700), y: rand(0..450) },
|
||||
z: rand(-10..10),
|
||||
click_mode: :pass,
|
||||
alpha: rand
|
||||
)
|
||||
end
|
||||
|
||||
500.times do |i|
|
||||
elements << ElementImage.new(
|
||||
animations.sample,
|
||||
position: { x: rand(0..700), y: rand(0..450) },
|
||||
z: rand(-10..10),
|
||||
alpha: rand,
|
||||
scale: { x: rand * 2, y: rand * 2 },
|
||||
click_mode: :pass
|
||||
)
|
||||
end
|
||||
|
||||
500.times do |i|
|
||||
elements << ElementRect.new(
|
||||
20 + rand(100),
|
||||
20 + rand(100),
|
||||
rand(0xFFFFFF),
|
||||
position: { x: rand(0..700), y: rand(0..450) },
|
||||
z: rand(-10..10),
|
||||
rotation: rand(360),
|
||||
alpha: rand,
|
||||
click_mode: :pass
|
||||
)
|
||||
end
|
||||
|
||||
text = ElementText.new(
|
||||
:btn_text,
|
||||
font,
|
||||
0xFF0000,
|
||||
{ count: 0 },
|
||||
position: { x: 20, y: 20 },
|
||||
z: 100,
|
||||
click_mode: :block
|
||||
)
|
||||
|
||||
scene << text
|
||||
elements.each { |e| scene << e }
|
||||
|
||||
# --- FPS thrashing test ---
|
||||
fps_values = [30, 60, 120, 240]
|
||||
|
||||
i = 0
|
||||
click_counter = 0
|
||||
|
||||
text.click do
|
||||
click_counter += 1
|
||||
text.params[:count] = click_counter
|
||||
end
|
||||
|
||||
start_time ||= Time.now
|
||||
frame_count ||= 0
|
||||
accum_dt ||= 0.0
|
||||
last_log ||= 0.0
|
||||
|
||||
App.update do |dt|
|
||||
frame_count += 1
|
||||
accum_dt += dt
|
||||
|
||||
now = Time.now
|
||||
elapsed = now - start_time
|
||||
|
||||
# log every second
|
||||
if elapsed - last_log >= 1.0
|
||||
dt_fps = frame_count / accum_dt
|
||||
real_fps = frame_count / elapsed
|
||||
|
||||
puts "---- FPS REPORT ----"
|
||||
puts "Engine FPS (dt): #{dt_fps.round(2)}"
|
||||
puts "Real FPS (wall): #{real_fps.round(2)}"
|
||||
puts "Avg dt: #{(accum_dt / frame_count * 1000).round(3)} ms"
|
||||
puts "Frame count: #{frame_count}"
|
||||
puts "--------------------"
|
||||
|
||||
last_log = elapsed
|
||||
end
|
||||
|
||||
i += 1
|
||||
|
||||
# --- Input spam check ---
|
||||
if App.pressed?(:mouse_left)
|
||||
puts "Mouse pressed at #{App.mouse_position}"
|
||||
end
|
||||
end
|
||||
|
||||
App.start scene
|
||||
Reference in New Issue
Block a user