Browse Source

update API and implement preliminary ability to add sources to scenes

jp9000 11 years ago
parent
commit
c129cc37cb

+ 3 - 0
build/data/obs-studio/locale/en.txt

@@ -12,6 +12,9 @@ MainMenu.FIle.Save="Save"
 MainWindow.AddSceneDlg.Title="Add Scene"
 MainWindow.AddSceneDlg.Text="Please enter the name of the scene"
 
+MainWindow.AddSourceDlg.Title="Add Source"
+MainWindow.AddSourceDlg.Text="Please enter the name of the source"
+
 MainWindow.NameExists.Title="Name already exists"
 MainWindow.NameExists.Text="The name is already in use by another source."
 

+ 4 - 4
libobs/obs-module.c

@@ -147,13 +147,13 @@ int obs_load_module(const char *path)
 
 	mod.name = bstrdup(path);
 	module_load_exports(&mod, &obs->input_types.da, "inputs",
-			sizeof(struct source_info), get_source_info);
+			sizeof(struct source_info), load_source_info);
 	module_load_exports(&mod, &obs->filter_types.da, "filters",
-			sizeof(struct source_info), get_source_info);
+			sizeof(struct source_info), load_source_info);
 	module_load_exports(&mod, &obs->transition_types.da, "transitions",
-			sizeof(struct source_info), get_source_info);
+			sizeof(struct source_info), load_source_info);
 	module_load_exports(&mod, &obs->output_types.da, "outputs",
-			sizeof(struct output_info), get_output_info);
+			sizeof(struct output_info), load_output_info);
 
 	da_push_back(obs->modules, &mod);
 	return MODULE_SUCCESS;

+ 1 - 1
libobs/obs-output.c

@@ -18,7 +18,7 @@
 #include "obs.h"
 #include "obs-data.h"
 
-bool get_output_info(void *module, const char *module_name,
+bool load_output_info(void *module, const char *module_name,
 		const char *output_id, struct output_info *info)
 {
 	info->getname = load_module_subfunc(module, module_name,

+ 1 - 1
libobs/obs-output.h

@@ -119,5 +119,5 @@ struct obs_output {
 	struct dstr settings;
 };
 
-extern bool get_output_info(void *module, const char *module_name,
+extern bool load_output_info(void *module, const char *module_name,
 		const char *output_name, struct output_info *info);

+ 18 - 4
libobs/obs-scene.c

@@ -119,10 +119,16 @@ obs_scene_t obs_scene_create(const char *name)
 	return scene;
 }
 
-void obs_scene_release(obs_scene_t scene)
+int obs_scene_addref(obs_scene_t scene)
+{
+	return obs_source_addref(scene->source);
+}
+
+int obs_scene_release(obs_scene_t scene)
 {
 	if (scene)
-		obs_source_release(scene->source);
+		return obs_source_release(scene->source);
+	return 0;
 }
 
 obs_source_t obs_scene_getsource(obs_scene_t scene)
@@ -154,15 +160,23 @@ obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source)
 	return item;
 }
 
-void obs_sceneitem_destroy(obs_sceneitem_t item)
+int obs_sceneitem_destroy(obs_sceneitem_t item)
 {
+	int ref = 0;
 	if (item) {
 		if (item->source)
-			obs_source_release(item->source);
+			ref = obs_source_release(item->source);
 
 		da_erase_item(item->parent->items, item);
 		bfree(item);
 	}
+
+	return ref;
+}
+
+obs_source_t obs_sceneitem_getsource(obs_sceneitem_t item)
+{
+	return item->source;
 }
 
 void obs_sceneitem_setpos(obs_sceneitem_t item, const struct vec2 *pos)

+ 27 - 14
libobs/obs-source.c

@@ -25,7 +25,7 @@
 
 static void obs_source_destroy(obs_source_t source);
 
-bool get_source_info(void *module, const char *module_name,
+bool load_source_info(void *module, const char *module_name,
 		const char *source_id, struct source_info *info)
 {
 	info->getname = load_module_subfunc(module, module_name,
@@ -85,6 +85,24 @@ static inline const struct source_info *find_source(struct darray *list,
 	return NULL;
 }
 
+static const struct source_info *get_source_info(enum source_type type,
+		const char *id)
+{
+	struct darray *list = NULL;
+
+	switch (type) {
+	case SOURCE_INPUT:      list = &obs->input_types.da; break;
+	case SOURCE_FILTER:     list = &obs->filter_types.da; break;
+	case SOURCE_TRANSITION: list = &obs->transition_types.da; break;
+	case SOURCE_SCENE:
+	default:
+		blog(LOG_WARNING, "get_source_info: invalid source type");
+		return NULL;
+	}
+
+	return find_source(list, id);
+}
+
 static inline bool obs_source_init_handlers(struct obs_source *source)
 {
 	source->signals = signal_handler_create();
@@ -95,6 +113,13 @@ static inline bool obs_source_init_handlers(struct obs_source *source)
 	return (source->procs != NULL);
 }
 
+const char *obs_source_getdisplayname(enum obs_source_type type,
+		const char *id, const char *locale)
+{
+	const struct source_info *info = get_source_info(type, id);
+	return (info != NULL) ? info->getname(locale) : NULL;
+}
+
 /* internal initialization */
 bool obs_source_init(struct obs_source *source, const char *settings,
 		const struct source_info *info)
@@ -141,21 +166,9 @@ static inline void obs_source_dosignal(struct obs_source *source,
 obs_source_t obs_source_create(enum obs_source_type type, const char *id,
 		const char *name, const char *settings)
 {
-	const struct source_info *info = NULL;
-	struct darray *list = NULL;
 	struct obs_source *source;
 
-	switch (type) {
-	case SOURCE_INPUT:      list = &obs->input_types.da; break;
-	case SOURCE_FILTER:     list = &obs->filter_types.da; break;
-	case SOURCE_TRANSITION: list = &obs->transition_types.da; break;
-	case SOURCE_SCENE:
-	default:
-		blog(LOG_WARNING, "Tried to create invalid source type");
-		return NULL;
-	}
-
-	info = find_source(list, id);
+	const struct source_info *info = get_source_info(type, id);
 	if (!info) {
 		blog(LOG_WARNING, "Source '%s' not found", id);
 		return NULL;

+ 1 - 1
libobs/obs-source.h

@@ -249,7 +249,7 @@ struct obs_source {
 	bool                         rendering_filter;
 };
 
-extern bool get_source_info(void *module, const char *module_name,
+extern bool load_source_info(void *module, const char *module_name,
 		const char *source_name, struct source_info *info);
 
 extern bool obs_source_init(struct obs_source *source, const char *settings,

+ 9 - 3
libobs/obs.h

@@ -445,7 +445,9 @@ EXPORT void obs_source_process_filter(obs_source_t filter,
  * display oriantations.  Scenes can also be used like any other source.
  */
 EXPORT obs_scene_t obs_scene_create(const char *name);
-EXPORT void        obs_scene_release(obs_scene_t scene);
+
+EXPORT int         obs_scene_addref(obs_scene_t scene);
+EXPORT int         obs_scene_release(obs_scene_t scene);
 
 /** Gets the scene's source context */
 EXPORT obs_source_t obs_scene_getsource(obs_scene_t scene);
@@ -456,8 +458,12 @@ EXPORT obs_scene_t obs_scene_fromsource(obs_source_t source);
 /** Adds/creates a new scene item for a source */
 EXPORT obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source);
 
-/** Removes/destroys a scene item */
-EXPORT void  obs_sceneitem_destroy(obs_sceneitem_t item);
+/** Removes/destroys a scene item.  Returns the source reference counter
+ * (if any) */
+EXPORT int obs_sceneitem_destroy(obs_sceneitem_t item);
+
+/** Gets the source of a scene item */
+EXPORT obs_source_t obs_sceneitem_getsource(obs_sceneitem_t item);
 
 /* Functions for gettings/setting specific oriantation of a scene item */
 EXPORT void obs_sceneitem_setpos(obs_sceneitem_t item, const struct vec2 *pos);

+ 2 - 0
obs/obs-app.cpp

@@ -136,6 +136,8 @@ bool OBSApp::InitLocale()
 	const char *lang = config_get_string(globalConfig, "General",
 			"Language");
 
+	locale = lang;
+
 	stringstream file;
 	file << "locale/" << lang << ".txt";
 

+ 11 - 3
obs/obs-app.hpp

@@ -22,15 +22,18 @@
 
 #include <util/util.hpp>
 
+#include <string>
+
 class OBSAppBase : public wxApp {
 public:
 	virtual ~OBSAppBase();
 };
 
 class OBSApp : public OBSAppBase {
-	ConfigFile globalConfig;
-	TextLookup textLookup;
-	wxWindow   *mainWindow;
+	std::string locale;
+	ConfigFile  globalConfig;
+	TextLookup  textLookup;
+	wxWindow    *mainWindow;
 
 	bool InitGlobalConfig();
 	bool InitGlobalConfigDefaults();
@@ -51,6 +54,11 @@ public:
 
 	inline config_t GlobalConfig() const {return globalConfig;}
 
+	inline const char *GetLocale() const
+	{
+		return locale.c_str();
+	}
+
 	inline const char *GetString(const char *lookupVal) const
 	{
 		return textLookup.GetString(lookupVal);

+ 68 - 3
obs/window-basic-main.cpp

@@ -91,7 +91,8 @@ bool OBSBasic::Init()
 	//obs_scene_t scene = obs_scene_create("test scene");
 	//obs_add_source(obs_scene_getsource(scene));
 
-	//obs_load_module("test-input");
+	/* TODO: this is a test */
+	obs_load_module("test-input");
 
 	return true;
 }
@@ -259,13 +260,77 @@ void OBSBasic::sourcesRDown(wxMouseEvent &event)
 {
 }
 
-void OBSBasic::sourceAddClicked(wxCommandEvent &event)
+void OBSBasic::AddSource(obs_scene_t scene, const char *id)
+{
+	string name;
+
+	bool success = false;
+	while (!success) {
+		int ret = NameDialog::AskForName(this,
+				Str("MainWindow.AddSourceDlg.Title"),
+				Str("MainWindow.AddSourceDlg.Text"),
+				name);
+
+		if (ret == wxID_CANCEL)
+			break;
+
+		obs_source_t source = obs_get_source_by_name(
+				name.c_str());
+		if (!source) {
+			success = true;
+		} else {
+			wxMessageBox(WXStr("MainWindow.NameExists.Text"),
+				     WXStr("MainWindow.NameExists.Title"),
+				     wxOK|wxCENTRE, this);
+			obs_source_release(source);
+		}
+	}
+
+	if (success) {
+		obs_source_t source = obs_source_create(SOURCE_INPUT, id,
+				name.c_str(), NULL);
+		obs_add_source(source);
+		obs_sceneitem_t item = obs_scene_add(scene, source);
+		obs_source_release(source);
+	}
+}
+
+void OBSBasic::AddSourcePopup()
 {
 	int sceneSel = scenes->GetSelection();
+	size_t idx = 0;
+	const char *type;
+	vector<const char *> types;
+
 	if (sceneSel == wxNOT_FOUND)
 		return;
 
-	
+	obs_scene_t scene = (obs_scene_t)scenes->GetClientData(sceneSel);
+	obs_scene_addref(scene);
+
+	unique_ptr<wxMenu> popup(new wxMenu());
+	while (obs_enum_input_types(idx, &type)) {
+		const char *name = obs_source_getdisplayname(SOURCE_INPUT,
+				type, wxGetApp().GetLocale());
+
+		types.push_back(type);
+		popup->Append((int)idx, wxString(name, wxConvUTF8));
+
+		idx++;
+	}
+
+	if (idx) {
+		int id = WXDoPopupMenu(this, popup.get());
+		if (id != -1)
+			AddSource(scene, types[id]);
+	}
+
+	obs_scene_release(scene);
+}
+
+void OBSBasic::sourceAddClicked(wxCommandEvent &event)
+{
+	AddSourcePopup();
 }
 
 void OBSBasic::sourceRemoveClicked(wxCommandEvent &event)

+ 3 - 0
obs/window-basic-main.hpp

@@ -28,6 +28,9 @@ class OBSBasic : public OBSBasicBase {
 	static void SourceAdded(void *data, calldata_t params);
 	static void SourceDestroyed(void *data, calldata_t params);
 
+	void AddSource(obs_scene_t scene, const char *id);
+	void AddSourcePopup();
+
 	bool InitGraphics();
 
 	void NewProject();

+ 1 - 1
test/test-input/test-random.c

@@ -3,7 +3,7 @@
 
 const char *random_getname(const char *locale)
 {
-	return "Random;";
+	return "Random Source";
 }
 
 struct random_tex *random_create(const char *settings, obs_source_t source)