1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 12:42:30 +04:00

ofw pr 4285 ViewStack: Store View by value to save memory

by CookiePLMonster
This commit is contained in:
MX
2025-10-12 03:34:40 +03:00
parent de35de4e58
commit fc34205f97
3 changed files with 32 additions and 28 deletions

View File

@@ -2,7 +2,7 @@
View* view_alloc(void) {
View* view = malloc(sizeof(View));
view->orientation = ViewOrientationHorizontal;
view_init(view);
return view;
}
@@ -12,6 +12,10 @@ void view_free(View* view) {
free(view);
}
void view_init(View* view) {
view->orientation = ViewOrientationHorizontal;
}
void view_tie_icon_animation(View* view, IconAnimation* icon_animation) {
furi_check(view);
icon_animation_set_update_callback(icon_animation, view_icon_animation_callback, view);

View File

@@ -31,6 +31,9 @@ struct View {
void* context;
};
/** Initialize View (for internal use) */
void view_init(View* view);
/** IconAnimation tie callback */
void view_icon_animation_callback(IconAnimation* instance, void* context);

View File

@@ -1,9 +1,6 @@
#include "view_stack.h"
#include "view_i.h"
#include <gui/view.h>
#include <core/memmgr.h>
#define MAX_VIEWS 3
typedef struct {
@@ -11,7 +8,7 @@ typedef struct {
} ViewStackModel;
struct ViewStack {
View* view;
View view;
};
static void view_stack_draw(Canvas* canvas, void* model);
@@ -32,26 +29,26 @@ static void view_stack_enter(void* context) {
furi_assert(context);
ViewStack* view_stack = context;
ViewStackModel* model = view_get_model(view_stack->view);
ViewStackModel* model = view_get_model(&view_stack->view);
/* if more than 1 Stack View hold same view they have to reassign update_callback_context */
for(int i = 0; i < MAX_VIEWS; ++i) {
if(model->views[i]) {
view_set_update_callback_context(model->views[i], view_stack->view);
view_set_update_callback_context(model->views[i], &view_stack->view);
if(model->views[i]->enter_callback) {
model->views[i]->enter_callback(model->views[i]->context);
}
}
}
view_commit_model(view_stack->view, false);
view_commit_model(&view_stack->view, false);
}
static void view_stack_exit(void* context) {
furi_assert(context);
ViewStack* view_stack = context;
ViewStackModel* model = view_get_model(view_stack->view);
ViewStackModel* model = view_get_model(&view_stack->view);
for(int i = 0; i < MAX_VIEWS; ++i) {
if(model->views[i] && model->views[i]->exit_callback) {
@@ -59,35 +56,35 @@ static void view_stack_exit(void* context) {
}
}
view_commit_model(view_stack->view, false);
view_commit_model(&view_stack->view, false);
}
ViewStack* view_stack_alloc(void) {
ViewStack* view_stack = malloc(sizeof(ViewStack));
view_stack->view = view_alloc();
view_init(&view_stack->view);
view_allocate_model(view_stack->view, ViewModelTypeLocking, sizeof(ViewStackModel));
view_set_draw_callback(view_stack->view, view_stack_draw);
view_set_input_callback(view_stack->view, view_stack_input);
view_set_context(view_stack->view, view_stack);
view_set_enter_callback(view_stack->view, view_stack_enter);
view_set_exit_callback(view_stack->view, view_stack_exit);
view_allocate_model(&view_stack->view, ViewModelTypeLocking, sizeof(ViewStackModel));
view_set_draw_callback(&view_stack->view, view_stack_draw);
view_set_input_callback(&view_stack->view, view_stack_input);
view_set_context(&view_stack->view, view_stack);
view_set_enter_callback(&view_stack->view, view_stack_enter);
view_set_exit_callback(&view_stack->view, view_stack_exit);
return view_stack;
}
void view_stack_free(ViewStack* view_stack) {
furi_assert(view_stack);
ViewStackModel* model = view_get_model(view_stack->view);
ViewStackModel* model = view_get_model(&view_stack->view);
for(int i = 0; i < MAX_VIEWS; ++i) {
if(model->views[i]) {
view_set_update_callback(model->views[i], NULL);
view_set_update_callback_context(model->views[i], NULL);
}
}
view_commit_model(view_stack->view, false);
view_commit_model(&view_stack->view, false);
view_free(view_stack->view);
view_free_model(&view_stack->view);
free(view_stack);
}
@@ -109,14 +106,14 @@ static bool view_stack_input(InputEvent* event, void* context) {
ViewStack* view_stack = context;
bool consumed = false;
ViewStackModel* model = view_get_model(view_stack->view);
ViewStackModel* model = view_get_model(&view_stack->view);
for(int i = MAX_VIEWS - 1; i >= 0; i--) {
if(model->views[i] && view_input(model->views[i], event)) {
consumed = true;
break;
}
}
view_commit_model(view_stack->view, false);
view_commit_model(&view_stack->view, false);
return consumed;
}
@@ -126,12 +123,12 @@ void view_stack_add_view(ViewStack* view_stack, View* view) {
furi_assert(view);
bool result = false;
ViewStackModel* model = view_get_model(view_stack->view);
ViewStackModel* model = view_get_model(&view_stack->view);
for(int i = 0; i < MAX_VIEWS; ++i) {
if(!model->views[i]) {
model->views[i] = view;
view_set_update_callback(model->views[i], view_stack_update_callback);
view_set_update_callback_context(model->views[i], view_stack->view);
view_set_update_callback_context(model->views[i], &view_stack->view);
if(view->enter_callback) {
view->enter_callback(view->context);
}
@@ -139,7 +136,7 @@ void view_stack_add_view(ViewStack* view_stack, View* view) {
break;
}
}
view_commit_model(view_stack->view, result);
view_commit_model(&view_stack->view, result);
furi_assert(result);
}
@@ -150,7 +147,7 @@ void view_stack_remove_view(ViewStack* view_stack, View* view) {
/* Removing view on-the-go is dangerous, but it is protected with
* Locking model, so system is consistent at any time. */
bool result = false;
ViewStackModel* model = view_get_model(view_stack->view);
ViewStackModel* model = view_get_model(&view_stack->view);
for(int i = 0; i < MAX_VIEWS; ++i) {
if(model->views[i] == view) {
if(view->exit_callback) {
@@ -163,11 +160,11 @@ void view_stack_remove_view(ViewStack* view_stack, View* view) {
break;
}
}
view_commit_model(view_stack->view, result);
view_commit_model(&view_stack->view, result);
furi_assert(result);
}
View* view_stack_get_view(ViewStack* view_stack) {
furi_assert(view_stack);
return view_stack->view;
return &view_stack->view;
}