Merge pull request #15431 from s-hadinger/openhasp_optim

OpenHASP memory optimization
This commit is contained in:
s-hadinger 2022-04-22 22:49:31 +02:00 committed by GitHub
commit 05b890f631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 806 additions and 650 deletions

View File

@ -195,6 +195,9 @@ intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *buf
} else {
be_raisef(vm, "type_error", "Can't find callback generator: 'cb.make_cb'");
}
} else if (be_iscomptr(vm, idx)) {
// if it's a pointer, just pass it without any change
return (int32_t) be_tocomptr(vm, idx);;
} else {
be_raise(vm, "type_error", "Closure expected for callback type");
}

File diff suppressed because it is too large Load Diff

View File

@ -186,7 +186,7 @@ const be_ntv_func_def_t lv_disp_func[] = {
/* `lv_obj` methods */
const be_ntv_func_def_t lv_obj_func[] = {
{ "add_event_cb", { (const void*) &lv_obj_add_event_cb, "i", "(lv.lv_obj)^lv_event_cb^i." } },
{ "add_event_cb", { (const void*) &lv_obj_add_event_cb, "c", "(lv.lv_obj)^lv_event_cb^i." } },
{ "add_flag", { (const void*) &lv_obj_add_flag, "", "(lv.lv_obj)i" } },
{ "add_state", { (const void*) &lv_obj_add_state, "", "(lv.lv_obj)i" } },
{ "add_style", { (const void*) &lv_obj_add_style, "", "(lv.lv_obj)(lv.lv_style)i" } },
@ -387,7 +387,7 @@ const be_ntv_func_def_t lv_obj_func[] = {
{ "refresh_style", { (const void*) &lv_obj_refresh_style, "", "(lv.lv_obj)ii" } },
{ "remove_event_cb", { (const void*) &lv_obj_remove_event_cb, "b", "(lv.lv_obj)." } },
{ "remove_event_cb_with_user_data", { (const void*) &lv_obj_remove_event_cb_with_user_data, "b", "(lv.lv_obj).." } },
{ "remove_event_dsc", { (const void*) &lv_obj_remove_event_dsc, "b", "(lv.lv_obj)i" } },
{ "remove_event_dsc", { (const void*) &lv_obj_remove_event_dsc, "b", "(lv.lv_obj)c" } },
{ "remove_local_style_prop", { (const void*) &lv_obj_remove_local_style_prop, "b", "(lv.lv_obj)ii" } },
{ "remove_style", { (const void*) &lv_obj_remove_style, "", "(lv.lv_obj)(lv.lv_style)i" } },
{ "remove_style_all", { (const void*) &lv_obj_remove_style_all, "", "(lv.lv_obj)" } },

View File

@ -110,7 +110,7 @@ return_types = {
"lv_flex_flow_t": "i",
"lv_grid_align_t": "i",
"_lv_event_dsc_t *": "i",
"_lv_event_dsc_t *": "c",
# lv_anim
"lv_anim_t *": "lv_anim",
"lv_anim_enable_t": "i",

View File

@ -287,20 +287,13 @@ class lvh_obj
lv.EVENT_VALUE_CHANGED: "changed",
}
def register_event_cb()
# register callback for each event
var f = / obj, event -> self.event_cb(obj, event)
var oh = self._page._oh
for ev:self._event_map.keys()
self._lv_obj.add_event_cb(f, ev, 0)
oh.register_event(self, ev)
end
# # print("register_event_cb")
# var mask = lv.EVENT_PRESSED | lv.EVENT_CLICKED | lv.EVENT_PRESS_LOST | lv.EVENT_RELEASED |
# lv.EVENT_LONG_PRESSED | lv.EVENT_LONG_PRESSED_REPEAT | lv.EVENT_VALUE_CHANGED
# var target = self
# mask = lv.EVENT_CLICKED
# self._lv_obj.add_event_cb(/ obj, event -> target.event_cb(obj, event), mask, 0)
end
def event_cb(obj, event)
def event_cb(event)
# the callback avoids doing anything sophisticated in the cb
# defer the actual action to the Tasmota event loop
# print("-> CB fired","self",self,"obj",obj,"event",event.tomap(),"code",event.code)
@ -314,24 +307,11 @@ class lvh_obj
var event_hasp = self._event_map.find(code)
if event_hasp != nil
import string
var val = string.format('{"hasp":{"p%ib%i":"%s"}}', self._page._page_id, self.id, event_hasp)
# var pxby = "p" + self._page._page_id + "b" + self.id
# var val = '{"hasp":{"p' + str(self._page._page_id) + 'b' + str(self.id) +
# '":"' + event_hasp + '"}}'
# var val = json.dump( {'hasp': {pxby: event_hasp}} )
# print("val=",val)
tasmota.set_timer(0, /-> tasmota.publish_rule(val))
end
end
# def action_cb(obj, event)
# # the callback avoids doing anything sophisticated in the cb
# # defer the actual action to the Tasmota event loop
# # print("-> CB fired","self",self,"obj",obj,"event",event.tomap(),"code",event.code)
# var oh = self._page._oh # openhasp global object
# var code = event.code # materialize to a local variable, otherwise the value can change (and don't capture event object)
# tasmota.set_timer(0, /-> oh.do_action(self, code))
# end
#====================================================================
# Mapping of synthetic attributes
@ -1108,6 +1088,9 @@ class OpenHASP
var lvh_page_cur_idx # (int) current page index number
# regex patterns
var re_page_target # compiled regex for action `p<number>`
# specific event_cb handling for less memory usage since we are registering a lot of callbacks
var event # try to keep the event object around and reuse it
var event_cb # the low-level callback for the closure to be registered
# assign lvh_page to a static attribute
static lvh_page = lvh_page
@ -1236,19 +1219,26 @@ class OpenHASP
self.lvh_pages[1] = lvh_page_class(1, self) # always create page #1
var f = open(templ_name,"r")
var jsonl = string.split(f.read(), "\n")
var f_content = f.read()
f.close()
var jsonl = string.split(f_content, "\n")
f = nil # allow deallocation
f_content = nil
# parse each line
for j:jsonl
var jline = json.load(j)
while size(jsonl) > 0
var jline = json.load(jsonl[0])
if type(jline) == 'instance'
self.parse_page(jline) # parse page first to create any page related objects, may change self.lvh_page_cur_idx
# objects are created in the current page
self.parse_obj(jline, self.lvh_pages[self.lvh_page_cur_idx]) # then parse object within this page
end
jline = nil
jsonl.remove(0)
end
jsonl = nil # make all of it freeable
# current page is always 1 when we start
self.lvh_page_cur_idx = 1
@ -1404,6 +1394,42 @@ class OpenHASP
end
end
#====================================================================
# Event CB handling
#====================================================================
def register_event(lvh_obj, event_type)
import cb
import introspect
# create the callback to the closure only once
if self.event_cb == nil
self.event_cb = cb.gen_cb(/ event_ptr_i -> self.event_dispatch(event_ptr_i))
end
# register the C callback
var lv_obj = lvh_obj._lv_obj
# we pass the cb as a comptr so it's already a C pointer
lv_obj.add_event_cb(self.event_cb, event_type, introspect.toptr(lvh_obj))
end
def event_dispatch(event_ptr_i)
import introspect
var event_ptr = introspect.toptr(event_ptr_i) # convert to comptr, because it was a pointer in the first place
if self.event self.event._change_buffer(event_ptr)
else self.event = lv.lv_event(event_ptr)
end
var user_data = self.event.user_data # it is supposed to be a pointer to the object
if int(user_data) != 0
var target_lvh_obj = introspect.fromptr(user_data)
if type(target_lvh_obj) == 'instance'
# print("CB Fired", self.event.code, target_lvh_obj)
target_lvh_obj.event_cb(self.event)
# print("CB Fired After")
end
end
end
#====================================================================
# Parse single object
#====================================================================