1
0
Эх сурвалжийг харах

UI: Fix properties view crash with non-obs objects

The properties view incorrectly assumed that it was being used with obs
objects only.

(Jim note: I'm annoyed.)
jp9000 3 жил өмнө
parent
commit
b0528e0cf7

+ 35 - 9
UI/properties-view.cpp

@@ -89,10 +89,11 @@ Q_DECLARE_METATYPE(media_frames_per_second);
 
 void OBSPropertiesView::ReloadProperties()
 {
-	if (weakObj) {
-		OBSObject obj = GetObject();
+	if (weakObj || rawObj) {
+		OBSObject strongObj = GetObject();
+		void *obj = strongObj ? strongObj.Get() : rawObj;
 		if (obj)
-			properties.reset(reloadCallback(obj.Get()));
+			properties.reset(reloadCallback(obj));
 	} else {
 		properties.reset(reloadCallback((void *)type.c_str()));
 		obs_properties_apply_settings(properties.get(), settings);
@@ -176,6 +177,24 @@ void OBSPropertiesView::GetScrollPos(int &h, int &v)
 		v = scroll->value();
 }
 
+OBSPropertiesView::OBSPropertiesView(OBSData settings_, obs_object_t *obj,
+				     PropertiesReloadCallback reloadCallback,
+				     PropertiesUpdateCallback callback_,
+				     PropertiesVisualUpdateCb cb_, int minSize_)
+	: VScrollArea(nullptr),
+	  properties(nullptr, obs_properties_destroy),
+	  settings(settings_),
+	  weakObj(obs_object_get_weak_object(obj)),
+	  reloadCallback(reloadCallback),
+	  callback(callback_),
+	  cb(cb_),
+	  minSize(minSize_)
+{
+	setFrameShape(QFrame::NoFrame);
+	QMetaObject::invokeMethod(this, "ReloadProperties",
+				  Qt::QueuedConnection);
+}
+
 OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj,
 				     PropertiesReloadCallback reloadCallback,
 				     PropertiesUpdateCallback callback_,
@@ -183,7 +202,7 @@ OBSPropertiesView::OBSPropertiesView(OBSData settings_, void *obj,
 	: VScrollArea(nullptr),
 	  properties(nullptr, obs_properties_destroy),
 	  settings(settings_),
-	  weakObj(obs_object_get_weak_object((obs_object_t *)obj)),
+	  rawObj(obj),
 	  reloadCallback(reloadCallback),
 	  callback(callback_),
 	  cb(cb_),
@@ -1907,9 +1926,13 @@ void WidgetInfo::ButtonClicked()
 		}
 		return;
 	}
-	if (obs_property_button_clicked(property, view->GetObject())) {
-		QMetaObject::invokeMethod(view, "RefreshProperties",
-					  Qt::QueuedConnection);
+	if (view->rawObj || view->weakObj) {
+		OBSObject strongObj = view->GetObject();
+		void *obj = strongObj ? strongObj.Get() : view->rawObj;
+		if (obs_property_button_clicked(property, obj)) {
+			QMetaObject::invokeMethod(view, "RefreshProperties",
+						  Qt::QueuedConnection);
+		}
 	}
 }
 
@@ -1983,7 +2006,9 @@ void WidgetInfo::ControlChanged()
 		update_timer = new QTimer;
 		connect(update_timer, &QTimer::timeout,
 			[this, &ru = recently_updated]() {
-				OBSObject obj = view->GetObject();
+				OBSObject strongObj = view->GetObject();
+				void *obj = strongObj ? strongObj.Get()
+						      : view->rawObj;
 				if (obj && view->callback &&
 				    !view->deferUpdate) {
 					view->callback(obj, old_settings_cache,
@@ -2004,7 +2029,8 @@ void WidgetInfo::ControlChanged()
 	}
 
 	if (view->cb && !view->deferUpdate) {
-		OBSObject obj = view->GetObject();
+		OBSObject strongObj = view->GetObject();
+		void *obj = strongObj ? strongObj.Get() : view->rawObj;
 		if (obj)
 			view->cb(obj, view->settings);
 	}

+ 23 - 0
UI/properties-view.hpp

@@ -98,6 +98,7 @@ private:
 	properties_t properties;
 	OBSData settings;
 	OBSWeakObjectAutoRelease weakObj;
+	void *rawObj;
 	std::string type;
 	PropertiesReloadCallback reloadCallback;
 	PropertiesUpdateCallback callback = nullptr;
@@ -152,6 +153,11 @@ signals:
 	void PropertiesRefreshed();
 
 public:
+	OBSPropertiesView(OBSData settings, obs_object_t *obj,
+			  PropertiesReloadCallback reloadCallback,
+			  PropertiesUpdateCallback callback,
+			  PropertiesVisualUpdateCb cb = nullptr,
+			  int minSize = 0);
 	OBSPropertiesView(OBSData settings, void *obj,
 			  PropertiesReloadCallback reloadCallback,
 			  PropertiesUpdateCallback callback,
@@ -161,6 +167,23 @@ public:
 			  PropertiesReloadCallback reloadCallback,
 			  int minSize = 0);
 
+#define obj_constructor(type)                                              \
+	inline OBSPropertiesView(OBSData settings, obs_##type##_t *type,   \
+				 PropertiesReloadCallback reloadCallback,  \
+				 PropertiesUpdateCallback callback,        \
+				 PropertiesVisualUpdateCb cb = nullptr,    \
+				 int minSize = 0)                          \
+		: OBSPropertiesView(settings, (obs_object_t *)type,        \
+				    reloadCallback, callback, cb, minSize) \
+	{                                                                  \
+	}
+
+	obj_constructor(source);
+	obj_constructor(output);
+	obj_constructor(encoder);
+	obj_constructor(service);
+#undef obj_constructor
+
 	inline obs_data_t *GetSettings() const { return settings; }
 
 	inline void UpdateSettings()