mirror of
				https://github.com/N64Recomp/N64ModernRuntime.git
				synced 2025-10-30 08:02:29 +00:00 
			
		
		
		
	Add callback for mod reordering and functions to get mod file path and order index (#99)
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				validate / windows (x64, Release) (push) Has been cancelled
				
			
		
			
				
	
				validate / ubuntu (arm64, Debug) (push) Has been cancelled
				
			
		
			
				
	
				validate / ubuntu (arm64, Release) (push) Has been cancelled
				
			
		
			
				
	
				validate / ubuntu (x64, Debug) (push) Has been cancelled
				
			
		
			
				
	
				validate / ubuntu (x64, Release) (push) Has been cancelled
				
			
		
			
				
	
				validate / windows (x64, Debug) (push) Has been cancelled
				
			
		
			
				
	
				validate / macos (arm64, Debug) (push) Has been cancelled
				
			
		
			
				
	
				validate / macos (arm64, Release) (push) Has been cancelled
				
			
		
			
				
	
				validate / macos (x64, Debug) (push) Has been cancelled
				
			
		
			
				
	
				validate / macos (x64, Release) (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	validate / windows (x64, Release) (push) Has been cancelled
				
			validate / ubuntu (arm64, Debug) (push) Has been cancelled
				
			validate / ubuntu (arm64, Release) (push) Has been cancelled
				
			validate / ubuntu (x64, Debug) (push) Has been cancelled
				
			validate / ubuntu (x64, Release) (push) Has been cancelled
				
			validate / windows (x64, Debug) (push) Has been cancelled
				
			validate / macos (arm64, Debug) (push) Has been cancelled
				
			validate / macos (arm64, Release) (push) Has been cancelled
				
			validate / macos (x64, Debug) (push) Has been cancelled
				
			validate / macos (x64, Release) (push) Has been cancelled
				
			This commit is contained in:
		
							parent
							
								
									8506c1b588
								
							
						
					
					
						commit
						af075623dc
					
				
					 3 changed files with 77 additions and 9 deletions
				
			
		|  | @ -260,9 +260,6 @@ namespace recomp { | |||
|                 mod_id(mod_id_), error(error_), error_param(error_param_) {} | ||||
|         }; | ||||
| 
 | ||||
|         std::string get_mod_id_from_filename(const std::filesystem::path& mod_filename); | ||||
|         std::optional<ModDetails> get_details_for_mod(const std::string& mod_id); | ||||
|         std::vector<ModDetails> get_all_mod_details(const std::string& mod_game_id); | ||||
|         void set_mod_index(const std::string &mod_game_id, const std::string &mod_id, size_t index); | ||||
| 
 | ||||
|         // Internal functions, TODO move to an internal header.
 | ||||
|  | @ -277,6 +274,7 @@ namespace recomp { | |||
|         class ModHandle; | ||||
|         using content_enabled_callback = void(ModContext&, const ModHandle&); | ||||
|         using content_disabled_callback = void(ModContext&, const ModHandle&); | ||||
|         using content_reordered_callback = void(ModContext&); | ||||
| 
 | ||||
|         struct ModContentType { | ||||
|             // The file that's used to indicate that a mod contains this content type.
 | ||||
|  | @ -288,6 +286,11 @@ namespace recomp { | |||
|             content_enabled_callback* on_enabled; | ||||
|             // Function to call when an instance of this content type is disabled.
 | ||||
|             content_disabled_callback* on_disabled; | ||||
|             // Function to call when an instance of this content type has been reordered.
 | ||||
|             // No mod handle is provided as multiple instances may have been reordered at the same time.
 | ||||
|             // Will not be called if an instance of this content type was incidentally reordered due
 | ||||
|             // to the reordering of another mod, as the ordering of just instances of this content type will not have changed.
 | ||||
|             content_reordered_callback* on_reordered; | ||||
|         }; | ||||
| 
 | ||||
|         // Holds IDs for mod content types, which get assigned as they're registered.
 | ||||
|  | @ -336,6 +339,8 @@ namespace recomp { | |||
|             std::vector<ModLoadErrorDetails> load_mods(const GameEntry& game_entry, uint8_t* rdram, int32_t load_address, uint32_t& ram_used); | ||||
|             void unload_mods(); | ||||
|             std::string get_mod_id_from_filename(const std::filesystem::path& mod_filename) const; | ||||
|             std::filesystem::path get_mod_filename(const std::string& mod_id) const; | ||||
|             size_t get_mod_order_index(const std::string& mod_id) const; | ||||
|             std::optional<ModDetails> get_details_for_mod(const std::string& mod_id) const; | ||||
|             std::vector<ModDetails> get_all_mod_details(const std::string& mod_game_id); | ||||
|             void set_mod_index(const std::string &mod_game_id, const std::string &mod_id, size_t index); | ||||
|  | @ -579,6 +584,8 @@ namespace recomp { | |||
|         void scan_mods(); | ||||
|         void close_mods(); | ||||
|         std::filesystem::path get_mods_directory(); | ||||
|         std::optional<ModDetails> get_details_for_mod(const std::string& mod_id); | ||||
|         std::vector<ModDetails> get_all_mod_details(const std::string& mod_game_id); | ||||
|         void enable_mod(const std::string& mod_id, bool enabled); | ||||
|         bool is_mod_enabled(const std::string& mod_id); | ||||
|         bool is_mod_auto_enabled(const std::string& mod_id); | ||||
|  | @ -588,6 +595,9 @@ namespace recomp { | |||
|         void set_mod_config_value(const std::string &mod_id, const std::string &option_id, const ConfigValueVariant &value); | ||||
|         ConfigValueVariant get_mod_config_value(size_t mod_index, const std::string &option_id); | ||||
|         ConfigValueVariant get_mod_config_value(const std::string &mod_id, const std::string &option_id); | ||||
|         std::string get_mod_id_from_filename(const std::filesystem::path& mod_filename); | ||||
|         std::filesystem::path get_mod_filename(const std::string& mod_id); | ||||
|         size_t get_mod_order_index(const std::string& mod_id); | ||||
|         ModContentTypeId register_mod_content_type(const ModContentType& type); | ||||
|         bool register_mod_container_type(const std::string& extension, const std::vector<ModContentTypeId>& content_types, bool requires_manifest); | ||||
| 
 | ||||
|  |  | |||
|  | @ -614,7 +614,10 @@ recomp::mods::ModLoadError recomp::mods::ModContext::load_mod(recomp::mods::ModH | |||
|     } | ||||
| 
 | ||||
|     for (ModContentTypeId type_id : mod.content_types) { | ||||
|         content_types[type_id.value].on_enabled(*this, mod); | ||||
|         content_enabled_callback* callback = content_types[type_id.value].on_enabled; | ||||
|         if (callback) { | ||||
|             callback(*this, mod); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     return ModLoadError::Good; | ||||
|  | @ -872,7 +875,8 @@ recomp::mods::ModContext::ModContext() { | |||
|         .content_filename = std::string{modpaths::binary_syms_path}, | ||||
|         .allow_runtime_toggle = false, | ||||
|         .on_enabled = ModContext::on_code_mod_enabled, | ||||
|         .on_disabled = nullptr | ||||
|         .on_disabled = nullptr, | ||||
|         .on_reordered = nullptr | ||||
|     }; | ||||
|     code_content_type_id = register_content_type(code_content_type); | ||||
|      | ||||
|  | @ -969,7 +973,10 @@ void recomp::mods::ModContext::enable_mod(const std::string& mod_id, bool enable | |||
|         // If mods have been loaded and a mod was successfully enabled by this call, call the on_enabled handlers for its content types.
 | ||||
|         if (was_enabled && mods_loaded) { | ||||
|             for (ModContentTypeId type_id : mod.content_types) { | ||||
|                 content_types[type_id.value].on_enabled(*this, mod); | ||||
|                 content_enabled_callback* callback = content_types[type_id.value].on_enabled; | ||||
|                 if (callback) { | ||||
|                     callback(*this, mod); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -990,7 +997,10 @@ void recomp::mods::ModContext::enable_mod(const std::string& mod_id, bool enable | |||
| 
 | ||||
|                             if (mods_loaded) { | ||||
|                                 for (ModContentTypeId type_id : mod_from_stack_handle.content_types) { | ||||
|                                     content_types[type_id.value].on_enabled(*this, mod_from_stack_handle); | ||||
|                                     content_enabled_callback* callback = content_types[type_id.value].on_enabled; | ||||
|                                     if (callback) { | ||||
|                                         callback(*this, mod_from_stack_handle); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|  | @ -1005,7 +1015,10 @@ void recomp::mods::ModContext::enable_mod(const std::string& mod_id, bool enable | |||
|         // If mods have been loaded and a mod was successfully disabled by this call, call the on_disabled handlers for its content types.
 | ||||
|         if (was_disabled && mods_loaded) { | ||||
|             for (ModContentTypeId type_id : mod.content_types) { | ||||
|                 content_types[type_id.value].on_disabled(*this, mod); | ||||
|                 content_disabled_callback* callback = content_types[type_id.value].on_disabled; | ||||
|                 if (callback) { | ||||
|                     callback(*this, mod); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1040,7 +1053,10 @@ void recomp::mods::ModContext::enable_mod(const std::string& mod_id, bool enable | |||
|                         if (enabled_mod_it != opened_mods_by_id.end()) { | ||||
|                             const ModHandle &enabled_mod_handle = opened_mods[enabled_mod_it->second]; | ||||
|                             for (ModContentTypeId type_id : enabled_mod_handle.content_types) { | ||||
|                                 content_types[type_id.value].on_disabled(*this, enabled_mod_handle); | ||||
|                                 content_disabled_callback* callback = content_types[type_id.value].on_disabled; | ||||
|                                 if (callback) { | ||||
|                                     callback(*this, enabled_mod_handle); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  | @ -1077,6 +1093,31 @@ std::string recomp::mods::ModContext::get_mod_id_from_filename(const std::filesy | |||
|     return opened_mods[find_it->second].manifest.mod_id; | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path recomp::mods::ModContext::get_mod_filename(const std::string& mod_id) const { | ||||
|     auto find_it = opened_mods_by_id.find(mod_id); | ||||
|     if (find_it == opened_mods_by_id.end()) { | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     return opened_mods[find_it->second].manifest.mod_root_path; | ||||
| } | ||||
| 
 | ||||
| size_t recomp::mods::ModContext::get_mod_order_index(const std::string& mod_id) const { | ||||
|     auto find_it = opened_mods_by_id.find(mod_id); | ||||
|     if (find_it == opened_mods_by_id.end()) { | ||||
|         return static_cast<size_t>(-1); | ||||
|     } | ||||
| 
 | ||||
|     // TODO keep a mapping of mod index to mod order index to prevent needing a lookup here.
 | ||||
|     auto find_order_it = std::find(opened_mods_order.begin(), opened_mods_order.end(), find_it->second); | ||||
|     if (find_order_it == opened_mods_order.end()) { | ||||
|         assert(false); | ||||
|         return static_cast<size_t>(-1); | ||||
|     } | ||||
| 
 | ||||
|     return find_order_it - opened_mods_order.begin(); | ||||
| } | ||||
| 
 | ||||
| std::optional<recomp::mods::ModDetails> recomp::mods::ModContext::get_details_for_mod(const std::string& mod_id) const { | ||||
|     auto find_it = opened_mods_by_id.find(mod_id); | ||||
|     if (find_it == opened_mods_by_id.end()) { | ||||
|  | @ -1272,6 +1313,13 @@ void recomp::mods::ModContext::set_mod_index(const std::string &mod_game_id, con | |||
|         opened_mods_order.push_back(mod_index); | ||||
|     } | ||||
| 
 | ||||
|     for (ModContentTypeId type_id : opened_mods[mod_index].content_types) { | ||||
|         content_reordered_callback* callback = content_types[type_id.value].on_reordered; | ||||
|         if (callback) { | ||||
|             callback(*this); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     mod_configuration_thread_queue.enqueue(ModConfigQueueSave()); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -563,6 +563,16 @@ std::string recomp::mods::get_mod_id_from_filename(const std::filesystem::path& | |||
|     return mod_context->get_mod_id_from_filename(mod_filename); | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path recomp::mods::get_mod_filename(const std::string& mod_id) { | ||||
|     std::lock_guard lock { mod_context_mutex }; | ||||
|     return mod_context->get_mod_filename(mod_id); | ||||
| } | ||||
| 
 | ||||
| size_t recomp::mods::get_mod_order_index(const std::string& mod_id) { | ||||
|     std::lock_guard lock { mod_context_mutex }; | ||||
|     return mod_context->get_mod_order_index(mod_id); | ||||
| } | ||||
| 
 | ||||
| std::optional<recomp::mods::ModDetails> recomp::mods::get_details_for_mod(const std::string& mod_id) { | ||||
|     std::lock_guard lock { mod_context_mutex }; | ||||
|     return mod_context->get_details_for_mod(mod_id); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Wiseguy
						Wiseguy