more refactors..
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_skateshop.c
index 99f9a7079d0ce6b6ead4021729f24f72a2d394ca..9bee505bc1412c124330ca33a9830d673f03b4ef 100644 (file)
@@ -14,6 +14,7 @@
 #include "highscores.h"
 #include "steam.h"
 #include "addon.h"
+#include "save.h"
 
 /*
  * Checks string equality but does a hash check first
@@ -42,22 +43,9 @@ VG_STATIC struct cache_board *skateshop_cache_fetch_board( u32 registry_index )
       }
    }
 
-   /* lru eviction. should be a linked list maybe... */
-   double min_time = 1e300;
-   struct cache_board *min_board = NULL;
-
-   SDL_AtomicLock( &global_skateshop.sl_cache_access );
-   for( u32 i=0; i<SKATESHOP_BOARD_CACHE_MAX; i++ ){
-      struct cache_board *cache_ptr = &global_skateshop.cache[i];
-
-      if( cache_ptr->state == k_cache_board_state_load_request ) continue;
-      if( cache_ptr->ref_count ) continue;
-
-      if( cache_ptr->last_use_time < min_time ){
-         min_time = cache_ptr->last_use_time;
-         min_board = cache_ptr;
-      }
-   }
+   SDL_AtomicLock( &addon_system.sl_cache );
+   struct cache_board *min_board = 
+      vg_pool_lru( &addon_system.board_cache );
 
    if( min_board ){
       if( min_board->state == k_cache_board_state_loaded ){
@@ -75,15 +63,13 @@ VG_STATIC struct cache_board *skateshop_cache_fetch_board( u32 registry_index )
 
       min_board->reg_ptr = reg;
       min_board->reg_index = registry_index;
-      min_board->last_use_time = vg.time;
-      min_board->ref_count = 0;
       min_board->state = k_cache_board_state_load_request;
    }
    else{
       vg_error( "No free boards to load registry!\n" );
    }
 
-   SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+   SDL_AtomicUnlock( &addon_system.sl_cache );
    return min_board;
 }
 
@@ -95,10 +81,13 @@ VG_STATIC void skateshop_update_viewpage(void)
       struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
       u32 request_id = page*SKATESHOP_VIEW_SLOT_MAX + i;
       
-      if( slot->cache_ptr ) unwatch_cache_board( slot->cache_ptr );
+      vg_pool *cache = &addon_system.board_cache;
+      if( slot->cache_ptr ) 
+         vg_pool_unwatch( cache, slot->cache_ptr );
 
       slot->cache_ptr = skateshop_cache_fetch_board( request_id );
-      if( slot->cache_ptr ) watch_cache_board( slot->cache_ptr );
+      if( slot->cache_ptr ) 
+         vg_pool_watch( cache, slot->cache_ptr );
    }
 }
 
@@ -112,13 +101,12 @@ VG_STATIC void skateshop_update_viewpage(void)
  */
 VG_STATIC void skateshop_async_board_loaded( void *payload, u32 size )
 {
-   SDL_AtomicLock( &global_skateshop.sl_cache_access );
+   SDL_AtomicLock( &addon_system.sl_cache );
    struct cache_board *cache_ptr = payload;
-   cache_ptr->last_use_time = vg.time;
    cache_ptr->state = k_cache_board_state_loaded;
 
    cache_ptr->reg_ptr->userdata = cache_ptr;
-   SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+   SDL_AtomicUnlock( &addon_system.sl_cache );
    vg_success( "Async board loaded (%s)\n", cache_ptr->reg_ptr->foldername );
 }
 
@@ -131,20 +119,20 @@ VG_STATIC void workshop_visibile_load_loop(void)
    vg_info( "Running load loop\n" );
    char path_buf[4096];
 
-   for( u32 i=0; i<SKATESHOP_BOARD_CACHE_MAX; i++ ){
-      struct cache_board *cache_ptr = &global_skateshop.cache[i];
+   for( u32 i=0; i<CACHE_BOARD_MAX; i++ ){
+      struct cache_board *cache_ptr = &addon_system.boards[i];
 
-      SDL_AtomicLock( &global_skateshop.sl_cache_access );
+      SDL_AtomicLock( &addon_system.sl_cache );
       if( cache_ptr->state == k_cache_board_state_load_request ){
          if( cache_ptr->reg_index >= addon_count(k_workshop_file_type_board) ){
             /* should maybe have a different value for this case */
             cache_ptr->state = k_cache_board_state_none;
-            SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+            SDL_AtomicUnlock( &addon_system.sl_cache );
             continue;
          }
 
          /* continue with the request */
-         SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+         SDL_AtomicUnlock( &addon_system.sl_cache );
          addon_reg *reg = get_addon_from_index( k_workshop_file_type_board,
                                                 cache_ptr->reg_index );
          cache_ptr->reg_ptr = reg;
@@ -157,10 +145,8 @@ VG_STATIC void workshop_visibile_load_loop(void)
 
          /* load content files
           * --------------------------------- */
-
          vg_str content_path = folder;
 
-
          vg_msg root = {0};
          root.buf = reg->metadata;
          root.len = reg->metadata_len;
@@ -187,12 +173,12 @@ VG_STATIC void workshop_visibile_load_loop(void)
          continue;
 
 file_is_broken:;
-         SDL_AtomicLock( &global_skateshop.sl_cache_access );
+         SDL_AtomicLock( &addon_system.sl_cache );
          cache_ptr->state = k_cache_board_state_none;
-         SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+         SDL_AtomicUnlock( &addon_system.sl_cache );
       }
       else
-         SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+         SDL_AtomicUnlock( &addon_system.sl_cache );
    }
 }
 
@@ -240,44 +226,27 @@ VG_STATIC void skateshop_op_processview(void){
  * -----------------------------------------------------------------------------
  */
 
-/* we can only keep using a viewslot pointer for multiple frames if we watch it
- * using this function */
-VG_STATIC void watch_cache_board( struct cache_board *ptr ){
-   if( ptr->ref_count >= 32 ){
-      vg_fatal_error( "dynamic board watch missmatch (limit is 32)\n" );
-   }
-
-   ptr->last_use_time = vg.time;
-   ptr->ref_count ++;
-}
-
-/* after this is called, the calling code only has access to the pointer for the
- * duration of the rest of the frame */
-VG_STATIC void unwatch_cache_board( struct cache_board *ptr ){
-   if( ptr->ref_count == 0 ){
-      vg_fatal_error( "dynamic board unwatch missmatch (no watchers)\n" );
-   }
-
-   ptr->ref_count --;
-}
-
-
 /*
  * VG event init
  */
 VG_STATIC void skateshop_init(void){
-   u32 cache_size = sizeof(struct cache_board)*SKATESHOP_BOARD_CACHE_MAX;
-   global_skateshop.cache = vg_linear_alloc( vg_mem.rtmemory, cache_size );
-   memset( global_skateshop.cache, 0, cache_size );
+   u32 cache_size = sizeof(struct cache_board)*CACHE_BOARD_MAX;
+   addon_system.boards = vg_linear_alloc( vg_mem.rtmemory, cache_size );
+   memset( addon_system.boards, 0, cache_size );
 
-   for( u32 i=0; i<SKATESHOP_BOARD_CACHE_MAX; i++ ){
-      struct cache_board *board = &global_skateshop.cache[i];
+   for( i32 i=0; i<CACHE_BOARD_MAX; i++ ){
+      struct cache_board *board = &addon_system.boards[i];
       board->state = k_cache_board_state_none;
       board->reg_ptr= NULL;
       board->reg_index = 0xffffffff;
-      board->last_use_time = -99999.9;
-      board->ref_count = 0;
    }
+
+   vg_pool *cache = &addon_system.board_cache;
+   cache->buffer = addon_system.boards;
+   cache->count = CACHE_BOARD_MAX;
+   cache->stride = sizeof( struct cache_board );
+   cache->offset = offsetof( struct cache_board, cachenode );
+   vg_pool_init( cache );
 }
 
 VG_STATIC struct cache_board *skateshop_selected_cache_if_loaded(void)
@@ -286,15 +255,15 @@ VG_STATIC struct cache_board *skateshop_selected_cache_if_loaded(void)
       addon_reg *reg = get_addon_from_index(k_workshop_file_type_board,
                                             global_skateshop.selected_board_id);
 
-      SDL_AtomicLock( &global_skateshop.sl_cache_access );
+      SDL_AtomicLock( &addon_system.sl_cache );
       if( reg->userdata ){
          struct cache_board *cache_ptr = reg->userdata;
          if( cache_ptr->state == k_cache_board_state_loaded ){
-            SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+            SDL_AtomicUnlock( &addon_system.sl_cache );
             return cache_ptr;
          }
       }
-      SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+      SDL_AtomicUnlock( &addon_system.sl_cache );
    }
 
    return NULL;
@@ -303,14 +272,12 @@ VG_STATIC struct cache_board *skateshop_selected_cache_if_loaded(void)
 VG_STATIC void pointcloud_async_end(void *_, u32 __)
 {
    pointcloud_animate( k_pointcloud_anim_opening );
-   skaterift_end_op();
 }
 
 VG_STATIC void pointcloud_clear_async(void *_, u32 __)
 {
    pointcloud.count = 0;
    pointcloud_animate( k_pointcloud_anim_opening );
-   skaterift_end_op();
 }
 
 VG_STATIC void skateshop_preview_loader_thread( void *_data )
@@ -351,10 +318,15 @@ VG_STATIC void skateshop_preview_loader_thread( void *_data )
    }
 }
 
+VG_STATIC void skateshop_preview_loader_thread_and_end( void *_data ){
+   skateshop_preview_loader_thread( _data );
+   skaterift_end_op();
+}
+
 VG_STATIC void skateshop_load_world_preview( addon_reg *reg )
 {
    skaterift_begin_op( k_async_op_world_load_preview );
-   vg_loader_start( skateshop_preview_loader_thread, reg );
+   vg_loader_start( skateshop_preview_loader_thread_and_end, reg );
 }
 
 /*
@@ -406,6 +378,8 @@ VG_STATIC void global_skateshop_preupdate(void)
 
    /* input */
    if( shop->type == k_skateshop_type_boardshop ){
+      if( skaterift.async_op != k_async_op_none ) return;
+
       gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" );
       gui_helper_action( button_display_string( k_srbind_mback ), "exit" );
 
@@ -418,6 +392,8 @@ VG_STATIC void global_skateshop_preupdate(void)
       /*
        * Controls
        * ----------------------
+       *
+       *  TODO: Crash if switch page too quick, delist browse if loading....
        */
 
       u32 opage = global_skateshop.selected_board_id/SKATESHOP_VIEW_SLOT_MAX;
@@ -447,12 +423,15 @@ VG_STATIC void global_skateshop_preupdate(void)
                      global_skateshop.selected_board_id );
 
          if( localplayer.board_view_slot ){
-            unwatch_cache_board( localplayer.board_view_slot );
+            vg_pool_unwatch( &addon_system.board_cache,
+                                 localplayer.board_view_slot );
          }
 
          localplayer.board_view_slot = selected_cache;
-         watch_cache_board( localplayer.board_view_slot );
+         vg_pool_watch( &addon_system.board_cache,
+                             localplayer.board_view_slot );
          global_skateshop_exit();
+         skaterift_write_savedata();
          return;
       }
    }
@@ -588,7 +567,7 @@ VG_STATIC void skateshop_render_boardshop(void)
                                   mdl_entity_id_id(shop->boards.id_display));
 
    int visibility[ SKATESHOP_VIEW_SLOT_MAX ];
-   SDL_AtomicLock( &global_skateshop.sl_cache_access );
+   SDL_AtomicLock( &addon_system.sl_cache );
    for( u32 i=0; i<SKATESHOP_VIEW_SLOT_MAX; i++ ){
       struct shop_view_slot *slot = &global_skateshop.shop_view_slots[i];
 
@@ -598,7 +577,7 @@ VG_STATIC void skateshop_render_boardshop(void)
       else if( slot->cache_ptr->state != k_cache_board_state_loaded )
          visibility[i] = 0;
    }
-   SDL_AtomicUnlock( &global_skateshop.sl_cache_access );
+   SDL_AtomicUnlock( &addon_system.sl_cache );
    
    /* Render loaded boards in the view slots */
    for( u32 i=0; i<slot_count; i++ ){