refactor(1)
[carveJwlIkooP6JGAAIwe30JlM.git] / addon.c
diff --git a/addon.c b/addon.c
index d408654100b3d5c5a8a0d66c7e7a45993c59fe08..0346d01fc2d4b906fb915a6f7ded777220426ff0 100644 (file)
--- a/addon.c
+++ b/addon.c
@@ -73,6 +73,51 @@ static u32 addon_match( enum workshop_file_type type,
 static void addon_system_init( void ){
    u32 reg_size   = sizeof(addon_reg)*ADDON_MOUNTED_MAX;
    addon_system.registry = vg_linear_alloc( vg_mem.rtmemory, reg_size );
+
+   struct cache_inf {
+      size_t stride;
+      u32 count;
+   }
+   static cache_inf[] = {
+      [k_workshop_file_type_board] = { 
+         .stride = sizeof(struct player_board),
+         .count  = CACHE_BOARD_MAX 
+      },
+      [k_workshop_file_type_player] = {
+         .stride = sizeof(struct player_model),
+         .count  = CACHE_PLAYER_MAX
+      }
+   };
+
+   for( u32 i=0; i<vg_list_size(cache_inf); i++ ){
+      struct cache_inf *inf = &cache_inf[i];
+      struct addon_cache *cache = &addon_system.cache[i];
+
+      if( inf->count ){
+         /* create the allocations pool */
+         u32 alloc_size = sizeof(struct addon_cache_entry)*inf->count;
+         cache->allocs = vg_linear_alloc( vg_mem.rtmemory, alloc_size );
+         memset( cache->allocs, 0, alloc_size );
+
+         cache->pool.buffer = cache->allocs;
+         cache->pool.count  = inf->count;
+         cache->pool.stride = sizeof( struct addon_cache_entry );
+         cache->pool.offset = offsetof( struct addon_cache_entry, poolnode );
+         vg_pool_init( &cache->pool );
+
+         /* create the real memory */
+         u32 cache_size = inf->stride*inf->count;
+         cache->items = vg_linear_alloc( vg_mem.rtmemory, cache_size );
+         cache->stride = inf->stride;
+         memset( cache->items, 0, cache_size );
+
+         for( i32 j=0; j<inf->count; j++ ){
+            struct addon_cache_entry *alloc = &cache->allocs[j];
+            alloc->reg_ptr   = NULL;
+            alloc->reg_index = 0xffffffff;
+         }
+      }
+   }
 }
 
 /*
@@ -113,7 +158,7 @@ VG_STATIC addon_reg *addon_alloc_reg( PublishedFileId_t workshop_id,
 
    addon_reg *reg = &addon_system.registry[ addon_system.registry_count ];
    reg->metadata_len = 0;
-   reg->userdata = NULL;
+   reg->cache_id = 0;
    reg->state = k_addon_state_indexed;
    reg->workshop_id = workshop_id;
    reg->foldername[0] = '\0';
@@ -163,7 +208,7 @@ VG_STATIC void addon_print_info( addon_reg *reg ){
    vg_info( "  workshop_id: " PRINTF_U64 "\n", reg->workshop_id );
    vg_info( "  folder: [%u]%s\n", reg->foldername_hash, reg->foldername );
    vg_info( "  metadata_len: %u\n", reg->metadata_len );
-   vg_info( "  userdata: %p\n", reg->userdata );
+   vg_info( "  cache_id: %hu\n", reg->cache_id );
    vg_info( "}\n" );
 }
 
@@ -411,4 +456,63 @@ static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){
    }
 }
 
+static u16 addon_cache_fetch( enum workshop_file_type type, u32 reg_index ){
+   vg_assert_thread( k_thread_purpose_main );
+
+   addon_reg *reg = NULL;
+
+   if( reg_index < addon_count( type ) ){
+      reg = get_addon_from_index( type, reg_index );
+      if( reg->cache_id ) 
+         return reg->cache_id;
+   }
+
+   return 0;
+}
+
+static u16 addon_cache_alloc( enum workshop_file_type type, u32 reg_index ){
+   struct addon_cache *cache = &addon_system.cache[ type ];
+
+   u16 new_id = vg_pool_lru( &cache->pool );
+   struct addon_cache_entry *new_entry = vg_pool_item( &cache->pool, new_id );
+
+   addon_reg *reg = NULL;
+   if( reg_index < addon_count( type ) )
+      reg = get_addon_from_index( type, reg_index );
+
+   if( new_entry ){
+      if( new_entry->reg_ptr )
+         new_entry->reg_ptr->cache_id = 0;
+
+      if( reg )
+         reg->cache_id = new_id;
+
+      new_entry->reg_ptr = reg;
+      new_entry->reg_index = reg_index;
+      return new_id;
+   }
+   else{
+      vg_error( "cache full (type: %u)!\n", type );
+      return 0;
+   }
+}
+
+static void *addon_cache_item( enum workshop_file_type type, u16 id ){
+   if( !id ) return NULL;
+
+   struct addon_cache *cache = &addon_system.cache[type];
+   return cache->items + ((size_t)(id-1) * cache->stride);
+}
+
+static void *addon_cache_item_if_loaded( enum workshop_file_type type, u16 id ){
+   if( !id ) return NULL;
+
+   struct addon_cache *cache = &addon_system.cache[type];
+   struct addon_cache_entry *entry = vg_pool_item( &cache->pool, id );
+
+   if( entry->state == k_addon_cache_state_loaded )
+      return addon_cache_item( type, id );
+   else return NULL;
+}
+
 #endif /* ADDON_C */