我正在为Pebble制作一个非常简单的射箭场分数跟踪应用程序,我遇到了在会话之间存储和检索整数值的问题。存储和检索的行为工作正常,但由于某些奇怪的原因,只检索了1个值,然后填入第二个变量,因此它们都是相同的。
粘贴我的完整代码,包括我的调试日志记录,同时试图找出它。即使卸载窗口,所有值都是正确的,但是当在下一个窗口加载时检索值时,它似乎只得到1 ......?
/* TODO
- Show time bar along top of screen
*/
#include <pebble.h>
uint32_t keyTotal,keyTargets;
static Window *window;
static TextLayer *text_layer_SCORE,*text_layer_TARGETS,*text_layer_TOTAL,*text_layer_TITLE;
int score,targets,total;
char targetText[]="Targets: ";
char scoreText[]="Score: ";
char totalText[]="TOTAL: ";
char currentScore[]="Score: xxxx";
char currentTotal[]="TOTAL: xxxx";
char currentTargets[]="Targets: xxx";
static void logValues(char *string) {
APP_LOG(APP_LOG_LEVEL_INFO, string);
APP_LOG(APP_LOG_LEVEL_DEBUG, "----- SCORE: %i", score);
APP_LOG(APP_LOG_LEVEL_DEBUG, "----- TOTAL: %i", total);
APP_LOG(APP_LOG_LEVEL_DEBUG, "----- TARGETS: %i", targets);
}
static void updateScore() {
snprintf(currentScore,sizeof(currentScore),"%s %d",scoreText,score);
text_layer_set_text(text_layer_SCORE, currentScore);
logValues("----- AFTER UPDATE SCORE");
}
static void updateTotal() {
snprintf(currentTotal,sizeof(currentTotal),"%s %d",totalText,total);
text_layer_set_text(text_layer_TOTAL, currentTotal);
logValues("----- UPDATE TOTAL");
}
static void updateTargets() {
snprintf(currentTargets,sizeof(currentTargets),"%s %d",targetText,targets);
text_layer_set_text(text_layer_TARGETS, currentTargets);
logValues("----- AFTER UPDATE TARGETS");
}
static void updateAll() {
updateTotal();
updateTargets();
updateScore();
logValues("----- AFTER UPDATE ALL");
}
static void persistValues() {
persist_write_int(keyTotal, total);
persist_write_int(keyTargets, targets);
logValues("----- AFTER PERSIST VALUES");
}
static void resetValues() {
score = 0;
total = 0;
targets = 0;
persist_write_int(keyTargets, 0);
persist_write_int(keyTotal, 0);
logValues("----- AFTER RESET VALUES");
}
static void select_click_handler(ClickRecognizerRef recognizer, void *context) {
total = total + score;
++targets;
updateAll();
logValues("----- AFTER SELECT PRESSED");
}
static void up_click_handler(ClickRecognizerRef recognizer, void *context) {
// text_layer_set_text(text_layer, "Up");
score++;
updateScore();
logValues("----- AFTER UP PRESSED");
}
static void down_click_handler(ClickRecognizerRef recognizer, void *context) {
// text_layer_set_text(text_layer, "Down");
score--;
updateScore();
logValues("----- AFTER DOWN PRESSED");
}
static void up_long_click_handler(ClickRecognizerRef recognizer, void *context) {
//Window *window = (Window *)context;
}
static void up_long_click_release_handler(ClickRecognizerRef recognizer, void *context) {
//Window *window = (Window *)
resetValues();
updateAll();
}
static void click_config_provider(void *context) {
window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
window_single_click_subscribe(BUTTON_ID_UP, up_click_handler);
window_single_click_subscribe(BUTTON_ID_DOWN, down_click_handler);
window_long_click_subscribe(BUTTON_ID_UP, 3000, up_long_click_handler, up_long_click_release_handler);
}
static void window_load(Window *window) {
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_bounds(window_layer);
logValues("----- START OF WINDOW LOAD");
score = 0;
// Get previous total (if it exists)
if(persist_exists(keyTotal)) {
total = persist_read_int(keyTotal);
} else {
total = 0;
//persist_write_int(keyTotal, total);
APP_LOG(APP_LOG_LEVEL_DEBUG, "----- PERSIST TOTAL NOT FOUND, SETTING: %i", total);
}
// Get previous targets (if it exists)
if(persist_exists(keyTargets)) {
targets = persist_read_int(keyTargets);
} else {
targets = 0;
//persist_write_int(keyTargets, targets);
APP_LOG(APP_LOG_LEVEL_DEBUG, "----- PERSIST TARGETS NOT FOUND, SETTING: %i", targets);
}
APP_LOG(APP_LOG_LEVEL_DEBUG, "----- PERSIST END, TOTAL IS CURRENTLY: %i", total);
APP_LOG(APP_LOG_LEVEL_DEBUG, "----- PERSIST END, TOTAL IS CURRENTLY: %i", total);
window_set_click_config_provider(window, (ClickConfigProvider) click_config_provider);
text_layer_TITLE = text_layer_create(GRect(0, 0, bounds.size.w, bounds.size.h));
text_layer_SCORE = text_layer_create(GRect(0, 40, bounds.size.w, 35));
text_layer_TARGETS = text_layer_create(GRect(0, 80, bounds.size.w, 35));
text_layer_TOTAL = text_layer_create(GRect(0,120, bounds.size.w, 50));
text_layer_set_text(text_layer_TITLE, "ScoreTracker");
text_layer_set_text(text_layer_SCORE, currentScore);
text_layer_set_text(text_layer_TARGETS, currentTargets);
text_layer_set_text(text_layer_TOTAL, currentTotal);
updateAll();
text_layer_set_text_color(text_layer_TOTAL, GColorWhite);
text_layer_set_text_color(text_layer_TARGETS, GColorWhite);
text_layer_set_text_color(text_layer_SCORE, GColorBlack);
text_layer_set_background_color(text_layer_TITLE, GColorGreen);
text_layer_set_background_color(text_layer_TOTAL, GColorBlack);
text_layer_set_background_color(text_layer_SCORE, GColorLightGray);
text_layer_set_background_color(text_layer_TARGETS, GColorBlue);
text_layer_set_text_alignment(text_layer_TITLE, GTextAlignmentCenter);
text_layer_set_text_alignment(text_layer_SCORE, GTextAlignmentLeft);
text_layer_set_text_alignment(text_layer_TARGETS, GTextAlignmentLeft);
text_layer_set_text_alignment(text_layer_TOTAL, GTextAlignmentCenter);
// Fonts
text_layer_set_font(text_layer_TITLE, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
text_layer_set_font(text_layer_SCORE, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD));
text_layer_set_font(text_layer_TARGETS, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD));
text_layer_set_font(text_layer_TOTAL, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
layer_add_child(window_layer, text_layer_get_layer(text_layer_TITLE));
layer_add_child(window_layer, text_layer_get_layer(text_layer_SCORE));
layer_add_child(window_layer, text_layer_get_layer(text_layer_TARGETS));
layer_add_child(window_layer, text_layer_get_layer(text_layer_TOTAL));
logValues("----- END OF WINDOW LOAD");
}
static void window_unload(Window *window) {
text_layer_destroy(text_layer_SCORE);
text_layer_destroy(text_layer_TARGETS);
text_layer_destroy(text_layer_TOTAL);
text_layer_destroy(text_layer_TITLE);
persistValues();
logValues("----- END OF WINDOW UNLOAD");
}
static void init(void) {
window = window_create();
window_set_click_config_provider(window, click_config_provider);
window_set_window_handlers(window, (WindowHandlers) {
.load = window_load,
.unload = window_unload,
});
const bool animated = true;
window_stack_push(window, animated);
logValues("----- END OF INIT");
}
static void deinit(void) {
window_destroy(window);
}
int main(void) {
init();
APP_LOG(APP_LOG_LEVEL_DEBUG, "Done initializing, pushed window: %p", window);
app_event_loop();
deinit();
}
以下是运行上述应用代码的日志输出,进行了一些分数更改,退出并重新加载应用。
[INFO] ocess_manager.c:419: Heap Usage for App <ScoreTrack: Total Size <62480B> Used <628B> Still allocated <0B>
[INFO] button_click.c:19: ----- START OF WINDOW LOAD
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[DEBUG] button_click.c:126: ----- PERSIST TOTAL NOT FOUND, SETTING: 0
[DEBUG] button_click.c:135: ----- PERSIST TARGETS NOT FOUND, SETTING: 0
[DEBUG] button_click.c:138: ----- PERSIST END, TOTAL IS CURRENTLY: 0
[DEBUG] button_click.c:139: ----- PERSIST END, TARGETS IS CURRENTLY: 0
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- END OF WINDOW LOAD
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- END OF INIT
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[DEBUG] button_click.c:213: Done initializing, pushed window: 0x20020c0c
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 1
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UP PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 1
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 2
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UP PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 2
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 3
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UP PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 3
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- AFTER UP PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 4
[DEBUG] button_click.c:22: ----- TARGETS: 1
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 4
[DEBUG] button_click.c:22: ----- TARGETS: 1
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 4
[DEBUG] button_click.c:22: ----- TARGETS: 1
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 4
[DEBUG] button_click.c:22: ----- TARGETS: 1
[INFO] button_click.c:19: ----- AFTER SELECT PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 4
[DEBUG] button_click.c:22: ----- TARGETS: 1
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 8
[DEBUG] button_click.c:22: ----- TARGETS: 2
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 8
[DEBUG] button_click.c:22: ----- TARGETS: 2
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 8
[DEBUG] button_click.c:22: ----- TARGETS: 2
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 8
[DEBUG] button_click.c:22: ----- TARGETS: 2
[INFO] button_click.c:19: ----- AFTER SELECT PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 8
[DEBUG] button_click.c:22: ----- TARGETS: 2
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 12
[DEBUG] button_click.c:22: ----- TARGETS: 3
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 12
[DEBUG] button_click.c:22: ----- TARGETS: 3
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 12
[DEBUG] button_click.c:22: ----- TARGETS: 3
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 12
[DEBUG] button_click.c:22: ----- TARGETS: 3
[INFO] button_click.c:19: ----- AFTER SELECT PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 12
[DEBUG] button_click.c:22: ----- TARGETS: 3
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 16
[DEBUG] button_click.c:22: ----- TARGETS: 4
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 16
[DEBUG] button_click.c:22: ----- TARGETS: 4
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 16
[DEBUG] button_click.c:22: ----- TARGETS: 4
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 16
[DEBUG] button_click.c:22: ----- TARGETS: 4
[INFO] button_click.c:19: ----- AFTER SELECT PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 16
[DEBUG] button_click.c:22: ----- TARGETS: 4
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 20
[DEBUG] button_click.c:22: ----- TARGETS: 5
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 20
[DEBUG] button_click.c:22: ----- TARGETS: 5
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 20
[DEBUG] button_click.c:22: ----- TARGETS: 5
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 20
[DEBUG] button_click.c:22: ----- TARGETS: 5
[INFO] button_click.c:19: ----- AFTER SELECT PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 20
[DEBUG] button_click.c:22: ----- TARGETS: 5
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 24
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 24
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 24
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 24
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER SELECT PRESSED
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 24
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER PERSIST VALUES
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 24
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- END OF WINDOW UNLOAD
[DEBUG] button_click.c:20: ----- SCORE: 4
[DEBUG] button_click.c:21: ----- TOTAL: 24
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] ocess_manager.c:419: Heap Usage for App <ScoreTrack: Total Size <62480B> Used <628B> Still allocated <0B>
[INFO] button_click.c:19: ----- START OF WINDOW LOAD
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 0
[DEBUG] button_click.c:22: ----- TARGETS: 0
[DEBUG] button_click.c:138: ----- PERSIST END, TOTAL IS CURRENTLY: 6
[DEBUG] button_click.c:139: ----- PERSIST END, TARGETS IS CURRENTLY: 6
[INFO] button_click.c:19: ----- UPDATE TOTAL
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 6
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER UPDATE TARGETS
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 6
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER UPDATE SCORE
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 6
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- AFTER UPDATE ALL
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 6
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- END OF WINDOW LOAD
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 6
[DEBUG] button_click.c:22: ----- TARGETS: 6
[INFO] button_click.c:19: ----- END OF INIT
[DEBUG] button_click.c:20: ----- SCORE: 0
[DEBUG] button_click.c:21: ----- TOTAL: 6
[DEBUG] button_click.c:22: ----- TARGETS: 6
[DEBUG] button_click.c:213: Done initializing, pushed window: 0x20020c0c
我尝试使用数据结构代替保存和检索这些值,但在我的生活中无法弄清楚这是如何完成的。 Pebble开发站点上的示例没有填充到足以让我填写空白。对于像这样的事情,仍然只是一个爱好编码器所以可能有一大堆基础知识,我在这里完全没有。非常感谢任何帮助!
答案 0 :(得分:0)
想出来。我将键值误解为您要保存到存储器的整数,而不是值存储在存储器中的位置的实际键值。所以每次我保存并检索它所保存的值,并根据当时的值从不同的位置检索。
查看下页的Persist Counter代码示例对我有所帮助 https://developer.pebble.com/examples/
相关代码现在
#define NUM_TOTAL_DEFAULT 0
#define NUM_TARGETS_DEFAULT 0
#define NUM_TOTAL_PKEY 1
#define NUM_TARGETS_PKEY 2
...
static void persistValues() {
persist_write_int(NUM_TARGETS_PKEY, targets);
persist_write_int(NUM_TOTAL_PKEY, total);
}
...
static void init(void) {
// SET PERSISTENT VALUES IF EXISTS
total = persist_exists(NUM_TOTAL_PKEY) ? persist_read_int(NUM_TOTAL_PKEY) : NUM_TOTAL_DEFAULT;
targets = persist_exists(NUM_TARGETS_PKEY) ? persist_read_int(NUM_TARGETS_PKEY) : NUM_TARGETS_DEFAULT;
...
}
static void deinit(void) {
// SAVE VALUES IN TO PERSISTENT STORAGE
persistValues();
window_destroy(window);
}