X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=addon.c;h=34e16f8e42b995a3028bec2f655dd551d2475cd8;hb=238a3a4ef19bb137e2a878ee38f99d253eddb51c;hp=0b342ce99ad3f063dea66034423edde0877a2b10;hpb=d3021395f97b2ae244835c6656008386c8874343;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/addon.c b/addon.c index 0b342ce..34e16f8 100644 --- a/addon.c +++ b/addon.c @@ -1,13 +1,17 @@ -#ifndef ADDON_C -#define ADDON_C - +#include "vg/vg_engine.h" +#include "vg/vg_io.h" +#include "vg/vg_loader.h" #include "addon.h" #include "addon_types.h" #include "vg/vg_msg.h" #include "steam.h" #include "workshop.h" +#include + +struct addon_system addon_system; -static u32 addon_count( enum addon_type type, u32 ignoreflags ){ +u32 addon_count( enum addon_type type, u32 ignoreflags ) +{ if( ignoreflags ){ u32 typecount = 0, count = 0; for( u32 i=0; typecounttype == k_addon_type_none ) return 0xffffffff; u32 foldername_djb2 = 0; @@ -100,7 +107,8 @@ static u32 addon_match( addon_alias *alias ){ /* * Create a string version of addon alias in buf */ -static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ){ +void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ) +{ if( alias->workshop_id ){ snprintf( buf, 128, "sr%03d-steam-"PRINTF_U64, alias->type, alias->workshop_id ); @@ -114,7 +122,8 @@ static void addon_alias_uid( addon_alias *alias, char buf[ADDON_UID_MAX] ){ /* * equality check */ -static int addon_alias_eq( addon_alias *a, addon_alias *b ){ +int addon_alias_eq( addon_alias *a, addon_alias *b ) +{ if( a->type == b->type ){ if( a->workshop_id == b->workshop_id ){ if( a->workshop_id ) @@ -131,7 +140,8 @@ static int addon_alias_eq( addon_alias *a, addon_alias *b ){ /* * make alias represent NULL. */ -static void invalidate_addon_alias( addon_alias *alias ){ +void invalidate_addon_alias( addon_alias *alias ) +{ alias->type = k_addon_type_none; alias->workshop_id = 0; alias->foldername[0] = '\0'; @@ -140,7 +150,8 @@ static void invalidate_addon_alias( addon_alias *alias ){ /* * parse uid to alias. returns 1 if successful */ -static int addon_uid_to_alias( const char *uid, addon_alias *alias ){ +int addon_uid_to_alias( const char *uid, addon_alias *alias ) +{ /* 1 * 01234567890123 * sr&&&-@@@@@-#* @@ -181,7 +192,8 @@ static int addon_uid_to_alias( const char *uid, addon_alias *alias ){ return 1; } -static void addon_system_init( void ){ +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 ); @@ -224,7 +236,7 @@ static void addon_system_init( void ){ /* * Reciever for scan completion. copies the registry counts back into main fred */ -static void async_addon_reg_update( void *data, u32 size ) +void async_addon_reg_update( void *data, u32 size ) { vg_info( "Registry update notify\n" ); @@ -334,11 +346,13 @@ static addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, vg_msg msg; vg_msg_init( &msg, reg->metadata, reg->metadata_len ); - if( vg_msg_seekframe( &msg, "workshop" )){ - type = vg_msg_getkvu32( &msg, "type", 0 ); + if( vg_msg_seekframe( &msg, "workshop" )) + { + vg_msg_getkvintg( &msg, "type", k_vg_msg_u32, &type, NULL ); } - if( type == k_addon_type_none ){ + if( type == k_addon_type_none ) + { vg_error( "Cannot determine addon type\n" ); return NULL; } @@ -351,9 +365,9 @@ static addon_reg *addon_mount_workshop_folder( PublishedFileId_t workshop_id, /* * Mount a local folder. may or may not have addon.inf */ -static addon_reg *addon_mount_local_addon( const char *folder, - enum addon_type type, - const char *content_ext ) +addon_reg *addon_mount_local_addon( const char *folder, + enum addon_type type, + const char *content_ext ) { char folder_path_buf[4096]; vg_str folder_path; @@ -368,7 +382,7 @@ static addon_reg *addon_mount_local_addon( const char *folder, if( (reg->alias.type == type) && (reg->foldername_hash == folder_hash) ){ if( !strcmp( reg->alias.foldername, folder_name ) ){ reg->state = k_addon_state_indexed; - return NULL; + return reg; } } } @@ -428,8 +442,14 @@ static addon_reg *addon_mount_local_addon( const char *folder, /* * Check all subscribed items */ -static void addon_mount_workshop_items(void){ +void addon_mount_workshop_items(void) +{ + if( skaterift.demo_mode ){ + vg_info( "Won't load workshop items in demo mode\n" ); + return; + } if( !steam_ready ) return; + /* * Steam workshop scan */ @@ -480,9 +500,9 @@ next_file_workshop:; * Scan a local content folder for addons. It must find at least one file with * the specified content_ext to be considered. */ -static void addon_mount_content_folder( enum addon_type type, - const char *base_folder, - const char *content_ext ) +void addon_mount_content_folder( enum addon_type type, + const char *base_folder, + const char *content_ext ) { vg_info( "Mounting addons(type:%d) matching skaterift/%s/*/*%s\n", type, base_folder, content_ext ); @@ -522,16 +542,31 @@ static void addon_mount_content_folder( enum addon_type type, /* * write the full path of the addon's folder into the vg_str */ -static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){ +int addon_get_content_folder( addon_reg *reg, vg_str *folder, int async) +{ if( reg->alias.workshop_id ){ - vg_async_item *call = - vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); - struct async_workshop_filepath_info *info = call->payload; + struct async_workshop_filepath_info *info = NULL; + vg_async_item *call = NULL; + + if( async ){ + call = vg_async_alloc( sizeof(struct async_workshop_filepath_info) ); + info = call->payload; + } + else + info = alloca( sizeof(struct async_workshop_filepath_info) ); + info->buf = folder->buffer; info->id = reg->alias.workshop_id; info->len = folder->len; - vg_async_dispatch( call, async_workshop_get_filepath ); - vg_async_stall(); /* too bad! */ + + if( async ){ + vg_async_dispatch( call, async_workshop_get_filepath ); + vg_async_stall(); /* too bad! */ + } + else { + async_workshop_get_filepath( info, 0 ); + } + if( info->buf[0] == '\0' ){ vg_error( "Failed SteamAPI_GetItemInstallInfo(" PRINTF_U64 ")\n", reg->alias.workshop_id ); @@ -557,7 +592,8 @@ static int addon_get_content_folder( addon_reg *reg, vg_str *folder ){ * Return existing cache id if reg_index points to a registry with its cache * already set. */ -static u16 addon_cache_fetch( enum addon_type type, u32 reg_index ){ +u16 addon_cache_fetch( enum addon_type type, u32 reg_index ) +{ addon_reg *reg = NULL; if( reg_index < addon_count( type, 0 ) ){ @@ -572,7 +608,8 @@ static u16 addon_cache_fetch( enum addon_type type, u32 reg_index ){ /* * Allocate a new cache item from the pool */ -static u16 addon_cache_alloc( enum addon_type type, u32 reg_index ){ +u16 addon_cache_alloc( enum addon_type type, u32 reg_index ) +{ struct addon_cache *cache = &addon_system.cache[ type ]; u16 new_id = vg_pool_lru( &cache->pool ); @@ -602,7 +639,8 @@ static u16 addon_cache_alloc( enum addon_type type, u32 reg_index ){ /* * Get the real item data for cache id */ -static void *addon_cache_item( enum addon_type type, u16 id ){ +void *addon_cache_item( enum addon_type type, u16 id ) +{ if( !id ) return NULL; struct addon_cache *cache = &addon_system.cache[type]; @@ -612,7 +650,8 @@ static void *addon_cache_item( enum addon_type type, u16 id ){ /* * Get the real item data for cache id ONLY if the item is completely loaded. */ -static void *addon_cache_item_if_loaded( enum addon_type type, u16 id ){ +void *addon_cache_item_if_loaded( enum addon_type type, u16 id ) +{ if( !id ) return NULL; struct addon_cache *cache = &addon_system.cache[type]; @@ -626,7 +665,8 @@ static void *addon_cache_item_if_loaded( enum addon_type type, u16 id ){ /* * Updates the item state from the main thread */ -static void async_addon_setstate( void *_entry, u32 _state ){ +void async_addon_setstate( void *_entry, u32 _state ) +{ addon_cache_entry *entry = _entry; SDL_AtomicLock( &addon_system.sl_cache_using_resources ); entry->state = _state; @@ -693,22 +733,27 @@ static void addon_cache_free_item( enum addon_type type, u16 id ){ /* * Goes over cache item load requests and calls the above ^ */ -static void addon_cache_load_loop(void){ +static void T1_addon_cache_load_loop(void *_) +{ vg_info( "Running load loop\n" ); char path_buf[4096]; - for( u32 type=0; typepool.count; id++ ){ + for( u32 id=1; id<=cache->pool.count; id++ ) + { addon_cache_entry *entry = vg_pool_item( &cache->pool, id ); SDL_AtomicLock( &addon_system.sl_cache_using_resources ); - if( entry->state == k_addon_cache_state_load_request ){ + if( entry->state == k_addon_cache_state_load_request ) + { vg_info( "process cache load request (%u#%u, reg:%u)\n", type, id, entry->reg_index ); - if( entry->reg_index >= addon_count(type,0) ){ + if( entry->reg_index >= addon_count(type,0) ) + { /* should maybe have a different value for this case */ entry->state = k_addon_cache_state_none; SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); @@ -723,8 +768,10 @@ static void addon_cache_load_loop(void){ vg_str folder; vg_strnull( &folder, path_buf, 4096 ); - if( addon_get_content_folder( reg, &folder ) ){ - if( addon_cache_load_request( type, id, reg, folder ) ){ + if( addon_get_content_folder( reg, &folder, 1 ) ) + { + if( addon_cache_load_request( type, id, reg, folder ) ) + { vg_async_call( async_addon_setstate, entry, k_addon_cache_state_loaded ); continue; @@ -742,11 +789,35 @@ static void addon_cache_load_loop(void){ } } +void addon_system_pre_update(void) +{ + if( !vg_loader_availible() ) return; + + SDL_AtomicLock( &addon_system.sl_cache_using_resources ); + for( u32 type=0; typepool.count; id++ ) + { + addon_cache_entry *entry = vg_pool_item( &cache->pool, id ); + if( entry->state == k_addon_cache_state_load_request ) + { + SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); + vg_loader_start( T1_addon_cache_load_loop, NULL ); + return; + } + } + } + SDL_AtomicUnlock( &addon_system.sl_cache_using_resources ); +} + /* * Perform the cache interactions required to create a viewslot which will * eventually be loaded by other parts of the system. */ -static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ){ +u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ) +{ struct addon_cache *cache = &addon_system.cache[type]; vg_pool *pool = &cache->pool; @@ -773,8 +844,9 @@ static u16 addon_cache_create_viewer( enum addon_type type, u16 reg_id ){ return cache_id; } -static u16 addon_cache_create_viewer_from_uid( enum addon_type type, - char uid[ADDON_UID_MAX] ){ +u16 addon_cache_create_viewer_from_uid( enum addon_type type, + char uid[ADDON_UID_MAX] ) +{ addon_alias q; if( !addon_uid_to_alias( uid, &q ) ) return 0; if( q.type != type ) return 0; @@ -790,7 +862,8 @@ static u16 addon_cache_create_viewer_from_uid( enum addon_type type, } } -static void addon_cache_watch( enum addon_type type, u16 cache_id ){ +void addon_cache_watch( enum addon_type type, u16 cache_id ) +{ if( !cache_id ) return; struct addon_cache *cache = &addon_system.cache[type]; @@ -798,12 +871,11 @@ static void addon_cache_watch( enum addon_type type, u16 cache_id ){ vg_pool_watch( pool, cache_id ); } -static void addon_cache_unwatch( enum addon_type type, u16 cache_id ){ +void addon_cache_unwatch( enum addon_type type, u16 cache_id ) +{ if( !cache_id ) return; struct addon_cache *cache = &addon_system.cache[type]; vg_pool *pool = &cache->pool; vg_pool_unwatch( pool, cache_id ); } - -#endif /* ADDON_C */