<commit_before>#include "simply_menu.h"

#include "simply_res.h"
#include "simply_msg.h"
#include "simply_window_stack.h"

#include "simply.h"

#include "util/menu_layer.h"

#include <pebble.h>

#define MAX_CACHED_SECTIONS 10

#define MAX_CACHED_ITEMS 6

#define REQUEST_DELAY_MS 10

static char EMPTY_TITLE[] = "";

static bool section_filter(List1Node *node, void *data) {
  SimplyMenuCommon *section = (SimplyMenuCommon*) node;
  uint16_t section_index = (uint16_t)(uintptr_t) data;
  return (section->section == section_index);
}

static bool item_filter(List1Node *node, void *data) {
  SimplyMenuItem *item = (SimplyMenuItem*) node;
  uint32_t cell_index = (uint32_t)(uintptr_t) data;
  uint16_t section_index = cell_index;
  uint16_t row = cell_index >> 16;
  return (item->section == section_index && item->item == row);
}

static SimplyMenuSection *get_menu_section(SimplyMenu *self, int index) {
  return (SimplyMenuSection*) list1_find(self->menu_layer.sections, section_filter, (void*)(uintptr_t) index);
}

static void destroy_section(SimplyMenu *self, SimplyMenuSection *section) {
  if (!section) { return; }
  list1_remove(&self->menu_layer.sections, &section->node);
  if (section->title && section->title != EMPTY_TITLE) {
    free(section->title);
    section->title = NULL;
  }
  free(section);
}

static void destroy_section_by_index(SimplyMenu *self, int section) {
  destroy_section(self, (SimplyMenuSection*) list1_find(
        self->menu_layer.sections, section_filter, (void*)(uintptr_t) section));
}

static SimplyMenuItem *get_menu_item(SimplyMenu *self, int section, int index) {
  uint32_t cell_index = section | (index << 16);
  return (SimplyMenuItem*) list1_find(self->menu_layer.items, item_filter, (void*)(uintptr_t) cell_index);
}

static void destroy_item(SimplyMenu *self, SimplyMenuItem *item) {
  if (!item) { return; }
  list1_remove(&self->menu_layer.items, &item->node);
  if (item->title) {
    free(item->title);
    item->title = NULL;
  }
  if (item->subtitle) {
    free(item->subtitle);
    item->subtitle = NULL;
  }
  free(item);
}

static void destroy_item_by_index(SimplyMenu *self, int section, int index) {
  uint32_t cell_index = section | (index << 16);
  destroy_item(self, (SimplyMenuItem*) list1_find(
        self->menu_layer.items, item_filter, (void*)(uintptr_t) cell_index));
}

static void add_section(SimplyMenu *self, SimplyMenuSection *section) {
  if (list1_size(self->menu_layer.sections) >= MAX_CACHED_SECTIONS) {
    destroy_section(self, (SimplyMenuSection*) list1_last(self->menu_layer.sections));
  }
  destroy_section_by_index(self, section->section);
  list1_append(&self->menu_layer.sections, &section->node);
}

static void add_item(SimplyMenu *self, SimplyMenuItem *item) {
  if (list1_size(self->menu_layer.items) >= MAX_CACHED_ITEMS) {
    destroy_item(self, (SimplyMenuItem*) list1_last(self->menu_layer.items));
  }
  destroy_item_by_index(self, item->section, item->item);
  list1_append(&self->menu_layer.items, &item->node);
}

static void request_menu_section(SimplyMenu *self, uint16_t section_index) {
  SimplyMenuSection *section = get_menu_section(self, section_index);
  if (section) {
    return;
  }
  section = malloc(sizeof(*section));
  *section = (SimplyMenuSection) {
    .section = section_index,
  };
  add_section(self, section);
  simply_msg_menu_get_section(self->window.simply->msg, section_index);
}

static void request_menu_item(SimplyMenu *self, uint16_t section_index, uint16_t item_index) {
  SimplyMenuItem *item = get_menu_item(self, section_index, item_index);
  if (item) {
    return;
  }
  item = malloc(sizeof(*item));<commit_msg>Fix menu to prepend new items into cache<commit_after>#include "simply_menu.h"

#include "simply_res.h"
#include "simply_msg.h"
#include "simply_window_stack.h"

#include "simply.h"

#include "util/menu_layer.h"

#include <pebble.h>

#define MAX_CACHED_SECTIONS 10

#define MAX_CACHED_ITEMS 6

#define REQUEST_DELAY_MS 10

static char EMPTY_TITLE[] = "";

static bool section_filter(List1Node *node, void *data) {
  SimplyMenuCommon *section = (SimplyMenuCommon*) node;
  uint16_t section_index = (uint16_t)(uintptr_t) data;
  return (section->section == section_index);
}

static bool item_filter(List1Node *node, void *data) {
  SimplyMenuItem *item = (SimplyMenuItem*) node;
  uint32_t cell_index = (uint32_t)(uintptr_t) data;
  uint16_t section_index = cell_index;
  uint16_t row = cell_index >> 16;
  return (item->section == section_index && item->item == row);
}

static SimplyMenuSection *get_menu_section(SimplyMenu *self, int index) {
  return (SimplyMenuSection*) list1_find(self->menu_layer.sections, section_filter, (void*)(uintptr_t) index);
}

static void destroy_section(SimplyMenu *self, SimplyMenuSection *section) {
  if (!section) { return; }
  list1_remove(&self->menu_layer.sections, &section->node);
  if (section->title && section->title != EMPTY_TITLE) {
    free(section->title);
    section->title = NULL;
  }
  free(section);
}

static void destroy_section_by_index(SimplyMenu *self, int section) {
  destroy_section(self, (SimplyMenuSection*) list1_find(
        self->menu_layer.sections, section_filter, (void*)(uintptr_t) section));
}

static SimplyMenuItem *get_menu_item(SimplyMenu *self, int section, int index) {
  uint32_t cell_index = section | (index << 16);
  return (SimplyMenuItem*) list1_find(self->menu_layer.items, item_filter, (void*)(uintptr_t) cell_index);
}

static void destroy_item(SimplyMenu *self, SimplyMenuItem *item) {
  if (!item) { return; }
  list1_remove(&self->menu_layer.items, &item->node);
  if (item->title) {
    free(item->title);
    item->title = NULL;
  }
  if (item->subtitle) {
    free(item->subtitle);
    item->subtitle = NULL;
  }
  free(item);
}

static void destroy_item_by_index(SimplyMenu *self, int section, int index) {
  uint32_t cell_index = section | (index << 16);
  destroy_item(self, (SimplyMenuItem*) list1_find(
        self->menu_layer.items, item_filter, (void*)(uintptr_t) cell_index));
}

static void add_section(SimplyMenu *self, SimplyMenuSection *section) {
  if (list1_size(self->menu_layer.sections) >= MAX_CACHED_SECTIONS) {
    destroy_section(self, (SimplyMenuSection*) list1_last(self->menu_layer.sections));
  }
  destroy_section_by_index(self, section->section);
  list1_prepend(&self->menu_layer.sections, &section->node);
}

static void add_item(SimplyMenu *self, SimplyMenuItem *item) {
  if (list1_size(self->menu_layer.items) >= MAX_CACHED_ITEMS) {
    destroy_item(self, (SimplyMenuItem*) list1_last(self->menu_layer.items));
  }
  destroy_item_by_index(self, item->section, item->item);
  list1_prepend(&self->menu_layer.items, &item->node);
}

static void request_menu_section(SimplyMenu *self, uint16_t section_index) {
  SimplyMenuSection *section = get_menu_section(self, section_index);
  if (section) {
    return;
  }
  section = malloc(sizeof(*section));
  *section = (SimplyMenuSection) {
    .section = section_index,
  };
  add_section(self, section);
  simply_msg_menu_get_section(self->window.simply->msg, section_index);
}

static void request_menu_item(SimplyMenu *self, uint16_t section_index, uint16_t item_index) {
  SimplyMenuItem *item = get_menu_item(self, section_index, item_index);
  if (item) {
    return;
  }
  item = malloc(sizeof(*item));
{'fraction_non_alphanumeric': 0.13398826579342338, 'fraction_numerical': 0.012825760676763541, 'mean_word_length': 5.615523465703971, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1845399', 'n_tokens_mistral': 2615, 'n_tokens_neox': 2574, 'n_words': 502}