Fetch list from phone

master
Alinson S. Xavier 9 years ago
parent e60aa7efdf
commit cfe014402c

@ -9,6 +9,7 @@ INCLUDE_DIRECTORIES("build/${PEBBLE_FLAVOUR}/src")
INCLUDE_DIRECTORIES("build/include")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-DCLION)
set(SOURCE_FILES
src/main.c

@ -38,6 +38,9 @@ static void on_update(struct Layer *layer, GContext *context)
};
graphics_context_set_fill_color(context, border->color);
graphics_fill_rect(context, rect, 0, GCornerNone);
graphics_context_set_fill_color(context, GColorBlack);
graphics_fill_circle(context, GPoint(7, 10), 2);
}
static struct Layer* create_raw_layer(struct BorderLayer *border,

@ -19,13 +19,26 @@
#include <pebble.h>
#include "screens/list/list_window.h"
#include "network.h"
#include "util.h"
int main(void)
{
struct ListWindow *window = LIST_WINDOW_create();
int rval = 0;
struct ListWindow *window = 0;
rval = NETWORK_register();
abort_if(rval, "NETWORK_register failed");
window = LIST_WINDOW_create();
abort_if(!window, "LIST_WINDOW_create failed");
window_stack_push(window->raw_window, true);
app_event_loop();
CLEANUP:
LIST_WINDOW_destroy(window);
NETWORK_cleanup();
return rval;
}

@ -22,17 +22,38 @@
#include "util.h"
#define MAX_HABIT_COUNT 50
static int HABIT_COUNT;
static int HABIT_CURRENT;
// LIST WINDOW
//------------------------------------------------------------------------------
struct NetworkState
{
int habit_count;
int habit_current;
struct NetworkCallbacks *callbacks;
};
static int process_ok(struct NetworkState *state)
{
int rval = 0;
abort_if(!state, "state is null");
struct NetworkCallbacks *callbacks = state->callbacks;
abort_if(!callbacks, "callbacks is null");
static int request_next_habit()
if(!callbacks->on_ok) goto CLEANUP;
rval = callbacks->on_ok(callbacks->on_ok_context);
abort_if(rval, "state->on_ok failed");
CLEANUP:
return rval;
}
static int request_next_habit(struct NetworkState *state)
{
int rval = 0;
abort_if(!state, "state is null");
if(HABIT_CURRENT >= HABIT_COUNT)
if(state->habit_current >= state->habit_count)
goto CLEANUP;
DictionaryIterator *dict;
@ -42,71 +63,78 @@ static int request_next_habit()
rval = dict_write_cstring(dict, 0, "FETCH");
abort_if(rval, "dict_write_cstring failed");
rval = dict_write_int32(dict, 1, HABIT_CURRENT);
rval = dict_write_int32(dict, 1, state->habit_current);
abort_if(rval, "dict_write_cstring failed");
rval = app_message_outbox_send();
abort_if(rval, "app_message_outbox_send failed");
HABIT_CURRENT++;
state->habit_current++;
CLEANUP:
return rval;
}
static int process_count(DictionaryIterator *iter)
static int process_count(DictionaryIterator *iter, struct NetworkState *state)
{
int rval = 0;
abort_if(!state, "state is null");
struct NetworkCallbacks *callbacks = state->callbacks;
Tuple *tuple = dict_find(iter, 1);
abort_if(!tuple, "tuple is null");
int count = tuple->value->int32;
// rval = LIST_WINDOW_allocate(count);
// abort_if(rval, "LIST_WINDOW_allocate failed");
if(callbacks->on_count)
{
rval = callbacks->on_count(count, callbacks->on_count_context);
abort_if(rval, "state->on_count failed");
}
if(count > MAX_HABIT_COUNT) count = MAX_HABIT_COUNT;
HABIT_COUNT = count;
HABIT_CURRENT = 0;
state->habit_count = count;
state->habit_current = 0;
rval = request_next_habit();
rval = request_next_habit(state);
abort_if(rval, "request_next_habit failed");
CLEANUP:
return rval;
}
static int process_habit(DictionaryIterator *iter)
static int process_habit(DictionaryIterator *iter, struct NetworkState *state)
{
int rval = 0;
struct NetworkCallbacks *callbacks = state->callbacks;
// // id
// Tuple *tuple = dict_find(iter, 1);
// abort_if(!tuple, "tuple is null");
// int id = tuple->value->int32;
//
// // name
// tuple = dict_find(iter, 2);
// abort_if(!tuple, "tuple is null");
// char *name = tuple->value->cstring;
//
// // checkmark value
// tuple = dict_find(iter, 3);
// abort_if(!tuple, "tuple is null");
// int checkmark = tuple->value->int32;
// rval = LIST_WINDOW_add_habit(id, name, checkmark);
// abort_if(rval, "LIST_WINDOW_add_habit failed");
rval = request_next_habit();
Tuple *tuple = dict_find(iter, 1);
abort_if(!tuple, "tuple is null");
int id = tuple->value->int32;
tuple = dict_find(iter, 2);
abort_if(!tuple, "tuple is null");
char *name = tuple->value->cstring;
tuple = dict_find(iter, 3);
abort_if(!tuple, "tuple is null");
int checkmark = tuple->value->int32;
if(callbacks->on_habit)
{
void *ctx = callbacks->on_habit_context;
rval = callbacks->on_habit(id, name, checkmark, ctx);
abort_if(rval, "state->on_habit failed");
rval = request_next_habit(state);
abort_if(rval, "request_next_habit failed");
}
CLEANUP:
return rval;
}
int NETWORK_request_list()
int NETWORK_request_toggle(int id)
{
int rval = 0;
@ -114,17 +142,22 @@ int NETWORK_request_list()
rval = app_message_outbox_begin(&dict);
abort_if(rval, "app_message_outbox_begin failed");
rval = dict_write_cstring(dict, 0, "COUNT");
rval = dict_write_cstring(dict, 0, "TOGGLE");
abort_if(rval, "dict_write_cstring failed");
rval = dict_write_int32(dict, 1, id);
abort_if(rval, "dict_write_cstring failed");
rval = app_message_outbox_send();
abort_if(rval, "app_message_outbox_send failed");
log_debug("--> %s", "COUNT");
CLEANUP:
return rval;
}
int NETWORK_request_toggle(int id)
int NETWORK_request_list()
{
int rval = 0;
@ -132,53 +165,88 @@ int NETWORK_request_toggle(int id)
rval = app_message_outbox_begin(&dict);
abort_if(rval, "app_message_outbox_begin failed");
rval = dict_write_cstring(dict, 0, "TOGGLE");
abort_if(rval, "dict_write_cstring failed");
rval = dict_write_int32(dict, 1, id);
rval = dict_write_cstring(dict, 0, "COUNT");
abort_if(rval, "dict_write_cstring failed");
rval = app_message_outbox_send();
abort_if(rval, "app_message_outbox_send failed");
log_debug("--> %s", "COUNT");
CLEANUP:
return rval;
}
//------------------------------------------------------------------------------
static void NETWORK_on_received(DictionaryIterator *iter, void *context)
{
int rval = 0;
struct NetworkState *state = context;
abort_if(!state, "state is null");
Tuple *tuple = dict_find(iter, 0);
abort_if(!tuple, "tuple is null");
char *action = tuple->value->cstring;
log_debug("<-- %s", action);
if(strcmp(action, "COUNT") == 0)
{
rval = process_count(iter);
rval = process_count(iter, state);
abort_if(rval, "process_count failed");
}
else if(strcmp(action, "HABIT") == 0)
{
rval = process_habit(iter);
rval = process_habit(iter, state);
abort_if(rval, "process_habit failed");
}
else if(strcmp(action, "OK") == 0)
{
rval = NETWORK_request_list();
abort_if(rval, "NETWORK_request_list failed");
rval = process_ok(state);
abort_if(rval, "process_ok failed");
}
CLEANUP:
return;
}
struct NetworkCallbacks * NETWORK_get_callbacks()
{
struct NetworkState *state = app_message_get_context();
return state->callbacks;
}
int NETWORK_register()
{
int rval = 0;
struct NetworkState *state = 0;
state = (struct NetworkState*) malloc(sizeof(struct NetworkState));
abort_if(!state, "could not allocate state");
struct NetworkCallbacks *callbacks = 0;
callbacks = (struct NetworkCallbacks*) malloc(sizeof(struct NetworkCallbacks));
abort_if(!callbacks, "could not allocate callbacks");
state->callbacks = callbacks;
callbacks->on_ok = 0;
callbacks->on_habit = 0;
callbacks->on_count = 0;
callbacks->on_ok_context = 0;
callbacks->on_habit_context = 0;
callbacks->on_count_context = 0;
app_message_register_inbox_received(NETWORK_on_received);
app_message_open(1024, 1024);
return 0;
app_message_set_context(state);
CLEANUP:
return rval;
}
void NETWORK_cleanup()
{
struct NetworkState *state = app_message_get_context();
free(state->callbacks);
free(state);
app_message_deregister_callbacks();
}

@ -19,8 +19,30 @@
#pragma once
int NETWORK_register();
struct NetworkCallbacks
{
void *on_count_context;
void *on_habit_context;
void *on_ok_context;
int (*on_count)(int count, void *callback_context);
int (*on_habit)(int id,
char *name,
int checkmark,
void *callback_context);
int (*on_ok)(void *callback_context);
};
int NETWORK_request_list();
int NETWORK_request_toggle(int id);
struct NetworkCallbacks* NETWORK_get_callbacks();
int NETWORK_register();
void NETWORK_cleanup();

@ -23,9 +23,12 @@
const char *ACTIONS[] = {
" Check",
" View stats"
" More Info"
};
// MENU LAYER CALLBACKS
// -----------------------------------------------------------------------------
// callback: MenuLayerSelectCallback
static void on_click(struct MenuLayer *menu_layer,
MenuIndex *cell_index,
@ -62,6 +65,8 @@ static int16_t on_get_cell_height(struct MenuLayer *menu_layer,
return CELL_HEIGHT;
}
// -----------------------------------------------------------------------------
static void set_menu_layer_callbacks(struct ActionMenuLayer *action_menu,
struct MenuLayer *menu)
{

@ -21,13 +21,12 @@
struct ActionMenuLayerCallbacks
{
void (*on_select)(void *callback_context);
int (*on_select)(void *callback_context);
};
struct ActionMenuLayer
{
struct MenuLayer *menu_layer;
void *callback_context;
struct ActionMenuLayerCallbacks callbacks;
};

@ -24,18 +24,47 @@
#include "action_menu_layer.h"
#include "style.h"
#include "../animation/animation_window.h"
#include "../../network.h"
static void on_select(void *callback_context)
#ifdef CLION
#include <resource_ids.auto.h>
#endif
// NETWORK CALLBACKS
// -----------------------------------------------------------------------------
static int on_ok(void *callback_context)
{
struct AnimationWindow *window = ANIMATION_WINDOW_create(
RESOURCE_ID_CONFIRM_SEQUENCE);
window_stack_push(window->raw_window, true);
return 0;
}
// ACTION MENU LAYER CALLBACKS
// -----------------------------------------------------------------------------
static int on_select(void *callback_context)
{
int rval = 0;
struct ActionWindow *window = callback_context;
ANIMATION_WINDOW_destroy(window->animation_window);
window->animation_window = ANIMATION_WINDOW_create(
RESOURCE_ID_CONFIRM_SEQUENCE);
rval = NETWORK_request_toggle(window->habit_id);
abort_if(rval, "NETWORK_request_toggle failed");
struct NetworkCallbacks *net_callbacks = NETWORK_get_callbacks();
abort_if(!net_callbacks, "NETWORK_get_callbacks failed");
net_callbacks->on_ok = on_ok;
window_stack_push(window->animation_window->raw_window, true);
CLEANUP:
return rval;
}
// -----------------------------------------------------------------------------
static int add_menu_layer(struct ActionWindow *window,
struct Layer *root_layer,
struct GRect bounds)
@ -109,13 +138,15 @@ static void set_raw_window_handlers(Window *raw_window)
window_set_window_handlers(raw_window, handlers);
}
struct ActionWindow *ACTION_WINDOW_create()
struct ActionWindow *ACTION_WINDOW_create(int habit_id)
{
struct ActionWindow *window = 0;
window = (struct ActionWindow*) malloc(sizeof(struct ActionWindow));
if(!window) return NULL;
window->habit_id = habit_id;
Window *raw_window = window_create();
if(!raw_window) return NULL;

@ -21,6 +21,8 @@
struct ActionWindow
{
int habit_id;
struct Window *raw_window;
struct ActionMenuLayer *menu_layer;
@ -30,6 +32,6 @@ struct ActionWindow
struct AnimationWindow *animation_window;
};
struct ActionWindow* ACTION_WINDOW_create();
struct ActionWindow* ACTION_WINDOW_create(int habit_id);
void ACTION_WINDOW_destroy(struct ActionWindow *window);

@ -31,6 +31,6 @@
#define BORDER_COLOR GColorFolly
#define BORDER_WIDTH 6
#define BORDER_WIDTH 14
#define CELL_HEIGHT 36

@ -23,22 +23,31 @@
#define MAX_NAME_LENGTH 20
static int free_habits(struct ListLayer *layer)
int LIST_LAYER_clear(struct ListLayer *layer)
{
int rval = 0;
abort_if(!layer, "layer is null");
for(int i = 0; i < layer->habit_count; i++) free(layer->habit_names[i]);
free(layer->habit_names);
free(layer->habit_checkmarks);
free(layer->habit_ids);
layer->habit_names = 0;
layer->habit_checkmarks = 0;
layer->habit_ids = 0;
layer->habit_count = 0;
return 0;
CLEANUP:
return rval;
}
int LIST_LAYER_allocate(struct ListLayer *layer, int count)
{
int rval = 0;
free_habits(layer);
rval = LIST_LAYER_clear(layer);
abort_if(rval, "LIST_LAYER_clear failed");
layer->habit_names = (char **) malloc(count * sizeof(char *));
abort_if(!layer->habit_names, "could not allocate habit_names");
@ -64,8 +73,14 @@ int LIST_LAYER_add_habit(struct ListLayer *layer,
char *new_name,
int new_checkmark)
{
uint16_t count = layer->habit_count;
int rval = 0;
abort_if(!layer, "layer is null");
abort_if(!layer->habit_ids, "layer->habit_ids is null");
abort_if(!layer->habit_names, "layer->habits_names is null");
abort_if(!layer->habit_checkmarks, "layer->habit_checkmarks is null");
uint16_t count = layer->habit_count;
char *name = layer->habit_names[count];
strncpy(name, new_name, MAX_NAME_LENGTH);
menu_layer_reload_data(layer->menu_layer);
@ -74,7 +89,8 @@ int LIST_LAYER_add_habit(struct ListLayer *layer,
layer->habit_checkmarks[count] = new_checkmark;
layer->habit_count++;
return 0;
CLEANUP:
return rval;
}
static uint16_t get_num_rows(MenuLayer *menu_layer,
@ -90,11 +106,20 @@ static void on_draw_row(GContext *ctx,
MenuIndex *cell_index,
void *callback_context)
{
int rval = 0;
abort_if(!cell_index, "cell_index is null");
int n = cell_index->row;
struct ListLayer *list_layer = callback_context;
abort_if(!list_layer, "list_layer is null");
char *name = list_layer->habit_names[n];
menu_cell_basic_draw(ctx, cell_layer, name, NULL, NULL);
CLEANUP:
if(rval) CRASH();
}
static int16_t get_cell_height(struct MenuLayer *menu_layer,
@ -108,21 +133,23 @@ static void select_click(struct MenuLayer *menu_layer,
struct MenuIndex *index,
void *callback_context)
{
int rval = 0;
struct ListLayer *list_layer = callback_context;
if(!list_layer->callbacks.on_select) return;
abort_if(!list_layer, "list_layer is null");
list_layer->callbacks.on_select(list_layer->callback_context);
}
struct ListLayerCallbacks *callbacks = &list_layer->callbacks;
abort_if(!callbacks, "callbacks is null");
static void request_list(void *context)
{
struct ListLayer *layer = context;
int n = index->row;
int habit_id = list_layer->habit_ids[n];
LIST_LAYER_allocate(layer, 4);
LIST_LAYER_add_habit(layer, 0, "Wake up early", 0);
LIST_LAYER_add_habit(layer, 1, "Meditate", 1);
LIST_LAYER_add_habit(layer, 2, "Exercise", 1);
LIST_LAYER_add_habit(layer, 3, "Go to school", 0);
if(!callbacks->on_select) return;
rval = callbacks->on_select(habit_id, callbacks->on_select_context);
abort_if(rval, "callbacks->on_select failed");
CLEANUP:
if(rval) CRASH();
}
static void set_menu_layer_callbacks(struct ListLayer *list_layer,
@ -149,7 +176,6 @@ static void set_menu_layer_styles(MenuLayer *menu_layer)
void LIST_LAYER_attach_to_window(struct ListLayer *layer, struct Window *window)
{
menu_layer_set_click_config_onto_window(layer->menu_layer, window);
app_timer_register(500, request_list, layer);
}
void LIST_LAYER_add_to_layer(struct ListLayer *layer, struct Layer *root_layer)
@ -178,7 +204,7 @@ struct ListLayer* LIST_LAYER_create(struct GRect bounds)
void LIST_LAYER_destroy(struct ListLayer *list_layer)
{
if(!list_layer) return;
free_habits(list_layer);
LIST_LAYER_clear(list_layer);
menu_layer_destroy(list_layer->menu_layer);
free(list_layer);
}

@ -22,7 +22,9 @@
struct ListLayerCallbacks
{
void (*on_select)(void *callback_context);
void *on_select_context;
int (*on_select)(int habit_id, void *callback_context);
};
struct ListLayer
@ -35,10 +37,16 @@ struct ListLayer
struct MenuLayer *menu_layer;
struct ActionWindow *action_window;
void *callback_context;
struct ListLayerCallbacks callbacks;
};
int LIST_LAYER_add_habit(struct ListLayer *layer,
int new_id,
char *new_name,
int new_checkmark);
int LIST_LAYER_allocate(struct ListLayer *layer, int count);
void LIST_LAYER_attach_to_window(struct ListLayer *layer, struct Window *window);
void LIST_LAYER_add_to_layer(struct ListLayer *layer, struct Layer *root_layer);
@ -46,3 +54,5 @@ void LIST_LAYER_add_to_layer(struct ListLayer *layer, struct Layer *root_layer);
struct ListLayer* LIST_LAYER_create(struct GRect bounds);
void LIST_LAYER_destroy(struct ListLayer *layer);
int LIST_LAYER_clear(struct ListLayer *layer);

@ -21,15 +21,69 @@
#include "list_window.h"
#include "../action/action_window.h"
#include "list_layer.h"
#include "../animation/animation_window.h"
#include "../../network.h"
#include "../../util.h"
static void on_select(void *callback_context)
// NETWORK CALLBACKS
// -----------------------------------------------------------------------------
int on_habit(int id, char *name, int checkmark, void *callback_context)
{
int rval = 0;
struct ListWindow *window = callback_context;
LIST_WINDOW_show_action_window(window);
rval = LIST_LAYER_add_habit(window->list_layer, id, name, checkmark);
abort_if(rval, "LIST_LAYER_add_habit failed");
CLEANUP:
return rval;
}
int on_count(int count, void *callback_context)
{
int rval = 0;
struct ListWindow *window = callback_context;
rval = LIST_LAYER_allocate(window->list_layer, count);
abort_if(rval, "LIST_LAYER_allocate failed");
CLEANUP:
return rval;
}
// BUTTON CALLBACKS
// -----------------------------------------------------------------------------
static int on_select(int habit_id, void *callback_context)
{
int rval = 0;
struct ListWindow *window = callback_context;
ACTION_WINDOW_destroy(window->action_window);
window->action_window = ACTION_WINDOW_create(habit_id);
abort_if(!window->action_window, "ACTION_WINDOW_create failed");
window_stack_push(window->action_window->raw_window, true);
CLEANUP:
return rval;
}
// callback: WindowHandler
// TIMER CALLBACKS
// -----------------------------------------------------------------------------
static void request_list(void *callback_context)
{
int rval = 0;
rval = NETWORK_request_list();
abort_if(rval, "NETWORK_request_list failed");
CLEANUP:
if(rval) CRASH();
}
// WINDOW HANDLERS
// -----------------------------------------------------------------------------
static void on_load(Window *raw_window)
{
Layer *root_layer = window_get_root_layer(raw_window);
@ -40,13 +94,12 @@ static void on_load(Window *raw_window)
LIST_LAYER_attach_to_window(window->list_layer, raw_window);
LIST_LAYER_add_to_layer(window->list_layer, root_layer);
window->list_layer->callback_context = window;
window->list_layer->callbacks = (struct ListLayerCallbacks) {
.on_select = on_select
.on_select = on_select,
.on_select_context = window
};
}
// callback: WindowHandler
static void on_unload(Window *raw_window)
{
struct ListWindow *list_window = window_get_user_data(raw_window);
@ -54,21 +107,48 @@ static void on_unload(Window *raw_window)
ACTION_WINDOW_destroy(list_window->action_window);
}
void LIST_WINDOW_show_action_window(struct ListWindow *window)
static void on_appear(Window *raw_window)
{
ACTION_WINDOW_destroy(window->action_window);
int rval = 0;
struct ListWindow *window = window_get_user_data(raw_window);
window->action_window = ACTION_WINDOW_create();
if(!window->action_window) return;
LIST_LAYER_clear(window->list_layer);
window_stack_push(window->action_window->raw_window, true);
struct NetworkCallbacks *callbacks = NETWORK_get_callbacks();
abort_if(!callbacks, "NETWORK_get_callbacks failed");
callbacks->on_count = on_count;
callbacks->on_count_context = window;
callbacks->on_habit = on_habit;
callbacks->on_habit_context = window;
app_timer_register(500, request_list, window);
CLEANUP:
if(rval) CRASH();
}
static void on_disappear(Window *raw_window)
{
int rval = 0;
struct NetworkCallbacks *callbacks = NETWORK_get_callbacks();
abort_if(!callbacks, "NETWORK_get_callbacks failed");
callbacks->on_count = 0;
callbacks->on_habit = 0;
CLEANUP:
if(rval) CRASH();
}
// -----------------------------------------------------------------------------
struct ListWindow *LIST_WINDOW_create()
{
WindowHandlers handlers = {
.load = on_load,
.unload = on_unload
.unload = on_unload,
.appear = on_appear,
.disappear = on_disappear,
};
struct ListWindow *list_window = 0;

@ -26,8 +26,6 @@ struct ListWindow
struct ActionWindow *action_window;
};
void LIST_WINDOW_show_action_window(struct ListWindow *window);
struct ListWindow *LIST_WINDOW_create();
void LIST_WINDOW_destroy(struct ListWindow *window);

@ -22,10 +22,18 @@
#include <pebble.h>
#define abort_if(cond, msg) if(cond) { \
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d) (%s:%d)", rval, __FILE__, __LINE__); \
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d)", rval); \
rval = 1; goto CLEANUP; }
#define abort_iff(cond, msg, ...) if(cond) { \
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d) (%s:%d)", __VA_ARGS__, rval, __FILE__, \
__LINE__); \
APP_LOG(APP_LOG_LEVEL_ERROR, msg " (%d)", __VA_ARGS__, rval); \
rval = 1; goto CLEANUP; }
#define log_debug(msg, ...) APP_LOG(APP_LOG_LEVEL_DEBUG, msg, __VA_ARGS__)
static void CRASH()
{
APP_LOG(APP_LOG_LEVEL_ERROR, "%s", "forcing crash");
int *x = NULL;
*x = 42;
}