Skip to content

Commit b6fd7eb

Browse files
committed
fuck it.
Signed-off-by: Katharine Berry <[email protected]>
1 parent 4d547d0 commit b6fd7eb

File tree

6 files changed

+71
-89
lines changed

6 files changed

+71
-89
lines changed

app/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,11 @@
491491
"targetPlatforms": [
492492
"diorite"
493493
]
494+
},
495+
{
496+
"file": "images/skull.pdc",
497+
"name": "IMAGE_SKULL",
498+
"type": "raw"
494499
}
495500
]
496501
}

app/resources/images/skull.pdc

201 Bytes
Binary file not shown.

app/src/c/converse/segments/widgets/map.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <pebble.h>
1818
#include "../../../image_manager/image_manager.h"
1919
#include "../../../util/memory/sdk.h"
20+
#include "../../../util/thinking_layer.h"
2021

2122
#include "map.h"
2223

@@ -26,6 +27,8 @@ static void prv_layer_update(Layer *layer, GContext *ctx);
2627
typedef struct {
2728
ConversationEntry* entry;
2829
GBitmap* bitmap;
30+
ThinkingLayer* loading_layer;
31+
GDrawCommandImage *skull_image;
2932
} MapWidgetData;
3033

3134
static inline int prv_get_image_id(MapWidgetData *data) {
@@ -39,6 +42,8 @@ MapWidget* map_widget_create(GRect rect, ConversationEntry* entry) {
3942
MapWidgetData* data = layer_get_data(layer);
4043
data->entry = entry;
4144
data->bitmap = NULL;
45+
data->loading_layer = thinking_layer_create(GRect(rect.size.w / 2 - THINKING_LAYER_WIDTH / 2, image_size.h / 2 - THINKING_LAYER_HEIGHT / 2, THINKING_LAYER_WIDTH, THINKING_LAYER_HEIGHT));
46+
layer_add_child(layer, data->loading_layer);
4247
image_manager_register_callback(image_id, prv_image_updated, layer);
4348
layer_set_update_proc(layer, prv_layer_update);
4449
return layer;
@@ -54,6 +59,12 @@ void map_widget_destroy(MapWidget* layer) {
5459
if (data->bitmap) {
5560
gbitmap_destroy(data->bitmap);
5661
}
62+
if (data->loading_layer) {
63+
thinking_layer_destroy(data->loading_layer);
64+
}
65+
if (data->skull_image) {
66+
gdraw_command_image_destroy(data->skull_image);
67+
}
5768
int image_id = prv_get_image_id(data);
5869
image_manager_unregister_callback(image_id);
5970
layer_destroy(layer);
@@ -67,13 +78,26 @@ static void prv_image_updated(int image_id, ImageStatus status, void *context) {
6778
Layer *layer = context;
6879
MapWidgetData* data = layer_get_data(layer);
6980
if (status == ImageStatusCompleted) {
81+
if (data->loading_layer) {
82+
layer_remove_from_parent(data->loading_layer);
83+
thinking_layer_destroy(data->loading_layer);
84+
data->loading_layer = NULL;
85+
}
7086
if (data->bitmap) {
7187
gbitmap_destroy(data->bitmap);
7288
}
7389
data->bitmap = image_manager_get_image(image_id);
7490
layer_mark_dirty(layer);
7591
} else if (status == ImageStatusDestroyed) {
92+
if (data->loading_layer) {
93+
layer_remove_from_parent(data->loading_layer);
94+
thinking_layer_destroy(data->loading_layer);
95+
data->loading_layer = NULL;
96+
}
7697
data->bitmap = NULL;
98+
if (!data->skull_image) {
99+
data->skull_image = bgdraw_command_image_create_with_resource(RESOURCE_ID_IMAGE_SKULL);
100+
}
77101
layer_mark_dirty(layer);
78102
}
79103
}
@@ -100,5 +124,9 @@ static void prv_layer_update(Layer *layer, GContext *ctx) {
100124
} else {
101125
graphics_context_set_fill_color(ctx, COLOR_FALLBACK(GColorLightGray, GColorWhite));
102126
graphics_fill_rect(ctx, image_rect, 0, GCornerNone);
127+
if (data->skull_image) {
128+
GSize skull_size = gdraw_command_image_get_bounds_size(data->skull_image);
129+
gdraw_command_image_draw(ctx, data->skull_image, GPoint(image_rect.origin.x + image_rect.size.w / 2 - skull_size.w / 2, image_rect.origin.y + image_rect.size.h / 2 - skull_size.h / 2));
130+
}
103131
}
104132
}

app/src/c/image_manager/image_manager.c

Lines changed: 26 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,19 @@ typedef struct {
3636

3737
static void prv_inbox_received(DictionaryIterator *iterator, void *context);
3838
static ManagedImage *prv_find_image(int image_id);
39-
static int16_t prv_find_image_index(int image_id);
40-
static bool prv_image_id_compare(void *image_id, void *object);
41-
static void prv_destroy_image(ManagedImage *image);
42-
static bool prv_foreach_destroy(void *object, void *context);
39+
static void prv_destroy_image();
4340
static void prv_handle_new_image(int image_id, size_t size, DictionaryIterator *iterator);
4441
static void prv_handle_image_chunk(int image_id, size_t offset, DictionaryIterator *iterator);
4542
static void prv_handle_image_complete(int image_id);
46-
static bool prv_handle_memory_pressure(void *context);
4743

44+
45+
static ManagedImage s_managed_image = {0};
46+
static uint8_t s_image_storage[PBL_IF_COLOR_ELSE(3800, 1900)] = {0};
4847
static EventHandle *s_appmessage_handle;
49-
static LinkedRoot *s_image_list;
50-
static ManagedImage *s_cached_image_ref = NULL;
5148

5249
void image_manager_init() {
53-
s_image_list = linked_list_create_root();
5450
events_app_message_request_inbox_size(1024);
5551
s_appmessage_handle = events_app_message_register_inbox_received(prv_inbox_received, NULL);
56-
memory_pressure_register_callback(prv_handle_memory_pressure, 0, NULL);
5752
}
5853

5954
void image_manager_deinit() {
@@ -94,63 +89,32 @@ GSize image_manager_get_size(int image_id) {
9489
}
9590

9691
void image_manager_destroy_image(int image_id) {
97-
int16_t image_idx = prv_find_image_index(image_id);
98-
if (image_idx < 0) {
92+
if (s_managed_image.image_id != image_id) {
9993
return;
10094
}
101-
ManagedImage *image = linked_list_get(s_image_list, image_idx);
102-
prv_destroy_image(image);
103-
linked_list_remove(s_image_list, image_idx);
95+
prv_destroy_image();
10496
}
10597

10698
void image_manager_destroy_all_images() {
107-
linked_list_foreach(s_image_list, prv_foreach_destroy, NULL);
108-
linked_list_clear(s_image_list);
99+
prv_destroy_image();
109100
}
110101

111102
static ManagedImage *prv_find_image(int image_id) {
112-
if (s_cached_image_ref != NULL && s_cached_image_ref->image_id == image_id) {
113-
return s_cached_image_ref;
114-
}
115-
int16_t idx = prv_find_image_index(image_id);
116-
if (idx >= 0) {
117-
return linked_list_get(s_image_list, idx);
103+
if (s_managed_image.image_id != image_id) {
104+
return NULL;
118105
}
119-
return NULL;
120-
}
121-
122-
static int16_t prv_find_image_index(int image_id) {
123-
return linked_list_find_compare(s_image_list, &image_id, prv_image_id_compare);
106+
return &s_managed_image;
124107
}
125108

126-
static bool prv_image_id_compare(void *image_id, void *object) {
127-
ManagedImage *image = object;
128-
return image->image_id == *(int *)image_id;
129-
}
130-
131-
static void prv_destroy_image(ManagedImage *image) {
132-
image->status = ImageStatusDestroyed;
133-
if (image->callback) {
134-
image->callback(image->image_id, ImageStatusDestroyed, image->context);
135-
}
136-
if (image->bitmap) {
137-
gbitmap_destroy(image->bitmap);
138-
image->bitmap = NULL;
109+
static void prv_destroy_image() {
110+
s_managed_image.status = ImageStatusDestroyed;
111+
if (s_managed_image.callback) {
112+
s_managed_image.callback(s_managed_image.image_id, ImageStatusDestroyed, s_managed_image.context);
139113
}
140-
if (image->data) {
141-
free(image->data);
142-
image->data = NULL;
114+
if (s_managed_image.bitmap) {
115+
gbitmap_destroy(s_managed_image.bitmap);
116+
s_managed_image.bitmap = NULL;
143117
}
144-
if (s_cached_image_ref == image) {
145-
s_cached_image_ref = NULL;
146-
}
147-
free(image);
148-
}
149-
150-
static bool prv_foreach_destroy(void *object, void *context) {
151-
ManagedImage *image = object;
152-
prv_destroy_image(image);
153-
return true;
154118
}
155119

156120
static void prv_inbox_received(DictionaryIterator *iterator, void *context) {
@@ -183,19 +147,16 @@ static void prv_handle_new_image(int image_id, size_t size, DictionaryIterator *
183147
tuple = dict_find(iterator, MESSAGE_KEY_IMAGE_HEIGHT);
184148
int16_t height = tuple->value->int32;
185149
BOBBY_LOG(APP_LOG_LEVEL_DEBUG, "New image: %d, size: %d, width: %d, height: %d", image_id, size, width, height);
186-
ManagedImage *image = bmalloc(sizeof(ManagedImage));
187-
if (!image) {
188-
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Failed to allocate memory for image");
189-
return;
150+
if (s_managed_image.image_id != 0) {
151+
prv_destroy_image();
190152
}
191-
image->image_id = image_id;
192-
image->status = ImageStatusCreated;
193-
image->callback = NULL;
194-
image->data = bmalloc(size);
195-
image->size = size;
196-
image->bitmap = NULL;
197-
image->image_size = GSize(width, height);
198-
linked_list_append(s_image_list, image);
153+
s_managed_image.image_id = image_id;
154+
s_managed_image.status = ImageStatusCreated;
155+
s_managed_image.callback = NULL;
156+
s_managed_image.data = s_image_storage;
157+
s_managed_image.size = size;
158+
s_managed_image.bitmap = NULL;
159+
s_managed_image.image_size = GSize(width, height);
199160
}
200161

201162
static void prv_handle_image_chunk(int image_id, size_t offset, DictionaryIterator *iterator) {
@@ -245,15 +206,3 @@ static void prv_handle_image_complete(int image_id) {
245206
image->callback(image->image_id, ImageStatusCompleted, image->context);
246207
}
247208
}
248-
249-
250-
static bool prv_handle_memory_pressure(void *context) {
251-
if (linked_list_count(s_image_list) == 0) {
252-
return false;
253-
}
254-
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Memory pressure! Destroying the oldest image.");
255-
ManagedImage *image = linked_list_get(s_image_list, 0);
256-
prv_destroy_image(image);
257-
linked_list_remove(s_image_list, 0);
258-
return true;
259-
}

app/src/c/util/memory/malloc.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,19 @@
2323
void *bmalloc(size_t size) {
2424
int heap_size = heap_bytes_free();
2525
BOBBY_LOG(APP_LOG_LEVEL_DEBUG, "malloc request: %d; free: %d", size, heap_size);
26-
void *ptr = malloc(size);
27-
if (ptr) {
28-
return ptr;
29-
}
30-
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Out of memory! Need to allocate %d bytes; %d bytes free.", size, heap_size);
3126
while (true) {
32-
void *ptr = malloc(size);
33-
if (ptr) {
34-
return ptr;
27+
if (heap_bytes_free() > 750) {
28+
void *ptr = malloc(size);
29+
if (ptr) {
30+
return ptr;
31+
}
32+
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Out of memory! Need to allocate %d bytes; %d bytes free.", size, heap_size);
33+
} else {
34+
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Low memory (%d byte free); trying to free some before allocating %d bytes.", heap_size, size);
3535
}
3636
if (!memory_pressure_try_free()) {
3737
BOBBY_LOG(APP_LOG_LEVEL_ERROR, "Failed to allocate memory: couldn't free enough heap.");
38-
return NULL;
38+
return malloc(size);
3939
}
4040
int new_heap_size = heap_bytes_free();
4141
BOBBY_LOG(APP_LOG_LEVEL_INFO, "Freed %d bytes, heap size is now %d. Retrying allocation of %d bytes.", heap_size - new_heap_size, new_heap_size, size);

app/src/c/util/memory/pressure.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,16 @@ void memory_pressure_unregister_callback(MemoryPressureHandler handler) {
6868

6969
bool memory_pressure_try_free() {
7070
BOBBY_LOG(APP_LOG_LEVEL_WARNING, "Memory emergency! Trying to free memory.");
71-
int priority = 0;
7271
int count = linked_list_count(s_callback_list);
7372
if (count == 0) {
7473
BOBBY_LOG(APP_LOG_LEVEL_DEBUG, "No memory freeing callbacks registered");
7574
return false;
7675
}
77-
for (int p = 0; p < s_max_priority; ++p) {
76+
for (int p = 0; p <= s_max_priority; ++p) {
77+
BOBBY_LOG(APP_LOG_LEVEL_DEBUG, "Trying priority level %d", p);
7878
for (int i = 0; i < count; ++i) {
7979
MemoryPressureCallbackEntry *entry = linked_list_get(s_callback_list, i);
80-
if (entry->priority != priority) {
80+
if (entry->priority != p) {
8181
continue;
8282
}
8383
BOBBY_LOG(APP_LOG_LEVEL_DEBUG, "Calling memory pressure callback %p with priority %d", entry->handler, entry->priority);

0 commit comments

Comments
 (0)