소스 검색

UI: Use saving functions for profiles/scenes

Replaces all the json/config loading/saving functions with safe
variants to reduce the chance of potential file corruption as much as
possible.

Also does a minor refactor of json writing by using
obs_data_save_json_safe for writing json files instead of manually using
obs_data_get_json and os_quick_write_utf8 each time.
jp9000 10 년 전
부모
커밋
ebf3abf04e
4개의 변경된 파일30개의 추가작업 그리고 49개의 파일을 삭제
  1. 4 4
      obs/window-basic-main-profiles.cpp
  2. 2 5
      obs/window-basic-main-scene-collections.cpp
  3. 16 27
      obs/window-basic-main.cpp
  4. 8 13
      obs/window-basic-settings.cpp

+ 4 - 4
obs/window-basic-main-profiles.cpp

@@ -225,7 +225,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
 			newDir.c_str());
 
 	config_set_string(config, "General", "Name", newName.c_str());
-	config.Save();
+	config.SaveSafe("tmp");
 	config.Swap(basicConfig);
 	InitBasicConfigDefaults();
 	RefreshProfiles();
@@ -237,7 +237,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
 			create_new ? "clean" : "duplicate", newDir.c_str());
 	blog(LOG_INFO, "------------------------------------------------");
 
-	config_save(App()->GlobalConfig());
+	config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
 	UpdateTitleBar();
 	return true;
 }
@@ -424,7 +424,7 @@ void OBSBasic::on_actionRemoveProfile_triggered()
 	ResetProfileData();
 	DeleteProfile(oldName.c_str(), oldDir.c_str());
 	RefreshProfiles();
-	config_save(App()->GlobalConfig());
+	config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
 
 	blog(LOG_INFO, "Switched to profile '%s' (%s)",
 			newName.c_str(), newDir);
@@ -475,7 +475,7 @@ void OBSBasic::ChangeProfile()
 	InitBasicConfigDefaults();
 	ResetProfileData();
 	RefreshProfiles();
-	config_save(App()->GlobalConfig());
+	config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
 	UpdateTitleBar();
 
 	blog(LOG_INFO, "Switched to profile '%s' (%s)",

+ 2 - 5
obs/window-basic-main-scene-collections.cpp

@@ -48,11 +48,8 @@ template <typename Func> static void EnumSceneCollections(Func &&cb)
 		if (glob->gl_pathv[i].directory)
 			continue;
 
-		BPtr<char> fileData = os_quick_read_utf8_file(filePath);
-		if (!fileData)
-			continue;
-
-		obs_data_t *data = obs_data_create_from_json(fileData);
+		obs_data_t *data = obs_data_create_from_json_file_safe(filePath,
+				"bak");
 		std::string name = obs_data_get_string(data, "name");
 
 		/* if no name found, use the file name as the name

+ 16 - 27
obs/window-basic-main.cpp

@@ -308,16 +308,9 @@ void OBSBasic::Save(const char *file)
 {
 	obs_data_array_t *sceneOrder = SaveSceneListOrder();
 	obs_data_t *saveData  = GenerateSaveData(sceneOrder);
-	const char *jsonData = obs_data_get_json(saveData);
 
-	if (!!jsonData) {
-		/* TODO: maybe a message box here? */
-		bool success = os_quick_write_utf8_file(file, jsonData,
-				strlen(jsonData), false);
-		if (!success)
-			blog(LOG_ERROR, "Could not save scene data to %s",
-					file);
-	}
+	if (!obs_data_save_json_safe(saveData, file, "tmp", "bak"))
+		blog(LOG_ERROR, "Could not save scene data to %s", file);
 
 	obs_data_release(saveData);
 	obs_data_array_release(sceneOrder);
@@ -450,23 +443,23 @@ void OBSBasic::CleanupUnusedSources()
 
 void OBSBasic::Load(const char *file)
 {
-	if (!file) {
+	if (!file || !os_file_exists(file)) {
 		blog(LOG_ERROR, "Could not find file %s", file);
 		return;
 	}
 
-	BPtr<char> jsonData = os_quick_read_utf8_file(file);
-	if (!jsonData) {
+	disableSaving++;
+
+	obs_data_t *data = obs_data_create_from_json_file_safe(file, "bak");
+	if (!data) {
+		disableSaving--;
 		CreateDefaultScene();
 		SaveProject();
 		return;
 	}
 
-	disableSaving++;
-
 	ClearSceneData();
 
-	obs_data_t       *data       = obs_data_create_from_json(jsonData);
 	obs_data_array_t *sceneOrder = obs_data_get_array(data, "scene_order");
 	obs_data_array_t *sources    = obs_data_get_array(data, "sources");
 	const char       *sceneName = obs_data_get_string(data,
@@ -535,9 +528,8 @@ void OBSBasic::SaveService()
 	obs_data_set_string(data, "type", obs_service_get_type(service));
 	obs_data_set_obj(data, "settings", settings);
 
-	const char *json = obs_data_get_json(data);
-
-	os_quick_write_utf8_file(serviceJsonPath, json, strlen(json), false);
+	if (!obs_data_save_json_safe(data, serviceJsonPath, "tmp", "bak"))
+		blog(LOG_WARNING, "Failed to save service");
 
 	obs_data_release(settings);
 	obs_data_release(data);
@@ -553,11 +545,8 @@ bool OBSBasic::LoadService()
 	if (ret <= 0)
 		return false;
 
-	BPtr<char> jsonText = os_quick_read_utf8_file(serviceJsonPath);
-	if (!jsonText)
-		return false;
-
-	obs_data_t *data = obs_data_create_from_json(jsonText);
+	obs_data_t *data = obs_data_create_from_json_file_safe(serviceJsonPath,
+			"bak");
 
 	obs_data_set_default_string(data, "type", "rtmp_common");
 	type = obs_data_get_string(data, "type");
@@ -632,7 +621,7 @@ bool OBSBasic::InitBasicConfigDefaults()
 		track = 1ULL << (track - 1);
 		config_set_uint(basicConfig, "AdvOut", "RecTracks", track);
 		config_remove_value(basicConfig, "AdvOut", "RecTrackIndex");
-		config_save(basicConfig);
+		config_save_safe(basicConfig, "tmp", nullptr);
 	}
 
 	/* ----------------------------------------------------- */
@@ -768,7 +757,7 @@ bool OBSBasic::InitBasicConfig()
 				"Basic", "Profile");
 
 		config_set_string(basicConfig, "General", "Name", curName);
-		basicConfig.Save();
+		basicConfig.SaveSafe("tmp");
 	}
 
 	return InitBasicConfigDefaults();
@@ -1152,7 +1141,7 @@ OBSBasic::~OBSBasic()
 			lastGeom.y());
 	config_set_bool(App()->GlobalConfig(), "BasicWindow", "PreviewEnabled",
 			previewEnabled);
-	config_save(App()->GlobalConfig());
+	config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
 
 #ifdef _WIN32
 	uint32_t winVer = GetWindowsVersion();
@@ -1669,7 +1658,7 @@ void OBSBasic::updateFileFinished(const QString &text, const QString &error)
 			long long t = (long long)time(nullptr);
 			config_set_int(App()->GlobalConfig(), "General",
 					"LastUpdateCheck", t);
-			config_save(App()->GlobalConfig());
+			config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
 		}
 	} else {
 		blog(LOG_WARNING, "Bad JSON file received from server");

+ 8 - 13
obs/window-basic-settings.cpp

@@ -1069,12 +1069,10 @@ OBSPropertiesView *OBSBasicSettings::CreateEncoderPropertyView(
 	int ret = GetProfilePath(encoderJsonPath, sizeof(encoderJsonPath),
 			path);
 	if (ret > 0) {
-		BPtr<char> jsonData = os_quick_read_utf8_file(encoderJsonPath);
-		if (!!jsonData) {
-			obs_data_t *data = obs_data_create_from_json(jsonData);
-			obs_data_apply(settings, data);
-			obs_data_release(data);
-		}
+		obs_data_t *data = obs_data_create_from_json_file_safe(
+				encoderJsonPath, "bak");
+		obs_data_apply(settings, data);
+		obs_data_release(data);
 	}
 
 	view = new OBSPropertiesView(settings, encoder,
@@ -1985,11 +1983,8 @@ static void WriteJsonData(OBSPropertiesView *view, const char *path)
 	if (ret > 0) {
 		obs_data_t *settings = view->GetSettings();
 		if (settings) {
-			const char *json = obs_data_get_json(settings);
-			if (json && *json) {
-				os_quick_write_utf8_file(full_path, json,
-						strlen(json), false);
-			}
+			obs_data_save_json_safe(settings, full_path,
+					"tmp", "bak");
 		}
 	}
 }
@@ -2247,8 +2242,8 @@ void OBSBasicSettings::SaveSettings()
 	if (videoChanged || advancedChanged)
 		main->ResetVideo();
 
-	config_save(main->Config());
-	config_save(GetGlobalConfig());
+	config_save_safe(main->Config(), "tmp", nullptr);
+	config_save_safe(GetGlobalConfig(), "tmp", nullptr);
 	main->SaveProject();
 
 	if (Changed()) {