void download_complete_handler(NetDownload *download) { printf("Loaded image with %lu bytes", download->length); printf("Heap free is %u bytes", heap_bytes_free()); #ifdef PBL_PLATFORM_APLITE GBitmap *bmp = gbitmap_create_with_png_data(download->data, download->length); #else GBitmap *bmp = gbitmap_create_from_png_data(download->data, download->length); #endif bitmap_layer_set_bitmap(bitmap_layer, bmp); // Save pointer to currently shown bitmap (to free it) if (current_bmp) { gbitmap_destroy(current_bmp); } current_bmp = bmp; // Free the memory now #ifdef PBL_PLATFORM_APLITE // gbitmap_create_with_png_data will free download->data #else free(download->data); #endif // We null it out now to avoid a double free download->data = NULL; netdownload_destroy(download); // Change tick handler to every minute now to save some battery tick_timer_service_unsubscribe(); tick_timer_service_subscribe(MINUTE_UNIT, tick_handler); time_t temp = time(NULL); last_check = localtime(&temp); }
const char *UpdateFreeText(void) { static char freeText[] = "0000000"; // Needs to be static because it's used by the system later. size_t bytesFree = heap_bytes_free(); IntToString(freeText, 7, bytesFree); return freeText; }
/* * Process clockface */ static void handle_minute_tick(struct tm *tick_time, TimeUnits units_changed) { #ifndef TESTING_MEMORY_LEAK // Only update the date if the day has changed if (tick_time->tm_mday != previous_mday) { strftime(date_text, sizeof(date_text), DATE_FORMAT, tick_time); if (!icon_state[IS_ALARM]) text_layer_set_text(ui.text_date_smart_alarm_range_layer, date_text); previous_mday = tick_time->tm_mday; } #else // Use the line to show heap space in testing mode snprintf(date_text, sizeof(date_text), "%d", heap_bytes_free()); text_layer_set_text(text_date_smart_alarm_range_layer, date_text); #endif // Perform all background processing uint16_t last_movement; if (is_animation_complete()) { last_movement = every_minute_processing(); } else { last_movement = CLOCK_UPDATE_THRESHOLD; } // Do the power nap countdown power_nap_countdown(); // Only update the clock every five minutes unless awake if (last_movement >= CLOCK_UPDATE_THRESHOLD || (tick_time->tm_min % 5 == 0)) { update_clock(); } }
void display_pinteract_dots_history(int16_t history_pi_code_in){ APP_LOG(APP_LOG_LEVEL_ERROR, "window start : heap size: used %d , free %d", heap_bytes_used(), heap_bytes_free()); history_pi_code = history_pi_code_in; day_offset = 1; // WHENEVER we access the main dash, we just want to clean everything up // window_stack_pop_all(false); // psleep(100); // NEEDED so OS clears prev window and frees RAM // get the points goal from the config file s_dots_history_window = window_create(); window_set_window_handlers(s_dots_history_window, (WindowHandlers){ .load = window_load, .unload = window_unload });
static void window_unload(Window* window){ // we sure to destroy the moving graphics!!! // Destroy all the graphics layer_destroy(s_dots_layer); text_layer_destroy(s_title_layer); // text_layer_destroy(s_dates_layer); // text_layer_destroy(s_day_layer); text_layer_destroy(s_axis_y_label_layer); for(int16_t i = 0; i < 7; i++){ text_layer_destroy(s_wday_layers[i]); } APP_LOG(APP_LOG_LEVEL_ERROR, "window unload : heap size: used %d , free %d", heap_bytes_used(), heap_bytes_free()); // psleep(100); }
uint32_t health_sum_timeframe(HealthMetric metric, time_t time_start, time_t time_end) { APP_LOG(APP_LOG_LEVEL_INFO, "Heap: %i", heap_bytes_free()); uint32_t output = 0; APP_LOG(APP_LOG_LEVEL_INFO, "Metric: %i", metric); if (health_service_metric_accessible(metric, time_start, time_end) == HealthServiceAccessibilityMaskAvailable) { HealthMinuteData * minute_data = malloc(sizeof(HealthMinuteData) * UPDATE_INTERVAL); time_t time_start_calc = time_start; while (time_start_calc < time_end && time_start_calc < time(NULL)) { time_t time_start_temp = time_start_calc; time_t time_end_temp = time_start_calc + UPDATE_INTERVAL*60; if (time_end_temp > time_end) { time_end_temp = time_end; } if (time_end_temp > time(NULL)) { time_end_temp = time(NULL); } APP_LOG(APP_LOG_LEVEL_DEBUG_VERBOSE, "start %lu", time_start_temp); APP_LOG(APP_LOG_LEVEL_DEBUG_VERBOSE, "end %lu", time_end_temp); uint32_t minutes_gotten = health_service_get_minute_history(minute_data, UPDATE_INTERVAL, &time_start_temp, &time_end_temp); APP_LOG(APP_LOG_LEVEL_DEBUG_VERBOSE, "-> start %lu", time_start_temp); APP_LOG(APP_LOG_LEVEL_DEBUG_VERBOSE, "-> end %lu", time_end_temp); APP_LOG(APP_LOG_LEVEL_DEBUG_VERBOSE, "mins gotten %lu", minutes_gotten); for (uint32_t i = 0; i < minutes_gotten; i++) { if (!minute_data[i].is_invalid) { output += minute_data[i].steps; } } APP_LOG(APP_LOG_LEVEL_DEBUG_VERBOSE, "output now %lu", output); time_start_calc += UPDATE_INTERVAL*60; } APP_LOG(APP_LOG_LEVEL_DEBUG, "OUTPUT: %lu", output); free(minute_data); } return output; }
void draw_full(Layer *layer, GContext *ctx) { unsigned int i; int realdaymin; #ifdef FORCESTARTAT APP_LOG(APP_LOG_LEVEL_DEBUG, "%d", daymin); #endif realdaymin = daymin - (SCREENWIDTH / 2); if(realdaymin < 0) realdaymin = MINSINDAY + realdaymin; graphics_context_set_compositing_mode(ctx, GCompOpSet); update_window_color(); #ifdef PROFILING int start, startms, end, endms; start = time(NULL); startms = time_ms(NULL, NULL); #endif // fill the screen with background graphic for(i = 0; i < SCREENWIDTH / 32 + 1; i++) { graphics_draw_bitmap_in_rect(ctx, bg, GRect(i * 32, 0, 32, 101)); } if(realdaymin <= MINSINDAY - SCREENWIDTH) { for(i = 0; i < SPRITECOUNT; i++) { // Consider sprites that wrap around past the end of a day. if(spritelist[i].rect.origin.x + spritelist[i].rect.size.w > MINSINDAY) { if(RANGE_TEST(realdaymin, realdaymin + SCREENWIDTH, spritelist[i].rect.origin.x - MINSINDAY, spritelist[i].rect.origin.x - MINSINDAY + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x - MINSINDAY - realdaymin, spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } } if(RANGE_TEST(realdaymin, realdaymin + SCREENWIDTH, spritelist[i].rect.origin.x, spritelist[i].rect.origin.x + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x - realdaymin, spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } } } else { for(i = 0; i < SPRITECOUNT; i++) { if(RANGE_TEST(realdaymin, MINSINDAY, spritelist[i].rect.origin.x, spritelist[i].rect.origin.x + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x - realdaymin, spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } else if (RANGE_TEST(0, SCREENWIDTH - (MINSINDAY - realdaymin), spritelist[i].rect.origin.x, spritelist[i].rect.origin.x + spritelist[i].rect.size.w)) { graphics_draw_bitmap_in_rect(ctx, bitmap_get(spritelist[i].res), GRect(spritelist[i].rect.origin.x + (MINSINDAY - realdaymin), spritelist[i].rect.origin.y, spritelist[i].rect.size.w, spritelist[i].rect.size.h)); } } } graphics_draw_bitmap_in_rect(ctx, pointergfx, GRect(SCREENWIDTH / 2 - 6, 0, 13, 7)); // Status bar stuff graphics_draw_bitmap_in_rect(ctx, status, GRect(2, SCREENHEIGHT - 15, 66, 13)); graphics_draw_bitmap_in_rect(ctx, weekdays[weekday], GRect(4, SCREENHEIGHT - 13, 23, 9)); if(day > 9) { graphics_draw_bitmap_in_rect(ctx, numbers[day / 10], GRect(31, SCREENHEIGHT - 13, 7, 9)); } graphics_draw_bitmap_in_rect(ctx, numbers[day % 10], GRect(39, SCREENHEIGHT - 13, 7, 9)); if(battlife <= BATT_MED_LEVEL) { graphics_draw_bitmap_in_rect(ctx, batteries[0], GRect(49, SCREENHEIGHT - 13, 7, 9)); } else if(battlife <= BATT_HIGH_LEVEL) { graphics_draw_bitmap_in_rect(ctx, batteries[1], GRect(49, SCREENHEIGHT - 13, 7, 9)); } else if(battlife <= BATT_FULL_LEVEL) { graphics_draw_bitmap_in_rect(ctx, batteries[2], GRect(49, SCREENHEIGHT - 13, 7, 9)); } else { graphics_draw_bitmap_in_rect(ctx, batteries[3], GRect(49, SCREENHEIGHT - 13, 7, 9)); } if(btstatus) { graphics_draw_bitmap_in_rect(ctx, bluetooth, GRect(59, SCREENHEIGHT - 13, 7, 9)); } #ifdef PROFILING // before bitmaps_clean() to get peak heap usage. APP_LOG(APP_LOG_LEVEL_DEBUG, "Heap free after draw: %d", heap_bytes_free()); #endif bitmaps_clean(); #ifdef PROFILING endms = time_ms(NULL, NULL); end = time(NULL); APP_LOG(APP_LOG_LEVEL_DEBUG, "Draw took %d milliseconds", ((end * 1000 + endms) - (start * 1000 + startms))); #endif }
void pge_init() { // Allocate for(int z = 0; z < GRID_DEPTH; z++) { for(int y = 0; y < GRID_HEIGHT; y++) { for(int x = 0; x < GRID_WIDTH; x++) { s_block_array[vec2i(Vec3(x, y, z))] = block_create(Vec3(x * BLOCK_SIZE, y * BLOCK_SIZE, z * BLOCK_SIZE), GSize(BLOCK_SIZE, BLOCK_SIZE), COLOR_INVISIBLE); } } } for(int i = 0; i < MAX_CLOUDS; i++) { s_cloud_array[i] = cloud_create(Vec3(0, 0, SKY_HEIGHT), GSize(BLOCK_SIZE, BLOCK_SIZE), Vec3(GRID_WIDTH * BLOCK_SIZE, GRID_HEIGHT * BLOCK_SIZE, SKY_HEIGHT)); } // Set up world generate_world(); // Set up engine pge_isometric_set_projection_offset(PBL_IF_ROUND_ELSE(GPoint(90, 110), GPoint(72, 80))); pge_isometric_set_enabled(true); pge_set_framerate(FRAME_RATE_IDLE); pge_begin(GColorBlack, logic, render, click); s_main_window = pge_get_window(); s_status_layer = text_layer_create(grect_inset( layer_get_bounds((window_get_root_layer(s_main_window))), PBL_IF_ROUND_ELSE(GEdgeInsets(30, 0, 130, 0), GEdgeInsets(0, 0, 150, 0)))); text_layer_set_background_color(s_status_layer, GColorBlack); text_layer_set_text_color(s_status_layer, GColorWhite); text_layer_set_text_alignment(s_status_layer, PBL_IF_ROUND_ELSE(GTextAlignmentCenter, GTextAlignmentLeft)); layer_add_child(window_get_root_layer(s_main_window), text_layer_get_layer(s_status_layer)); update_status_text(); #ifdef BENCHMARK APP_LOG(APP_LOG_LEVEL_INFO, "Heap free: %dB after creating %d blocks (Size: %dB)", (int)heap_bytes_free(), (GRID_WIDTH * GRID_HEIGHT * GRID_DEPTH), get_world_size()); #endif }
static void window_load(Window* window){ // NOTE!!, we are essentially trying to immitate Misfit and jawbone, // so white text on black background Layer* window_layer = window_get_root_layer(window); GRect window_bounds = layer_get_bounds(window_layer); window_set_background_color(window, GColorBlack); time_t init_t = time(NULL); // run the tick handler once to update everything struct tm *tick_time = localtime( &init_t ); num_bars = 7; axis_x = window_bounds.size.w -1; bar_w = ((window_bounds.size.w*23/24 )/num_bars); // pinteract 11 & 1 mid_y = window_bounds.size.h/2 + 5; step_h = (window_bounds.size.h*10/12)/5; // add title layer s_title_layer = text_layer_create(GRect(5,1,window_bounds.size.w-5,21)); text_layer_set_text_alignment(s_title_layer, GTextAlignmentLeft); text_layer_set_font(s_title_layer,fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); text_layer_set_background_color(s_title_layer, GColorBlack); text_layer_set_text_color(s_title_layer, GColorWhite); layer_add_child(window_layer, text_layer_get_layer(s_title_layer)); // add the y axis label s_axis_y_label_layer = text_layer_create(GRect(axis_x-41,mid_y-21,40,21)); text_layer_set_text_alignment(s_axis_y_label_layer, GTextAlignmentRight); text_layer_set_font(s_axis_y_label_layer,fonts_get_system_font(FONT_KEY_GOTHIC_18)); text_layer_set_background_color(s_axis_y_label_layer, GColorBlack); text_layer_set_text_color(s_axis_y_label_layer, GColorWhite); layer_add_child(window_layer, text_layer_get_layer(s_axis_y_label_layer)); set_title_dates_y_axis_label(); char* weekday[7]; weekday[0] = "Su"; weekday[1] = "Mo"; weekday[2] = "Tu"; weekday[3] = "We"; weekday[4] = "Th"; weekday[5] = "Fr"; weekday[6] = "Sa"; for(int8_t i = 0; i < num_bars; i++){ s_wday_layers[i] = text_layer_create(GRect( (num_bars-1-i)*bar_w + 5 , window_bounds.size.h-18,20,18) ); text_layer_set_text_alignment(s_wday_layers[i], GTextAlignmentCenter); text_layer_set_font(s_wday_layers[i],fonts_get_system_font(FONT_KEY_GOTHIC_18)); text_layer_set_background_color(s_wday_layers[i], GColorBlack); text_layer_set_text_color(s_wday_layers[i], GColorWhite); text_layer_set_text(s_wday_layers[i], weekday[ (tick_time->tm_wday -i -1+7)%7 ]); layer_add_child(window_layer, text_layer_get_layer(s_wday_layers[i])); } // ADD THE MOVING GRAPHICS MUST BE AT TOP OF LAYER STACK s_dots_layer = layer_create(window_bounds); layer_set_update_proc(s_dots_layer, dots_layer_update_proc); // layer_set_background_color(s_points_layer, GColorBlack); layer_add_child(window_layer, s_dots_layer); layer_mark_dirty(s_dots_layer); APP_LOG(APP_LOG_LEVEL_ERROR, "window load : heap size: used %d , free %d", heap_bytes_used(), heap_bytes_free()); }
//Hippo Command, I put my pants on backwards! void handle_init(void) { APP_LOG(APP_LOG_LEVEL_DEBUG, "INIT MEMORY: %u bytes used, %u bytes free", (unsigned) heap_bytes_used(), (unsigned) heap_bytes_free()); // TODO: restore this once done profiling #ifndef LOCK_SHIP srand(time(NULL)); load_holomesh(rand() % c_craft_info_count); #else load_holomesh(LOCK_SHIP); #endif APP_LOG(APP_LOG_LEVEL_DEBUG, "UI MEMORY: %u bytes used, %u bytes free", (unsigned) heap_bytes_used(), (unsigned) heap_bytes_free()); my_window = window_create(); window_set_background_color(my_window, GColorBlack); GRect logoRect = GRect(0, 12, c_viewportWidth, c_viewportWidth); logoLayer = bitmap_layer_create(logoRect); bitmap_layer_set_bitmap(logoLayer, logoBitmap); layer_add_child(window_get_root_layer(my_window), bitmap_layer_get_layer(logoLayer)); // Fonts g_font_sw = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_14)); g_font_sw_symbol = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_SYMBOL_14)); g_font_time = fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD); g_font_info = fonts_get_system_font(FONT_KEY_GOTHIC_14); // Paint layer frameBufferLayer = bitmap_layer_create(GRect(0, 0, c_viewportWidth, c_viewportHeight)); layer_add_child(window_get_root_layer(my_window), bitmap_layer_get_layer(frameBufferLayer)); frameBufferBitmap = gbitmap_create_blank_with_palette( GSize(c_viewportWidth, c_viewportHeight), GBitmapFormat2BitPalette, c_palette, false); bitmap_layer_set_bitmap(frameBufferLayer, frameBufferBitmap); bitmap_layer_set_compositing_mode(frameBufferLayer, GCompOpSet); paint(); GRect layerSize = GRect(0, 0, c_viewportWidth, c_viewportHeight); // Two small text layers textLayer = text_layer_create(layerSize); text_layer_set_background_color(textLayer, GColorClear); text_layer_set_text_color(textLayer, GColorYellow); text_layer_set_font(textLayer, g_font_sw); layer_add_child(window_get_root_layer(my_window), text_layer_get_layer(textLayer)); //Jet Force Push-up, you silly-billy. textLayerSym = text_layer_create(layerSize); text_layer_set_background_color(textLayerSym, GColorClear); text_layer_set_text_color(textLayerSym, GColorYellow); text_layer_set_font(textLayerSym, g_font_sw_symbol); layer_set_hidden(text_layer_get_layer(textLayerSym), true); layer_add_child(window_get_root_layer(my_window), text_layer_get_layer(textLayerSym)); //Hippo Command, I also put my watch on backwards! // Info text layer infoTextLayer = text_layer_create(layerSize); text_layer_set_background_color(infoTextLayer, GColorClear); text_layer_set_text_color(infoTextLayer, GColorYellow); text_layer_set_font(infoTextLayer, g_font_info); layer_add_child(window_get_root_layer(my_window), text_layer_get_layer(infoTextLayer)); // Time GSize timeSize = graphics_text_layout_get_content_size( "00:00 AM", g_font_time, layerSize, 0, GTextAlignmentLeft); GRect timeRect = { GPoint(DT_EDGE_PAD, c_viewportHeight - timeSize.h), GSize(c_viewportWidth, timeSize.h) }; timeLayer = text_layer_create(timeRect); text_layer_set_background_color(timeLayer, GColorClear); text_layer_set_text_color(timeLayer, GColorYellow); text_layer_set_font(timeLayer, g_font_time); //text_layer_set_text(timeLayer, "23:45 AM"); layer_add_child(window_get_root_layer(my_window), text_layer_get_layer(timeLayer)); // Date dateLayer = text_layer_create(layerSize); text_layer_set_background_color(dateLayer, GColorClear); text_layer_set_text_color(dateLayer, GColorYellow); text_layer_set_font(dateLayer, g_font_info); layer_add_child(window_get_root_layer(my_window), text_layer_get_layer(dateLayer)); time_t t = time(NULL); update_time_display(localtime(&t)); update_date_display(localtime(&t)); update_title_and_info(); APP_LOG(APP_LOG_LEVEL_DEBUG, "FINAL MEMORY: %u bytes used, %u bytes free", (unsigned) heap_bytes_used(), (unsigned) heap_bytes_free()); window_stack_push(my_window, true); tick_timer_service_subscribe(SECOND_UNIT | MINUTE_UNIT, tick_handler); g_timer = app_timer_register(c_refreshTimer, animation_timer_trigger, NULL); accel_data_service_subscribe(c_accelSampleCount, accel_data_handler); accel_service_set_sampling_rate(ACCEL_SAMPLING_25HZ); }
void UpdateMinFreeMemory() { size_t bytesFree = heap_bytes_free(); if(bytesFree < minMemoryFree) minMemoryFree = bytesFree; }