/
d.vision
/
division_engine_cpp
Обзор
Документация
Войти
/
d.vision
/
division_engine_cpp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
resources/scripts/division.lua
328 строк
10 KB
den163
Fixed double texture deleting
05 дек 2024, 02:28
05 дек 2024, 02:28
08d53e2
Код
Авторство
О чём код?
local Color = require "color" local ffi = require "ffi" local BorderRadius = require "border_radius" require "rect" require "vec4" ffi.cdef [[ typedef uint64_t id_t; typedef uint32_t texture_id_t; typedef struct { vec4_t color; border_radius_t border_radius; } renderable_rect_t; typedef struct { const char* text; vec4_t color; float font_size; } renderable_text_t; id_t division_ffi_create_drawable_rect(void* state, void* render_manager, id_t batch_id); id_t division_ffi_create_drawable_text(void* state, void* render_manager); id_t division_ffi_create_selectable(void* state, void* render_manager); void division_ffi_destroy_entity(void* state, id_t entity_id); void division_ffi_set_RenderBounds(void* state, id_t entity_id, rect_t bounds); void division_ffi_set_CollisionRect(void* state, id_t entity_id, rect_t bounds); void division_ffi_set_RenderableRect( void* state, id_t entity_id, renderable_rect_t renderable_rect); void division_ffi_set_c_renderable_text( void* state, id_t entity_id, renderable_text_t renderable_text); rect_t division_ffi_get_TextBounds(void* state, id_t entity_id); vec2_t division_ffi_get_screen_size(void* state); vec2_t division_ffi_get_mouse_position(void* state); bool division_ffi_is_mouse_button_pressed(void* state, int button); bool division_ffi_has_selected_id(void* state); id_t division_ffi_get_selected_id(void* state); void division_ffi_add_tag_Selectable(void* state, id_t entity_id); void division_ffi_remove_tag_Selectable(void* state, id_t entity_id); texture_id_t division_ffi_create_texture(void* state, const char* texture_path); id_t division_ffi_create_texture_batch(void* state, texture_id_t texture_id); void division_ffi_destroy_texture(void* state, texture_id_t texture_id); id_t division_ffi_get_white_texture_batch_id(void* state); ]] local renderable_rect_t = ffi.typeof('renderable_rect_t') local renderable_text_t = ffi.typeof('renderable_text_t') ---@class division local division = { ---@enum division.mouse_button mouse_button = { left = 0, right = 1, middle = 2 }, ---@package __render_manager__ = __RENDER_MANAGER__, ---@package __state__ = __ENGINE_STATE__, ---@package __destroy_listeners__ = {}, ---@package __update_listeners__ = {}, ---@package __select_listeners__ = {}, ---@package __delayed_until_update_queue__ = {}, ---@package __textures__ = {} } ---@class entity_id ---Draw rect with render manager ---@param selectable boolean? true by default ---@param texture_path string? ---@return entity_id # drawable ecs entity id function division:create_drawable_rect(selectable, texture_path) local batch_id if texture_path then local texture = division.__textures__[texture_path] if not texture then local c_tex = ffi.C.division_ffi_create_texture(self.__state__, texture_path) texture = { c_texture = c_tex, batch_id = ffi.C.division_ffi_create_texture_batch(self.__state__, c_tex) } division.__textures__[texture_path] = texture end batch_id = texture.batch_id else batch_id = ffi.C.division_ffi_get_white_texture_batch_id(self.__state__) end local entity_id = ffi.C.division_ffi_create_drawable_rect( self.__state__, self.__render_manager__, batch_id ) if selectable == nil or selectable == true then ffi.C.division_ffi_add_tag_Selectable(self.__state__, entity_id) end return entity_id end ---Draw text with render manager ---@param selectable boolean? true by default ---@return entity_id # drawable ecs entity id function division:create_drawable_text(selectable) local entity_id = ffi.C.division_ffi_create_drawable_text( self.__state__, self.__render_manager__ ) if selectable == nil or selectable == true then ffi.C.division_ffi_add_tag_Selectable(self.__state__, entity_id) end return entity_id end ---Create entity that could be selected ---@return entity_id # selectable ecs entity id function division:create_selectable() return ffi.C.division_ffi_create_selectable(self.__state__, self.__render_manager__) end ---Set rect parameters ---@param entity_id entity_id ---@param bounds rect? ---@param color vec4? ---@param border_radius border_radius? function division:set_drawable_rect(entity_id, bounds, color, border_radius) ffi.C.division_ffi_set_RenderBounds(self.__state__, entity_id, bounds) ffi.C.division_ffi_set_CollisionRect(self.__state__, entity_id, bounds) ffi.C.division_ffi_set_RenderableRect( self.__state__, entity_id, ffi.new( renderable_rect_t, { color = color or Color.BLACK, border_radius = border_radius or BorderRadius.all(0) } ) ) end ---Set drawable text parameters ---@param entity_id entity_id ---@param text string? ---@param bounds rect? ---@param color vec4? ---@param font_size number? function division:set_drawable_text(entity_id, text, bounds, color, font_size) ffi.C.division_ffi_set_RenderBounds(self.__state__, entity_id, bounds) ffi.C.division_ffi_set_CollisionRect(self.__state__, entity_id, bounds) ffi.C.division_ffi_set_c_renderable_text( self.__state__, entity_id, ffi.new( renderable_text_t, { text = text or "", color = color or Color.BLACK, font_size = font_size or 16 } ) ) end ---@param entity_id entity_id ---@return rect function division:get_text_bounds(entity_id) return ffi.C.division_ffi_get_TextBounds(self.__state__, entity_id); end ---Set collision parameters ---@param entity_id entity_id ---@param bounds rect? function division:set_collision_bounds(entity_id, bounds) ffi.C.division_ffi_set_CollisionRect(self.__state__, entity_id, bounds) end function division:screen_size() return ffi.C.division_ffi_get_screen_size(self.__state__) end function division:mouse_position() return ffi.C.division_ffi_get_mouse_position(self.__state__) end ---@param button division.mouse_button | number ---@return boolean function division:is_mouse_button_pressed(button) return ffi.C.division_ffi_is_mouse_button_pressed(self.__state__, button) end ---@return boolean function division:has_selected_id() return ffi.C.division_ffi_has_selected_id(self.__state__) end ---@return entity_id function division:get_selected_id() return ffi.C.division_ffi_get_selected_id(self.__state__) end function division:get_selected_id_safe() assert(self:has_selected_id(), "No entity selected") return self:get_selected_id() end ---@param entity_id entity_id ---@param is_selectable boolean function division:set_entity_selectable(entity_id, is_selectable) if is_selectable then ffi.C.division_ffi_add_tag_Selectable(self.__state__, entity_id) else ffi.C.division_ffi_remove_tag_Selectable(self.__state__, entity_id) end end --Destroy ecs entity ---@param entity_id entity_id function division:destroy_entity(entity_id) ffi.C.division_ffi_destroy_entity(self.__state__, entity_id) end ---@private function division:__on_destroy__() for _, listener in ipairs(self.__destroy_listeners__) do listener() end for _, tex in pairs(self.__textures__) do ffi.C.division_ffi_destroy_texture(self.__state__, tex.c_texture) ffi.C.division_ffi_destroy_entity(self.__state__, tex.batch_id) end self.__textures__ = {} end ---@private function division:__on_update__() for i = 1, #self.__delayed_until_update_queue__ do self.__delayed_until_update_queue__[i]() end self.__delayed_until_update_queue__ = {} for _, listener in ipairs(self.__update_listeners__) do listener() end end ---@param listener function function division:add_destroy_listener(listener) table.insert(self.__destroy_listeners__, listener) end ---@param listener function function division:add_update_listener(listener) table.insert(self.__update_listeners__, listener) end ---@param func function function division:delay_until_update(func) table.insert(self.__delayed_until_update_queue__, func) end ---@param listener function function division:remove_update_listener(listener) for i, l in ipairs(self.__update_listeners__) do if l == listener then table.remove(self.__update_listeners__, i) break end end end ---@param id entity_id selected entity id ---@param listener function function division:add_select_callback(id, listener) self.__select_listeners__[tostring(id)] = listener end ---@param id entity_id selected entity id function division:remove_select_callback(id) self.__select_listeners__[tostring(id)] = nil end __ON_DESTROY__ = function() division:__on_destroy__() end local mouse_was_pressed = false __ON_UPDATE__ = function() local is_mouse_down = false local is_left_button_pressed = division:is_mouse_button_pressed( division.mouse_button.left ) if is_left_button_pressed and not mouse_was_pressed then is_mouse_down = true mouse_was_pressed = true elseif not is_left_button_pressed then mouse_was_pressed = false end if is_mouse_down and division:has_selected_id() then local key = tostring(division:get_selected_id()) if division.__select_listeners__[key] then division.__select_listeners__[key]() end end division:__on_update__() end return division