Source

inpulse / app.c

Full commit
/**
*
* Multi-app main loop
*
* Copyright (C) 2011 Trammell Hudson <hudson@osresearch.net>
*
* Permission to use, copy, modify, and/or distribute this software for 
* any purpose with or without fee is hereby granted, provided that the 
* above copyright notice and this permission notice appear in all copies. 
* 
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 
* BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES 
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
* SOFTWARE.
*
**/

#include "app.h"


extern const app_t stars_app;
extern const app_t qr_app;
extern const app_t life_app;
extern const app_t powersave_app;
extern const app_t swarm_app;
extern const app_t plaid_app;

static const app_t * apps[] = {
	&powersave_app,
	&stars_app,
	//&qr_app,
	//&life_app,
	&swarm_app,
	//&plaid_app,
};

static uint8_t current;
#define NUM_APPS (sizeof(apps) / sizeof(*apps))

static unsigned button_down_time;
static uint8_t common_block[APP_COMMON_SIZE];
void * const app_common_data = common_block;


void
main_app_handle_button_down(void)
{
	button_down_time = pulse_get_millis();

	if (apps[current]->button_down)
		apps[current]->button_down();
}


void
main_app_handle_button_up(void)
{
	// If the button down time is not set, we have had a cancelled
	// button press due to an app switch.  Do not foward it to the app.
	if (button_down_time == 0)
		return;

	unsigned delta_ms = pulse_get_millis() - button_down_time;
	button_down_time = 0;

	if (apps[current]->button_up)
		apps[current]->button_up(delta_ms);
}


static void
short_pulse()
{
	pulse_vibe_on();
	pulse_mdelay(100);
	pulse_vibe_off();
}


static void
new_app(void)
{
	pulse_blank_canvas();

	current = (current < NUM_APPS - 1) ? current + 1 : 0;

	button_down_time = 0;
	short_pulse();

	if (apps[current]->init)
		apps[current]->init();
}


void
main_app_loop(void)
{
	// Check for a long button press; switch apps if this occurs
	if (button_down_time)
	{
		if (pulse_get_millis() - button_down_time > 2000)
			new_app();
	}

	struct pulse_time_tm now;
	pulse_get_time_date(&now);

	if (apps[current]->loop)
		apps[current]->loop(&now);
}


void
main_app_init(void)
{
	pulse_oled_set_brightness(25);
	srand(pulse_get_millis());

	current = 0;
	
	if (apps[current]->init)
		apps[current]->init();
}


void
main_app_handle_doz(void)
{
#ifdef CONFIG_HAVE_DOZ
	if (apps[current]->doz)
		apps[current]->doz();
#endif
}


void
main_app_handle_hardware_update(
	enum PulseHardwareEvent event
)
{
#ifdef CONFIG_HAVE_HW_UPDATE
	if (apps[current]->hardware_update)
		apps[current]->hardware_update(event);
#endif
}