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

View File

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

View File

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