<commit_before>#include <json.h>
#include <remote_api.h>
#include <ttrss_api.h>
#include <cstring>
#include <algorithm>

#include <markreadthread.h>

namespace newsbeuter {

ttrss_api::ttrss_api(configcontainer * c) : remote_api(c) {
	single = (cfg->get_configvalue("ttrss-mode") == "single");
	auth_info = utils::strprintf("%s:%s", cfg->get_configvalue("ttrss-login").c_str(), cfg->get_configvalue("ttrss-password").c_str());
	auth_info_ptr = auth_info.c_str();
	sid = "";
}

ttrss_api::~ttrss_api() {
}

bool ttrss_api::authenticate() {
	 if (auth_lock.trylock()) {
		sid = retrieve_sid();
		auth_lock.unlock();
	 } else {
	 	// wait for other thread to finish and return its result:
	 	auth_lock.lock();
	 	auth_lock.unlock();
	 }

	return sid != "";
}

std::string ttrss_api::retrieve_sid() {
	CURL * handle = curl_easy_init();

	std::map<std::string, std::string> args;
	args["user"] = single ? "admin" : cfg->get_configvalue("ttrss-login");
	args["password"] = cfg->get_configvalue("ttrss-password");
	struct json_object * content = run_op("login", args);

	if (content == NULL)
		return "";

	std::string sid;

	struct json_object * session_id = json_object_object_get(content, "session_id");
	sid = json_object_get_string(session_id);

	json_object_put(content);

	LOG(LOG_DEBUG, "ttrss_api::retrieve_sid: sid = '%s'", sid.c_str());

	return sid;
}

struct json_object * ttrss_api::run_op(const std::string& op,
				       const std::map<std::string, std::string >& args,
				       bool try_login) {
	std::string url = utils::strprintf("%s/api/", cfg->get_configvalue("ttrss-url").c_str());

	std::string req_data = "{\"op\":\"" + op + "\",\"sid\":\"" + sid + "\"";

	for (std::map<std::string, std::string>::const_iterator it = args.begin(); it != args.end(); it++) {
		req_data += ",\"" + it->first + "\":\"" + it->second + "\"";
	}
	req_data += "}";

	std::string result = utils::retrieve_url(url, cfg, auth_info_ptr, &req_data);

	LOG(LOG_DEBUG, "ttrss_api::run_op(%s,...): post=%s reply = %s", op.c_str(), req_data.c_str(), result.c_str());

	struct json_object * reply = json_tokener_parse(result.c_str());
	if (is_error(reply)) {
		LOG(LOG_ERROR, "ttrss_api::run_op: reply failed to parse: %s", result.c_str());
		return NULL;
	}

	struct json_object * status = json_object_object_get(reply, "status");
	if (is_error(status)) {
		LOG(LOG_ERROR, "ttrss_api::run_op: no status code");
		return NULL;
	}

	struct json_object * content = json_object_object_get(reply, "content");
	if (is_error(content)) {
		LOG(LOG_ERROR, "ttrss_api::run_op: no content part in answer from server");
		return NULL;
	}

	if (json_object_get_int(status) != 0) {
		struct json_object * error = json_object_object_get(content, "error");
		if ((strcmp(json_object_get_string(error), "NOT_LOGGED_IN") == 0) && try_login) {
			json_object_put(reply);
			if (authenticate())
				return run_op(op, args, false);
			else
				return NULL;
		} else {
			json_object_put(reply);
			return NULL;
		}
	}

	// free the parent object, without freeing content as well:
	json_object_get(content);
	json_object_put(reply);
	return content;
}

std::vector<tagged_feedurl> ttrss_api::get_subscribed_urls() {

	std::string cat_url = utils::strprintf("%s/api/");
	std::string req_data = "{\"op\":\"getCategories\",\"sid\":\"" + sid + "\"}";
	std::string result = utils::retrieve_url(cat_url, cfg, auth_info_ptr, &req_data);

	LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: reply = %s", result.c_str());

	std::vector<tagged_feedurl> feeds;

	struct json_object * content = run_op("getCategories", std::map<std::string, std::string>());
	if (!content)
		return feeds;

	if (json_object_get_type(content) != json_type_array)
		return feeds;

	struct array_list * categories = json_object_get_array(content);

	int catsize = array_list_length(categories);

	// first fetch feeds within no category
	fetch_feeds_per_category(NULL, feeds);

	// then fetch the feeds of all categories
	for (int i=0;i<catsize;i++) {
		struct json_object * cat = (struct json_object *)array_list_get_idx(categories, i);
		fetch_feeds_per_category(cat, feeds);
	}

	json_object_put(content);

	return feeds;
}

void ttrss_api::configure_handle(CURL * /*handle*/) {
	// nothing required
}

bool ttrss_api::mark_all_read(const std::string& feed_url) {

	std::map<std::string, std::string> args;
	args["feed_id"] = url_to_id(feed_url);
	struct json_object * content = run_op("catchupFeed", args);

	if(!content)
		return false;

	json_object_put(content);
	return true;
}

bool ttrss_api::mark_article_read(const std::string& guid, bool read) {

	// Do this in a thread, as we don't care about the result enough to wait for
	// it.
	thread * mrt = new markreadthread( this, guid, read );
	mrt->start();
	return true;

}

bool ttrss_api::update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid) {
	std::string star_flag = cfg->get_configvalue("ttrss-flag-star");
	std::string publish_flag = cfg->get_configvalue("ttrss-flag-publish");
	bool success = true;

	if (star_flag.length() > 0) {
		if (strchr(oldflags.c_str(), star_flag[0])==NULL && strchr(newflags.c_str(), star_flag[0])!=NULL) {
			success = star_article(guid, true);
		} else if (strchr(oldflags.c_str(), star_flag[0])!=NULL && strchr(newflags.c_str(), star_flag[0])==NULL) {
			success = star_article(guid, false);
		}
	}

	if (publish_flag.length() > 0) {
		if (strchr(oldflags.c_str(), publish_flag[0])==NULL && strchr(newflags.c_str(), publish_flag[0])!=NULL) {
			success = publish_article(guid, true);
		} else if (strchr(oldflags.c_str(), publish_flag[0])!=NULL && strchr(newflags.c_str(), publish_flag[0])==NULL) {
			success = publish_article(guid, false);
		}
	}

	return success;
}

static bool sort_by_pubdate(const rsspp::item& a, const rsspp::item& b) {
	return a.pubDate_ts > b.pubDate_ts;
}

rsspp::feed ttrss_api::fetch_feed(const std::string& id) {
	rsspp::feed f;

	f.rss_version = rsspp::TTRSS_JSON;

	std::map<std::string, std::string> args;
	args["feed_id"] = id;
	args["show_content"] = "1";
	struct json_object * content = run_op("getHeadlines", args);

	if (!content)
		return f;

	if (json_object_get_type(content) != json_type_array) {
		LOG(LOG_ERROR, "ttrss_api::fetch_feed: content is not an array");
		return f;
	}

	struct array_list * items = json_object_get_array(content);
	int items_size = array_list_length(items);
	LOG(LOG_DEBUG, "ttrss_api::fetch_feed: %d items", items_size);

	for (int i=0;i<items_size;i++) {
		struct json_object * item_obj = (struct json_object *)array_list_get_idx(items, i);
		int id = json_object_get_int(json_object_object_get(item_obj, "id"));
		const char * title = json_object_get_string(json_object_object_get(item_obj, "title"));
		const char * link = json_object_get_string(json_object_object_get(item_obj, "link"));
		const char * content = json_object_get_string(json_object_object_get(item_obj, "content"));
		time_t updated = (time_t)json_object_get_int(json_object_object_get(item_obj, "updated"));
		bool unread = json_object_get_boolean(json_object_object_get(item_obj, "unread"));

		rsspp::item item;

		if (title)
			item.title = title;

		if (link)
			item.link = link;

		if (content)
			item.content_encoded = content;

		item.guid = utils::strprintf("%d", id);

		if (unread) {
			item.labels.push_back("ttrss:unread");
		} else {
			item.labels.push_back("ttrss:read");
		}

		char rfc822_date[128];
		strftime(rfc822_date, sizeof(rfc822_date), "%a, %d %b %Y %H:%M:%S %z", gmtime(&updated));
		item.pubDate = rfc822_date;
		item.pubDate_ts = updated;

		f.items.push_back(item);
	}

	std::sort(f.items.begin(), f.items.end(), sort_by_pubdate);

	json_object_put(content);
	return f;
}

void ttrss_api::fetch_feeds_per_category(struct json_object * cat, std::vector<tagged_feedurl>& feeds) {
	const char * cat_name = NULL;
	struct json_object * cat_title_obj = NULL;
	int cat_id;

	if (cat) {
		struct json_object * cat_id_obj = json_object_object_get(cat, "id");
		cat_id = json_object_get_int(cat_id_obj);

		cat_title_obj = json_object_object_get(cat, "title");
		cat_name = json_object_get_string(cat_title_obj);
		LOG(LOG_DEBUG, "ttrss_api::fetch_feeds_per_category: id = %d title = %s", cat_id, cat_name);
	}

	std::map<std::string, std::string> args;
	if (cat)
		args["cat_id"] = utils::to_s(cat_id);
	struct json_object * feed_list_obj = run_op("getFeeds", args);

	if (!feed_list_obj)
		return;

	struct array_list * feed_list = json_object_get_array(feed_list_obj);

	int feed_list_size = array_list_length(feed_list);

	for (int j=0;j<feed_list_size;j++) {
		struct json_object * feed = (struct json_object *)array_list_get_idx(feed_list, j);

		int feed_id = json_object_get_int(json_object_object_get(feed, "id"));
		const char * feed_title = json_object_get_string(json_object_object_get(feed, "title"));
		const char * feed_url = json_object_get_string(json_object_object_get(feed, "feed_url"));

		std::vector<std::string> tags;
		tags.push_back(std::string("~") + feed_title);
		if (cat_name) {
			tags.push_back(cat_name);
		}
		feeds.push_back(tagged_feedurl(utils::strprintf("%s#%d", feed_url, feed_id), tags));

		// TODO: cache feed_id -> feed_url (or feed_url -> feed_id ?)
	}

	json_object_put(feed_list_obj);

}

bool ttrss_api::star_article(const std::string& guid, bool star) {
	return update_article(guid, 0, star ? 1 : 0);
}

bool ttrss_api::publish_article(const std::string& guid, bool publish) {
	return update_article(guid, 1, publish ? 1 : 0);
}

bool ttrss_api::update_article(const std::string& guid, int field, int mode) {

	std::map<std::string, std::string> args;
	args["article_ids"] = guid;
	args["field"] = utils::to_s(field);
	args["mode"] = utils::to_s(mode);
	struct json_object * content = run_op("updateArticle", args);

	if (!content)
	    return false;

	json_object_put(content);
	return true;
}

std::string ttrss_api::url_to_id(const std::string& url) {
	const char * uri = url.c_str();
	const char * pound = strrchr(uri, '#');
	if (!pound)
		return "";
	return std::string(pound+1);
}

}
<commit_msg>TinyTinyRSS API workaround<commit_after>#include <json.h>
#include <remote_api.h>
#include <ttrss_api.h>
#include <cstring>
#include <algorithm>

#include <markreadthread.h>

namespace newsbeuter {

ttrss_api::ttrss_api(configcontainer * c) : remote_api(c) {
	single = (cfg->get_configvalue("ttrss-mode") == "single");
	auth_info = utils::strprintf("%s:%s", cfg->get_configvalue("ttrss-login").c_str(), cfg->get_configvalue("ttrss-password").c_str());
	auth_info_ptr = auth_info.c_str();
	sid = "";
}

ttrss_api::~ttrss_api() {
}

bool ttrss_api::authenticate() {
	 if (auth_lock.trylock()) {
		sid = retrieve_sid();
		auth_lock.unlock();
	 } else {
	 	// wait for other thread to finish and return its result:
	 	auth_lock.lock();
	 	auth_lock.unlock();
	 }

	return sid != "";
}

std::string ttrss_api::retrieve_sid() {
	CURL * handle = curl_easy_init();

	std::map<std::string, std::string> args;
	args["user"] = single ? "admin" : cfg->get_configvalue("ttrss-login");
	args["password"] = cfg->get_configvalue("ttrss-password");
	struct json_object * content = run_op("login", args);

	if (content == NULL)
		return "";

	std::string sid;

	struct json_object * session_id = json_object_object_get(content, "session_id");
	sid = json_object_get_string(session_id);

	json_object_put(content);

	LOG(LOG_DEBUG, "ttrss_api::retrieve_sid: sid = '%s'", sid.c_str());

	return sid;
}

struct json_object * ttrss_api::run_op(const std::string& op,
				       const std::map<std::string, std::string >& args,
				       bool try_login) {
	std::string url = utils::strprintf("%s/api/", cfg->get_configvalue("ttrss-url").c_str());

	std::string req_data = "{\"op\":\"" + op + "\",\"sid\":\"" + sid + "\"";

	for (std::map<std::string, std::string>::const_iterator it = args.begin(); it != args.end(); it++) {
		req_data += ",\"" + it->first + "\":\"" + it->second + "\"";
	}
	req_data += "}";

	std::string result = utils::retrieve_url(url, cfg, auth_info_ptr, &req_data);

	LOG(LOG_DEBUG, "ttrss_api::run_op(%s,...): post=%s reply = %s", op.c_str(), req_data.c_str(), result.c_str());

	struct json_object * reply = json_tokener_parse(result.c_str());
	if (is_error(reply)) {
		LOG(LOG_ERROR, "ttrss_api::run_op: reply failed to parse: %s", result.c_str());
		return NULL;
	}

	struct json_object * status = json_object_object_get(reply, "status");
	if (is_error(status)) {
		LOG(LOG_ERROR, "ttrss_api::run_op: no status code");
		return NULL;
	}

	struct json_object * content = json_object_object_get(reply, "content");
	if (is_error(content)) {
		LOG(LOG_ERROR, "ttrss_api::run_op: no content part in answer from server");
		return NULL;
	}

	if (json_object_get_int(status) != 0) {
		struct json_object * error = json_object_object_get(content, "error");
		if ((strcmp(json_object_get_string(error), "NOT_LOGGED_IN") == 0) && try_login) {
			json_object_put(reply);
			if (authenticate())
				return run_op(op, args, false);
			else
				return NULL;
		} else {
			json_object_put(reply);
			return NULL;
		}
	}

	// free the parent object, without freeing content as well:
	json_object_get(content);
	json_object_put(reply);
	return content;
}

std::vector<tagged_feedurl> ttrss_api::get_subscribed_urls() {

	std::string cat_url = utils::strprintf("%s/api/");
	std::string req_data = "{\"op\":\"getCategories\",\"sid\":\"" + sid + "\"}";
	std::string result = utils::retrieve_url(cat_url, cfg, auth_info_ptr, &req_data);

	LOG(LOG_DEBUG, "ttrss_api::get_subscribed_urls: reply = %s", result.c_str());

	std::vector<tagged_feedurl> feeds;

	struct json_object * content = run_op("getCategories", std::map<std::string, std::string>());
	if (!content)
		return feeds;

	if (json_object_get_type(content) != json_type_array)
		return feeds;

	struct array_list * categories = json_object_get_array(content);

	int catsize = array_list_length(categories);

	// first fetch feeds within no category
	fetch_feeds_per_category(NULL, feeds);

	// then fetch the feeds of all categories
	for (int i=0;i<catsize;i++) {
		struct json_object * cat = (struct json_object *)array_list_get_idx(categories, i);
		fetch_feeds_per_category(cat, feeds);
	}

	json_object_put(content);

	return feeds;
}

void ttrss_api::configure_handle(CURL * /*handle*/) {
	// nothing required
}

bool ttrss_api::mark_all_read(const std::string& feed_url) {

	std::map<std::string, std::string> args;
	args["feed_id"] = url_to_id(feed_url);
	struct json_object * content = run_op("catchupFeed", args);

	if(!content)
		return false;

	json_object_put(content);
	return true;
}

bool ttrss_api::mark_article_read(const std::string& guid, bool read) {

	// Do this in a thread, as we don't care about the result enough to wait for
	// it.
	thread * mrt = new markreadthread( this, guid, read );
	mrt->start();
	return true;

}

bool ttrss_api::update_article_flags(const std::string& oldflags, const std::string& newflags, const std::string& guid) {
	std::string star_flag = cfg->get_configvalue("ttrss-flag-star");
	std::string publish_flag = cfg->get_configvalue("ttrss-flag-publish");
	bool success = true;

	if (star_flag.length() > 0) {
		if (strchr(oldflags.c_str(), star_flag[0])==NULL && strchr(newflags.c_str(), star_flag[0])!=NULL) {
			success = star_article(guid, true);
		} else if (strchr(oldflags.c_str(), star_flag[0])!=NULL && strchr(newflags.c_str(), star_flag[0])==NULL) {
			success = star_article(guid, false);
		}
	}

	if (publish_flag.length() > 0) {
		if (strchr(oldflags.c_str(), publish_flag[0])==NULL && strchr(newflags.c_str(), publish_flag[0])!=NULL) {
			success = publish_article(guid, true);
		} else if (strchr(oldflags.c_str(), publish_flag[0])!=NULL && strchr(newflags.c_str(), publish_flag[0])==NULL) {
			success = publish_article(guid, false);
		}
	}

	return success;
}

static bool sort_by_pubdate(const rsspp::item& a, const rsspp::item& b) {
	return a.pubDate_ts > b.pubDate_ts;
}

rsspp::feed ttrss_api::fetch_feed(const std::string& id) {
	rsspp::feed f;

	f.rss_version = rsspp::TTRSS_JSON;

	std::map<std::string, std::string> args;
	args["feed_id"] = id;
	args["show_content"] = "1";
	struct json_object * content = run_op("getHeadlines", args);

	if (!content)
		return f;

	if (json_object_get_type(content) != json_type_array) {
		LOG(LOG_ERROR, "ttrss_api::fetch_feed: content is not an array");
		return f;
	}

	struct array_list * items = json_object_get_array(content);
	int items_size = array_list_length(items);
	LOG(LOG_DEBUG, "ttrss_api::fetch_feed: %d items", items_size);

	for (int i=0;i<items_size;i++) {
		struct json_object * item_obj = (struct json_object *)array_list_get_idx(items, i);
		int id = json_object_get_int(json_object_object_get(item_obj, "id"));
		const char * title = json_object_get_string(json_object_object_get(item_obj, "title"));
		const char * link = json_object_get_string(json_object_object_get(item_obj, "link"));
		const char * content = json_object_get_string(json_object_object_get(item_obj, "content"));
		time_t updated = (time_t)json_object_get_int(json_object_object_get(item_obj, "updated"));
		bool unread = json_object_get_boolean(json_object_object_get(item_obj, "unread"));

		rsspp::item item;

		if (title)
			item.title = title;

		if (link)
			item.link = link;

		if (content)
			item.content_encoded = content;

		item.guid = utils::strprintf("%d", id);

		if (unread) {
			item.labels.push_back("ttrss:unread");
		} else {
			item.labels.push_back("ttrss:read");
		}

		char rfc822_date[128];
		strftime(rfc822_date, sizeof(rfc822_date), "%a, %d %b %Y %H:%M:%S %z", gmtime(&updated));
		item.pubDate = rfc822_date;
		item.pubDate_ts = updated;

		f.items.push_back(item);
	}

	std::sort(f.items.begin(), f.items.end(), sort_by_pubdate);

	json_object_put(content);
	return f;
}

void ttrss_api::fetch_feeds_per_category(struct json_object * cat, std::vector<tagged_feedurl>& feeds) {
	const char * cat_name = NULL;
	struct json_object * cat_title_obj = NULL;
	int cat_id;

	if (cat) {
		struct json_object * cat_id_obj = json_object_object_get(cat, "id");
		cat_id = json_object_get_int(cat_id_obj);

		cat_title_obj = json_object_object_get(cat, "title");
		cat_name = json_object_get_string(cat_title_obj);
		LOG(LOG_DEBUG, "ttrss_api::fetch_feeds_per_category: id = %d title = %s", cat_id, cat_name);
	}
	else {
		// As uncategorized is a category itself (id = 0) and the default value
		// for a getFeeds is id = 0, the feeds in uncategorized will appear twice
		return;
	}

	std::map<std::string, std::string> args;
	if (cat)
		args["cat_id"] = utils::to_s(cat_id);
	struct json_object * feed_list_obj = run_op("getFeeds", args);

	if (!feed_list_obj)
		return;

	struct array_list * feed_list = json_object_get_array(feed_list_obj);

	int feed_list_size = array_list_length(feed_list);

	for (int j=0;j<feed_list_size;j++) {
		struct json_object * feed = (struct json_object *)array_list_get_idx(feed_list, j);

		int feed_id = json_object_get_int(json_object_object_get(feed, "id"));
		const char * feed_title = json_object_get_string(json_object_object_get(feed, "title"));
		const char * feed_url = json_object_get_string(json_object_object_get(feed, "feed_url"));

		std::vector<std::string> tags;
		tags.push_back(std::string("~") + feed_title);
		if (cat_name) {
			tags.push_back(cat_name);
		}
		feeds.push_back(tagged_feedurl(utils::strprintf("%s#%d", feed_url, feed_id), tags));

		// TODO: cache feed_id -> feed_url (or feed_url -> feed_id ?)
	}

	json_object_put(feed_list_obj);

}

bool ttrss_api::star_article(const std::string& guid, bool star) {
	return update_article(guid, 0, star ? 1 : 0);
}

bool ttrss_api::publish_article(const std::string& guid, bool publish) {
	return update_article(guid, 1, publish ? 1 : 0);
}

bool ttrss_api::update_article(const std::string& guid, int field, int mode) {

	std::map<std::string, std::string> args;
	args["article_ids"] = guid;
	args["field"] = utils::to_s(field);
	args["mode"] = utils::to_s(mode);
	struct json_object * content = run_op("updateArticle", args);

	if (!content)
	    return false;

	json_object_put(content);
	return true;
}

std::string ttrss_api::url_to_id(const std::string& url) {
	const char * uri = url.c_str();
	const char * pound = strrchr(uri, '#');
	if (!pound)
		return "";
	return std::string(pound+1);
}

}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include <dukat/uimanager.h>
#include <dukat/audiomanager.h>
#include <dukat/gamebase.h>

namespace dukat
{
	static constexpr auto channel = 10;

	void UIManager::add_control(UIControl* control)
	{
		for (auto it = controls.begin(); it != controls.end(); ++it)
		{
			if ((*it)->get_priority() < control->get_priority())
			{
				controls.insert(it, control);
				return;
			}
		}
		controls.insert(controls.end(), control);
	}

	void UIManager::remove_control(UIControl* control)
	{
		auto it = std::find(controls.begin(), controls.end(), control);
		if (it != controls.end())
		{
			controls.erase(it);
		}
		if (control == focus)
		{
			focus->set_focus(false);
			focus = nullptr;
		}
	}

	bool UIManager::handle_click(const Vector2 & pos)
	{
		for (auto ctrl : controls)
		{
			if (ctrl->is_enabled() && ctrl->get_bb().contains(pos))
			{
				ctrl->trigger();
				return true;
			}
		}
		return false;
	}

	void UIManager::first_control(void)
	{
		if (controls.empty())
			return;
		auto it = std::find_if(controls.begin(), controls.end(),
			[](UIControl* c) { return c->is_enabled() && c->get_index() >= 0; });
		if (it != controls.end())
		{
			if (focus != nullptr)
			{
				focus->set_focus(false);
			}
			focus = *it;
			focus->set_focus(true);
		}
	}

	// search for previous element starting from current focus
	void UIManager::prev_control(void)
	{
		if (controls.empty())
			return;
		auto it = (focus == nullptr) ? controls.rbegin() :
			std::find(controls.rbegin(), controls.rend(), focus);
		if (*it == focus)
		{
			++it; // skip current element in focus
		}
		it = std::find_if(it, controls.rend(),
			[](UIControl* c) { return c->is_enabled() && c->get_index() >= 0; });
		if (it != controls.rend())
		{
			if (focus != nullptr)
			{
				focus->set_focus(false);
			}
			focus = *it;
			focus->set_focus(true);

			if (select_sample != nullptr)
				game->get_audio()->play_sample(select_sample, channel);
		}
	}

	// search for next element starting from current focus
	void UIManager::next_control(void)
	{
		if (controls.empty())
			return;
		auto it = (focus == nullptr) ? controls.begin() :
			std::find(controls.begin(), controls.end(), focus);
		if (*it == focus)
		{
			++it; // skip current element in focus
		}
		it = std::find_if(it, controls.end(),
			[](UIControl* c) { return c->is_enabled() && c->get_index() >= 0; });
		if (it != controls.end())
		{
			if (focus != nullptr)
				focus->set_focus(false);
			focus = *it;
			focus->set_focus(true);

			if (select_sample != nullptr)
				game->get_audio()->play_sample(select_sample, channel);
		}
	}

	void UIManager::focus_on(UIControl* control)
	{
		if (controls.empty() || focus == control)
			return;

		if (focus != nullptr)
			focus->set_focus(false);
		focus = control;
		focus->set_focus(true);
	}

	bool UIManager::trigger_focus(void)
	{
		if (focus != nullptr)
		{
			focus->trigger();
			if (trigger_sample != nullptr)
				game->get_audio()->play_sample(trigger_sample, channel);
			return true;
		}
		return false;
	}

	bool UIManager::cycle_focus(int dir)
	{
		if (focus != nullptr)
		{
			focus->cycle(dir);
			if (cycle_sample != nullptr)
				game->get_audio()->play_sample(cycle_sample, channel);
			return true;
		}
		return false;
	}

	void UIManager::set_select_sample(const std::string& sample)
	{
		if (sample.length() > 0)
			select_sample = game->get_samples()->get_sample(sample);
		else
			select_sample = nullptr;
	}

	void UIManager::set_trigger_sample(const std::string& sample)
	{
		if (sample.length() > 0)
			trigger_sample = game->get_samples()->get_sample(sample);
		else
			trigger_sample = nullptr;
	}

	void UIManager::set_cycle_sample(const std::string& sample)
	{
		if (sample.length() > 0)
			cycle_sample = game->get_samples()->get_sample(sample);
		else
			cycle_sample = nullptr;
	}
}<commit_msg>Roll controls at start / end of list<commit_after>#include "stdafx.h"
#include <dukat/uimanager.h>
#include <dukat/audiomanager.h>
#include <dukat/gamebase.h>

namespace dukat
{
	static constexpr auto channel = 10;

	void UIManager::add_control(UIControl* control)
	{
		for (auto it = controls.begin(); it != controls.end(); ++it)
		{
			if ((*it)->get_priority() < control->get_priority())
			{
				controls.insert(it, control);
				return;
			}
		}
		controls.insert(controls.end(), control);
	}

	void UIManager::remove_control(UIControl* control)
	{
		auto it = std::find(controls.begin(), controls.end(), control);
		if (it != controls.end())
		{
			controls.erase(it);
		}
		if (control == focus)
		{
			focus->set_focus(false);
			focus = nullptr;
		}
	}

	bool UIManager::handle_click(const Vector2 & pos)
	{
		for (auto ctrl : controls)
		{
			if (ctrl->is_enabled() && ctrl->get_bb().contains(pos))
			{
				ctrl->trigger();
				return true;
			}
		}
		return false;
	}

	void UIManager::first_control(void)
	{
		if (controls.empty())
			return;
		auto it = std::find_if(controls.begin(), controls.end(),
			[](UIControl* c) { return c->is_enabled() && c->get_index() >= 0; });
		if (it != controls.end())
		{
			if (focus != nullptr)
			{
				focus->set_focus(false);
			}
			focus = *it;
			focus->set_focus(true);
		}
	}

	// search for previous element starting from current focus
	void UIManager::prev_control(void)
	{
		if (controls.empty())
			return;
		auto it = (focus == nullptr) ? controls.rbegin() :
			std::find(controls.rbegin(), controls.rend(), focus);
		if (*it == focus)
		{
			++it; // skip current element in focus
		}
		if (it == controls.rend()) // if we're at the first element, roll to end of list
			it = controls.rbegin();
		it = std::find_if(it, controls.rend(),
			[](UIControl* c) { return c->is_enabled() && c->get_index() >= 0; });
		if (it != controls.rend())
		{
			if (focus != nullptr)
			{
				focus->set_focus(false);
			}
			focus = *it;
			focus->set_focus(true);

			if (select_sample != nullptr)
				game->get_audio()->play_sample(select_sample, channel);
		}
	}

	// search for next element starting from current focus
	void UIManager::next_control(void)
	{
		if (controls.empty())
			return;
		auto it = (focus == nullptr) ? controls.begin() :
			std::find(controls.begin(), controls.end(), focus);
		if (*it == focus)
		{
			++it; // skip current element in focus
		}
		if (it == controls.end()) // if we're at the last element, roll to the start of list
			it = controls.begin();
		it = std::find_if(it, controls.end(),
			[](UIControl* c) { return c->is_enabled() && c->get_index() >= 0; });
		if (it != controls.end())
		{
			if (focus != nullptr)
				focus->set_focus(false);
			focus = *it;
			focus->set_focus(true);

			if (select_sample != nullptr)
				game->get_audio()->play_sample(select_sample, channel);
		}
	}

	void UIManager::focus_on(UIControl* control)
	{
		if (controls.empty() || focus == control)
			return;

		if (focus != nullptr)
			focus->set_focus(false);
		focus = control;
		focus->set_focus(true);
	}

	bool UIManager::trigger_focus(void)
	{
		if (focus != nullptr)
		{
			focus->trigger();
			if (trigger_sample != nullptr)
				game->get_audio()->play_sample(trigger_sample, channel);
			return true;
		}
		return false;
	}

	bool UIManager::cycle_focus(int dir)
	{
		if (focus != nullptr)
		{
			focus->cycle(dir);
			if (cycle_sample != nullptr)
				game->get_audio()->play_sample(cycle_sample, channel);
			return true;
		}
		return false;
	}

	void UIManager::set_select_sample(const std::string& sample)
	{
		if (sample.length() > 0)
			select_sample = game->get_samples()->get_sample(sample);
		else
			select_sample = nullptr;
	}

	void UIManager::set_trigger_sample(const std::string& sample)
	{
		if (sample.length() > 0)
			trigger_sample = game->get_samples()->get_sample(sample);
		else
			trigger_sample = nullptr;
	}

	void UIManager::set_cycle_sample(const std::string& sample)
	{
		if (sample.length() > 0)
			cycle_sample = game->get_samples()->get_sample(sample);
		else
			cycle_sample = nullptr;
	}
}<|endoftext|>


<commit_before>/****************************************************************************
 *
 *   Copyright (c) 2013-2016 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/*
 * @file LandDetector.cpp
 *
 * @author Johan Jansen <jnsn.johan@gmail.com>
 * @author Julian Oes <julian@oes.ch>
 */

#include <px4_config.h>
#include <px4_defines.h>
#include <drivers/drv_hrt.h>

#include "LandDetector.h"

namespace land_detector
{

LandDetector::LandDetector() :
	_landDetectedPub(nullptr),
	_landDetected{0, false, false},
	_freefall_hysteresis(false),
	_landed_hysteresis(true),
	_taskShouldExit(false),
	_taskIsRunning(false),
	_work{}
{
	// Use Trigger time when transitioning from in-air (false) to landed (true).
	_landed_hysteresis.set_hysteresis_time_from(false, LAND_DETECTOR_TRIGGER_TIME_US);
}

LandDetector::~LandDetector()
{
	work_cancel(HPWORK, &_work);
	_taskShouldExit = true;
}

int LandDetector::start()
{
	_taskShouldExit = false;

	/* schedule a cycle to start things */
	work_queue(HPWORK, &_work, (worker_t)&LandDetector::_cycle_trampoline, this, 0);

	return 0;
}

void LandDetector::stop()
{
	_taskShouldExit = true;
}

void
LandDetector::_cycle_trampoline(void *arg)
{
	LandDetector *dev = reinterpret_cast<LandDetector *>(arg);

	dev->_cycle();
}

void LandDetector::_cycle()
{
	if (!_taskIsRunning) {
		PX4_INFO("we are doing the init");
		// Advertise the first land detected uORB.
		_landDetected.timestamp = hrt_absolute_time();
		_landDetected.landed = false;
		_landDetected.freefall = false;

		// Initialize uORB topics.
		_initialize_topics();

		_check_params(true);

		// Task is now running, keep doing so until we need to stop.
		_taskIsRunning = true;
	}

	_check_params(false);

	_update_topics();

	_update_state();

	bool landDetected = (_state == LandDetectionState::LANDED);
	bool freefallDetected = (_state == LandDetectionState::FREEFALL);

	// Only publish very first time or when the result has changed.
	if ((_landDetectedPub == nullptr) ||
	    (_landDetected.landed != landDetected) ||
	    (_landDetected.freefall != freefallDetected)) {

		_landDetected.timestamp = hrt_absolute_time();
		_landDetected.landed = (_state == LandDetectionState::LANDED);
		_landDetected.freefall = (_state == LandDetectionState::FREEFALL);

		int instance;
		orb_publish_auto(ORB_ID(vehicle_land_detected), &_landDetectedPub, &_landDetected,
				 &instance, ORB_PRIO_DEFAULT);
	}

	if (!_taskShouldExit) {

		// Schedule next cycle.
		work_queue(HPWORK, &_work, (worker_t)&LandDetector::_cycle_trampoline, this,
			   USEC2TICK(1000000 / LAND_DETECTOR_UPDATE_RATE_HZ));

	} else {
		_taskIsRunning = false;
	}
}

void LandDetector::_check_params(const bool force)
{
	bool updated;
	parameter_update_s paramUpdate;

	orb_check(_parameterSub, &updated);

	if (updated) {
		orb_copy(ORB_ID(parameter_update), _parameterSub, &paramUpdate);
	}

	if (updated || force) {
		_update_params();
	}
}

void LandDetector::_update_state()
{
	bool landed = _get_landed_state();
	_landed_hysteresis.set_state_and_update(landed);
	_freefall_hysteresis.set_state_and_update(_get_freefall_state());

	if (_freefall_hysteresis.get_state()) {
		_state = LandDetectionState::FREEFALL;

	} else if (_landed_hysteresis.get_state()) {
		_state = LandDetectionState::LANDED;

	} else {
		_state = LandDetectionState::FLYING;
	}

	return;
}

bool LandDetector::_orb_update(const struct orb_metadata *meta, int handle, void *buffer)
{
	bool newData = false;

	// check if there is new data to grab
	if (orb_check(handle, &newData) != OK) {
		return false;
	}

	if (!newData) {
		return false;
	}

	if (orb_copy(meta, handle, buffer) != OK) {
		return false;
	}

	return true;
}

} // namespace land_detector
<commit_msg>land_detector: remove leftover printf (#5178)<commit_after>/****************************************************************************
 *
 *   Copyright (c) 2013-2016 PX4 Development Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name PX4 nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/*
 * @file LandDetector.cpp
 *
 * @author Johan Jansen <jnsn.johan@gmail.com>
 * @author Julian Oes <julian@oes.ch>
 */

#include <px4_config.h>
#include <px4_defines.h>
#include <drivers/drv_hrt.h>

#include "LandDetector.h"

namespace land_detector
{

LandDetector::LandDetector() :
	_landDetectedPub(nullptr),
	_landDetected{0, false, false},
	_freefall_hysteresis(false),
	_landed_hysteresis(true),
	_taskShouldExit(false),
	_taskIsRunning(false),
	_work{}
{
	// Use Trigger time when transitioning from in-air (false) to landed (true).
	_landed_hysteresis.set_hysteresis_time_from(false, LAND_DETECTOR_TRIGGER_TIME_US);
}

LandDetector::~LandDetector()
{
	work_cancel(HPWORK, &_work);
	_taskShouldExit = true;
}

int LandDetector::start()
{
	_taskShouldExit = false;

	/* schedule a cycle to start things */
	work_queue(HPWORK, &_work, (worker_t)&LandDetector::_cycle_trampoline, this, 0);

	return 0;
}

void LandDetector::stop()
{
	_taskShouldExit = true;
}

void
LandDetector::_cycle_trampoline(void *arg)
{
	LandDetector *dev = reinterpret_cast<LandDetector *>(arg);

	dev->_cycle();
}

void LandDetector::_cycle()
{
	if (!_taskIsRunning) {
		// Advertise the first land detected uORB.
		_landDetected.timestamp = hrt_absolute_time();
		_landDetected.landed = false;
		_landDetected.freefall = false;

		// Initialize uORB topics.
		_initialize_topics();

		_check_params(true);

		// Task is now running, keep doing so until we need to stop.
		_taskIsRunning = true;
	}

	_check_params(false);

	_update_topics();

	_update_state();

	bool landDetected = (_state == LandDetectionState::LANDED);
	bool freefallDetected = (_state == LandDetectionState::FREEFALL);

	// Only publish very first time or when the result has changed.
	if ((_landDetectedPub == nullptr) ||
	    (_landDetected.landed != landDetected) ||
	    (_landDetected.freefall != freefallDetected)) {

		_landDetected.timestamp = hrt_absolute_time();
		_landDetected.landed = (_state == LandDetectionState::LANDED);
		_landDetected.freefall = (_state == LandDetectionState::FREEFALL);

		int instance;
		orb_publish_auto(ORB_ID(vehicle_land_detected), &_landDetectedPub, &_landDetected,
				 &instance, ORB_PRIO_DEFAULT);
	}

	if (!_taskShouldExit) {

		// Schedule next cycle.
		work_queue(HPWORK, &_work, (worker_t)&LandDetector::_cycle_trampoline, this,
			   USEC2TICK(1000000 / LAND_DETECTOR_UPDATE_RATE_HZ));

	} else {
		_taskIsRunning = false;
	}
}

void LandDetector::_check_params(const bool force)
{
	bool updated;
	parameter_update_s paramUpdate;

	orb_check(_parameterSub, &updated);

	if (updated) {
		orb_copy(ORB_ID(parameter_update), _parameterSub, &paramUpdate);
	}

	if (updated || force) {
		_update_params();
	}
}

void LandDetector::_update_state()
{
	bool landed = _get_landed_state();
	_landed_hysteresis.set_state_and_update(landed);
	_freefall_hysteresis.set_state_and_update(_get_freefall_state());

	if (_freefall_hysteresis.get_state()) {
		_state = LandDetectionState::FREEFALL;

	} else if (_landed_hysteresis.get_state()) {
		_state = LandDetectionState::LANDED;

	} else {
		_state = LandDetectionState::FLYING;
	}

	return;
}

bool LandDetector::_orb_update(const struct orb_metadata *meta, int handle, void *buffer)
{
	bool newData = false;

	// check if there is new data to grab
	if (orb_check(handle, &newData) != OK) {
		return false;
	}

	if (!newData) {
		return false;
	}

	if (orb_copy(meta, handle, buffer) != OK) {
		return false;
	}

	return true;
}

} // namespace land_detector
<|endoftext|>


<commit_before>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016-2020 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <inviwo/dataframe/datastructures/dataframe.h>

#include <inviwo/core/datastructures/buffer/buffer.h>
#include <inviwo/core/datastructures/buffer/bufferram.h>
#include <inviwo/dataframe/datastructures/datapoint.h>
#include <inviwo/core/util/formatdispatching.h>
#include <inviwo/core/util/stdextensions.h>

#include <utility>

namespace inviwo {

/*
 * This creates a table with one column: The index column
 */
DataFrame::DataFrame(std::uint32_t size) : columns_{} {
    // at the moment, GPUs only support uints up to 32bit
    auto& cont = addColumn<std::uint32_t>("index", size)
                     ->getTypedBuffer()
                     ->getEditableRAMRepresentation()
                     ->getDataContainer();
    std::iota(cont.begin(), cont.end(), 0);
}
DataFrame::DataFrame(const DataFrame& rhs) : columns_{} {
    for (const auto& col : rhs.columns_) {
        columns_.emplace_back(col->clone());
    }
}
DataFrame& DataFrame::operator=(const DataFrame& that) {
    if (this != &that) {
        DataFrame tmp(that);
        std::swap(tmp.columns_, columns_);
    }
    return *this;
}
DataFrame& DataFrame::operator=(DataFrame&&) = default;
DataFrame::DataFrame(DataFrame&&) = default;

std::shared_ptr<Column> DataFrame::addColumn(std::shared_ptr<Column> column) {
    if (column) {
        columns_.push_back(column);
    }
    return column;
}

std::shared_ptr<Column> DataFrame::addColumnFromBuffer(const std::string& identifier,
                                                       std::shared_ptr<const BufferBase> buffer) {
    return buffer->getRepresentation<BufferRAM>()
        ->dispatch<std::shared_ptr<Column>, dispatching::filter::Scalars>([&](auto buf) {
            using ValueType = util::PrecisionValueType<decltype(buf)>;
            auto col = this->addColumn<ValueType>(identifier);
            auto newBuf = col->getTypedBuffer();
            auto& newVec = newBuf->getEditableRAMRepresentation()->getDataContainer();
            auto& oldVec = buf->getDataContainer();
            newVec.insert(newVec.end(), oldVec.begin(), oldVec.end());
            return col;
        });
}

void DataFrame::dropColumn(const std::string& header) {
    columns_.erase(std::remove_if(std::begin(columns_), std::end(columns_),
                                  [&](std::shared_ptr<Column> col) -> bool {
                                      return col->getHeader() == header;
                                  }),
                   std::end(columns_));
}

void DataFrame::dropColumn(const size_t index) {
    if (index >= columns_.size()) {
        return;
    }
    columns_.erase(std::begin(columns_) + index);
}

std::shared_ptr<CategoricalColumn> DataFrame::addCategoricalColumn(const std::string& header,
                                                                   size_t size) {
    auto col = std::make_shared<CategoricalColumn>(header);
    col->getTypedBuffer()->getEditableRAMRepresentation()->getDataContainer().resize(size);
    columns_.push_back(col);
    return col;
}

void DataFrame::addRow(const std::vector<std::string>& data) {
    if (columns_.size() <= 1) {
        throw NoColumns("DataFrame: DataFrame has no columns", IVW_CONTEXT);
    } else if (columns_.size() != data.size() + 1) {  // consider index column of DataFrame
        std::ostringstream oss;
        oss << "Data does not match column count, DataFrame has " << (columns_.size() - 1)
            << " columns while input data has " << data.size();
        oss << ". Input data is : " << joinString(data, " | ");
        throw InvalidColCount(oss.str(), IVW_CONTEXT);
    }
    // Try to match up input data with columns.
    std::vector<size_t> columnIdForDataTypeErrors;
    for (size_t i = 0; i < data.size(); ++i) {
        try {
            columns_[i + 1]->add(data[i]);
        } catch (InvalidConversion& ) {
            columnIdForDataTypeErrors.push_back(i + 1);
        }
    }
    if (!columnIdForDataTypeErrors.empty()) {
        std::stringstream errStr;
        errStr << "Data type mismatch for columns: (";
        auto joiner = util::make_ostream_joiner(errStr, ", ");
        std::copy(columnIdForDataTypeErrors.begin(), columnIdForDataTypeErrors.end(), joiner);
        errStr << ") with values: (";
        std::copy(data.begin(), data.end(), joiner);
        errStr << ")" << std::endl
               << " DataFrame will be in an invalid state since since all columns must be of equal "
                  "size.";
        throw DataTypeMismatch(errStr.str(), IVW_CONTEXT);
    }
}

DataFrame::DataItem DataFrame::getDataItem(size_t index, bool getStringsAsStrings) const {
    DataItem di;
    for (auto column : columns_) {
        di.push_back(column->get(index, getStringsAsStrings));
    }
    return di;
}

void DataFrame::updateIndexBuffer() {
    const size_t nrows = getNumberOfRows();

    auto indexBuffer = std::static_pointer_cast<Buffer<std::uint32_t>>(columns_[0]->getBuffer());
    auto& indexVector = indexBuffer->getEditableRAMRepresentation()->getDataContainer();
    indexVector.resize(nrows);
    std::iota(indexVector.begin(), indexVector.end(), 0);
}

size_t DataFrame::getNumberOfColumns() const { return columns_.size(); }

size_t DataFrame::getNumberOfRows() const {
    size_t size = 0;
    if (columns_.size() > 1) {
        for (size_t i = 1; i < columns_.size(); i++) {
            size = std::max(size, columns_[i]->getSize());
        }
    }
    return size;
}

std::vector<std::shared_ptr<Column>>::const_iterator DataFrame::end() const {
    return columns_.end();
}

const std::vector<std::pair<std::string, const DataFormatBase *>> DataFrame::getHeaders() const {
    std::vector<std::pair<std::string, const DataFormatBase *>> headers;
    for (const auto& c : columns_) {
        headers.emplace_back(c->getHeader(), c->getBuffer()->getDataFormat());
    }
    return headers;
}

std::string DataFrame::getHeader(size_t idx) const { return columns_[idx]->getHeader(); }

std::shared_ptr<const Column> DataFrame::getColumn(size_t index) const { return columns_[index]; }

std::shared_ptr<Column> DataFrame::getColumn(const std::string& name) {
    return util::find_if_or_null(columns_, [name](auto c) { return c->getHeader() == name; });
}

std::shared_ptr<const Column> DataFrame::getColumn(const std::string& name) const {
    return util::find_if_or_null(columns_, [name](auto c) { return c->getHeader() == name; });
}

std::shared_ptr<Column> DataFrame::getColumn(size_t index) { return columns_[index]; }

std::shared_ptr<const TemplateColumn<std::uint32_t>> DataFrame::getIndexColumn() const {
    return std::dynamic_pointer_cast<const TemplateColumn<std::uint32_t>>(columns_[0]);
}

std::shared_ptr<TemplateColumn<std::uint32_t>> DataFrame::getIndexColumn() {
    return std::dynamic_pointer_cast<TemplateColumn<std::uint32_t>>(columns_[0]);
}

std::vector<std::shared_ptr<Column>>::iterator DataFrame::begin() { return columns_.begin(); }

std::vector<std::shared_ptr<Column>>::const_iterator DataFrame::begin() const {
    return columns_.begin();
}

std::vector<std::shared_ptr<Column>>::iterator DataFrame::end() { return columns_.end(); }

std::shared_ptr<DataFrame> createDataFrame(const std::vector<std::vector<std::string>>& exampleRows,
                                           const std::vector<std::string>& colHeaders) {

    if (exampleRows.empty()) {
        throw InvalidColCount("No example data to derive columns from",
                              IVW_CONTEXT_CUSTOM("DataFrame::createDataFrame"));
    }

    // Guess type of each column, ordinal or nominal
    std::vector<std::pair<unsigned int, unsigned int>> columnTypeStatistics(colHeaders.size(),
                                                                            std::make_pair(0, 0));
    for (size_t i = 0; i < exampleRows.size(); ++i) {
        const auto& rowData = exampleRows[i];
        if (rowData.size() != colHeaders.size()) {
            std::ostringstream oss;
            oss << "Number of headers does not match column count, number of headers: "
                << colHeaders.size() << ", number of columns: " << rowData.size();
            throw InvalidColCount(oss.str(), IVW_CONTEXT_CUSTOM("DataFrame::createDataFrame"));
        }
        for (auto column = 0u; column < rowData.size(); ++column) {
            std::istringstream iss(trim(rowData[column]));
            float d;
            // try extracting floating point number. If the stream is not at its end, then there was
            // trailing data. Hence this value does not represent a floating point number.
            if ((iss >> d) && iss.eof()) {
                // ordinal buffer
                columnTypeStatistics[column].first++;
            } else {  // nominal buffer
                columnTypeStatistics[column].second++;
            }
        }
    }

    auto dataFrame = std::make_shared<DataFrame>(0u);
    for (size_t column = 0; column < exampleRows.front().size(); ++column) {
        const auto header =
            (!colHeaders.empty() ? colHeaders[column]
                                 : std::string("Column ") + std::to_string(column + 1));
        if (columnTypeStatistics[column].first > columnTypeStatistics[column].second) {
            // ordinal buffer
            dataFrame->addColumn<float>(header, 0u);
        } else {  // nominal buffer
            dataFrame->addCategoricalColumn(header, 0);
        }
    }
    return dataFrame;
}

}  // namespace inviwo
<commit_msg>Jenkins: Format fixes<commit_after>/*********************************************************************************
 *
 * Inviwo - Interactive Visualization Workshop
 *
 * Copyright (c) 2016-2020 Inviwo Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *********************************************************************************/

#include <inviwo/dataframe/datastructures/dataframe.h>

#include <inviwo/core/datastructures/buffer/buffer.h>
#include <inviwo/core/datastructures/buffer/bufferram.h>
#include <inviwo/dataframe/datastructures/datapoint.h>
#include <inviwo/core/util/formatdispatching.h>
#include <inviwo/core/util/stdextensions.h>

#include <utility>

namespace inviwo {

/*
 * This creates a table with one column: The index column
 */
DataFrame::DataFrame(std::uint32_t size) : columns_{} {
    // at the moment, GPUs only support uints up to 32bit
    auto& cont = addColumn<std::uint32_t>("index", size)
                     ->getTypedBuffer()
                     ->getEditableRAMRepresentation()
                     ->getDataContainer();
    std::iota(cont.begin(), cont.end(), 0);
}
DataFrame::DataFrame(const DataFrame& rhs) : columns_{} {
    for (const auto& col : rhs.columns_) {
        columns_.emplace_back(col->clone());
    }
}
DataFrame& DataFrame::operator=(const DataFrame& that) {
    if (this != &that) {
        DataFrame tmp(that);
        std::swap(tmp.columns_, columns_);
    }
    return *this;
}
DataFrame& DataFrame::operator=(DataFrame&&) = default;
DataFrame::DataFrame(DataFrame&&) = default;

std::shared_ptr<Column> DataFrame::addColumn(std::shared_ptr<Column> column) {
    if (column) {
        columns_.push_back(column);
    }
    return column;
}

std::shared_ptr<Column> DataFrame::addColumnFromBuffer(const std::string& identifier,
                                                       std::shared_ptr<const BufferBase> buffer) {
    return buffer->getRepresentation<BufferRAM>()
        ->dispatch<std::shared_ptr<Column>, dispatching::filter::Scalars>([&](auto buf) {
            using ValueType = util::PrecisionValueType<decltype(buf)>;
            auto col = this->addColumn<ValueType>(identifier);
            auto newBuf = col->getTypedBuffer();
            auto& newVec = newBuf->getEditableRAMRepresentation()->getDataContainer();
            auto& oldVec = buf->getDataContainer();
            newVec.insert(newVec.end(), oldVec.begin(), oldVec.end());
            return col;
        });
}

void DataFrame::dropColumn(const std::string& header) {
    columns_.erase(std::remove_if(std::begin(columns_), std::end(columns_),
                                  [&](std::shared_ptr<Column> col) -> bool {
                                      return col->getHeader() == header;
                                  }),
                   std::end(columns_));
}

void DataFrame::dropColumn(const size_t index) {
    if (index >= columns_.size()) {
        return;
    }
    columns_.erase(std::begin(columns_) + index);
}

std::shared_ptr<CategoricalColumn> DataFrame::addCategoricalColumn(const std::string& header,
                                                                   size_t size) {
    auto col = std::make_shared<CategoricalColumn>(header);
    col->getTypedBuffer()->getEditableRAMRepresentation()->getDataContainer().resize(size);
    columns_.push_back(col);
    return col;
}

void DataFrame::addRow(const std::vector<std::string>& data) {
    if (columns_.size() <= 1) {
        throw NoColumns("DataFrame: DataFrame has no columns", IVW_CONTEXT);
    } else if (columns_.size() != data.size() + 1) {  // consider index column of DataFrame
        std::ostringstream oss;
        oss << "Data does not match column count, DataFrame has " << (columns_.size() - 1)
            << " columns while input data has " << data.size();
        oss << ". Input data is : " << joinString(data, " | ");
        throw InvalidColCount(oss.str(), IVW_CONTEXT);
    }
    // Try to match up input data with columns.
    std::vector<size_t> columnIdForDataTypeErrors;
    for (size_t i = 0; i < data.size(); ++i) {
        try {
            columns_[i + 1]->add(data[i]);
        } catch (InvalidConversion&) {
            columnIdForDataTypeErrors.push_back(i + 1);
        }
    }
    if (!columnIdForDataTypeErrors.empty()) {
        std::stringstream errStr;
        errStr << "Data type mismatch for columns: (";
        auto joiner = util::make_ostream_joiner(errStr, ", ");
        std::copy(columnIdForDataTypeErrors.begin(), columnIdForDataTypeErrors.end(), joiner);
        errStr << ") with values: (";
        std::copy(data.begin(), data.end(), joiner);
        errStr << ")" << std::endl
               << " DataFrame will be in an invalid state since since all columns must be of equal "
                  "size.";
        throw DataTypeMismatch(errStr.str(), IVW_CONTEXT);
    }
}

DataFrame::DataItem DataFrame::getDataItem(size_t index, bool getStringsAsStrings) const {
    DataItem di;
    for (auto column : columns_) {
        di.push_back(column->get(index, getStringsAsStrings));
    }
    return di;
}

void DataFrame::updateIndexBuffer() {
    const size_t nrows = getNumberOfRows();

    auto indexBuffer = std::static_pointer_cast<Buffer<std::uint32_t>>(columns_[0]->getBuffer());
    auto& indexVector = indexBuffer->getEditableRAMRepresentation()->getDataContainer();
    indexVector.resize(nrows);
    std::iota(indexVector.begin(), indexVector.end(), 0);
}

size_t DataFrame::getNumberOfColumns() const { return columns_.size(); }

size_t DataFrame::getNumberOfRows() const {
    size_t size = 0;
    if (columns_.size() > 1) {
        for (size_t i = 1; i < columns_.size(); i++) {
            size = std::max(size, columns_[i]->getSize());
        }
    }
    return size;
}

std::vector<std::shared_ptr<Column>>::const_iterator DataFrame::end() const {
    return columns_.end();
}

const std::vector<std::pair<std::string, const DataFormatBase*>> DataFrame::getHeaders() const {
    std::vector<std::pair<std::string, const DataFormatBase*>> headers;
    for (const auto& c : columns_) {
        headers.emplace_back(c->getHeader(), c->getBuffer()->getDataFormat());
    }
    return headers;
}

std::string DataFrame::getHeader(size_t idx) const { return columns_[idx]->getHeader(); }

std::shared_ptr<const Column> DataFrame::getColumn(size_t index) const { return columns_[index]; }

std::shared_ptr<Column> DataFrame::getColumn(const std::string& name) {
    return util::find_if_or_null(columns_, [name](auto c) { return c->getHeader() == name; });
}

std::shared_ptr<const Column> DataFrame::getColumn(const std::string& name) const {
    return util::find_if_or_null(columns_, [name](auto c) { return c->getHeader() == name; });
}

std::shared_ptr<Column> DataFrame::getColumn(size_t index) { return columns_[index]; }

std::shared_ptr<const TemplateColumn<std::uint32_t>> DataFrame::getIndexColumn() const {
    return std::dynamic_pointer_cast<const TemplateColumn<std::uint32_t>>(columns_[0]);
}

std::shared_ptr<TemplateColumn<std::uint32_t>> DataFrame::getIndexColumn() {
    return std::dynamic_pointer_cast<TemplateColumn<std::uint32_t>>(columns_[0]);
}

std::vector<std::shared_ptr<Column>>::iterator DataFrame::begin() { return columns_.begin(); }

std::vector<std::shared_ptr<Column>>::const_iterator DataFrame::begin() const {
    return columns_.begin();
}

std::vector<std::shared_ptr<Column>>::iterator DataFrame::end() { return columns_.end(); }

std::shared_ptr<DataFrame> createDataFrame(const std::vector<std::vector<std::string>>& exampleRows,
                                           const std::vector<std::string>& colHeaders) {

    if (exampleRows.empty()) {
        throw InvalidColCount("No example data to derive columns from",
                              IVW_CONTEXT_CUSTOM("DataFrame::createDataFrame"));
    }

    // Guess type of each column, ordinal or nominal
    std::vector<std::pair<unsigned int, unsigned int>> columnTypeStatistics(colHeaders.size(),
                                                                            std::make_pair(0, 0));
    for (size_t i = 0; i < exampleRows.size(); ++i) {
        const auto& rowData = exampleRows[i];
        if (rowData.size() != colHeaders.size()) {
            std::ostringstream oss;
            oss << "Number of headers does not match column count, number of headers: "
                << colHeaders.size() << ", number of columns: " << rowData.size();
            throw InvalidColCount(oss.str(), IVW_CONTEXT_CUSTOM("DataFrame::createDataFrame"));
        }
        for (auto column = 0u; column < rowData.size(); ++column) {
            std::istringstream iss(trim(rowData[column]));
            float d;
            // try extracting floating point number. If the stream is not at its end, then there was
            // trailing data. Hence this value does not represent a floating point number.
            if ((iss >> d) && iss.eof()) {
                // ordinal buffer
                columnTypeStatistics[column].first++;
            } else {  // nominal buffer
                columnTypeStatistics[column].second++;
            }
        }
    }

    auto dataFrame = std::make_shared<DataFrame>(0u);
    for (size_t column = 0; column < exampleRows.front().size(); ++column) {
        const auto header =
            (!colHeaders.empty() ? colHeaders[column]
                                 : std::string("Column ") + std::to_string(column + 1));
        if (columnTypeStatistics[column].first > columnTypeStatistics[column].second) {
            // ordinal buffer
            dataFrame->addColumn<float>(header, 0u);
        } else {  // nominal buffer
            dataFrame->addCategoricalColumn(header, 0);
        }
    }
    return dataFrame;
}

}  // namespace inviwo
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/desktop_capture_options.h"

namespace webrtc {

DesktopCaptureOptions::DesktopCaptureOptions()
    : use_update_notifications_(true),
      disable_effects_(true) {
#if defined(USE_X11)
  // XDamage is often broken, so don't use it by default.
  use_update_notifications_ = false;
#endif

#if defined(WEBRTC_WIN)
  allow_use_magnification_api_ = false;
#endif
}

DesktopCaptureOptions::~DesktopCaptureOptions() {}

// static
DesktopCaptureOptions DesktopCaptureOptions::CreateDefault() {
  DesktopCaptureOptions result;
#if defined(USE_X11)
  result.set_x_display(SharedXDisplay::CreateDefault());
#endif
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
  result.set_configuration_monitor(new DesktopConfigurationMonitor());
#endif
  return result;
}

}  // namespace webrtc
<commit_msg>Create FullScreenChromeWindowDetector in DesktopConfigurationOptions::CreateDefault.<commit_after>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/desktop_capture_options.h"

namespace webrtc {

DesktopCaptureOptions::DesktopCaptureOptions()
    : use_update_notifications_(true),
      disable_effects_(true) {
#if defined(USE_X11)
  // XDamage is often broken, so don't use it by default.
  use_update_notifications_ = false;
#endif

#if defined(WEBRTC_WIN)
  allow_use_magnification_api_ = false;
#endif
}

DesktopCaptureOptions::~DesktopCaptureOptions() {}

// static
DesktopCaptureOptions DesktopCaptureOptions::CreateDefault() {
  DesktopCaptureOptions result;
#if defined(USE_X11)
  result.set_x_display(SharedXDisplay::CreateDefault());
#endif
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
  result.set_configuration_monitor(new DesktopConfigurationMonitor());
  result.set_full_screen_chrome_window_detector(
      new FullScreenChromeWindowDetector());
#endif
  return result;
}

}  // namespace webrtc
<|endoftext|>


<commit_before>//===-- SIFixSGPRCopies.cpp - Remove potential VGPR => SGPR copies --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Copies from VGPR to SGPR registers are illegal and the register coalescer
/// will sometimes generate these illegal copies in situations like this:
///
///  Register Class <vsrc> is the union of <vgpr> and <sgpr>
///
/// BB0:
///   %vreg0 <sgpr> = SCALAR_INST
///   %vreg1 <vsrc> = COPY %vreg0 <sgpr>
///    ...
///    BRANCH %cond BB1, BB2
///  BB1:
///    %vreg2 <vgpr> = VECTOR_INST
///    %vreg3 <vsrc> = COPY %vreg2 <vgpr>
///  BB2:
///    %vreg4 <vsrc> = PHI %vreg1 <vsrc>, <BB#0>, %vreg3 <vrsc>, <BB#1>
///    %vreg5 <vgpr> = VECTOR_INST %vreg4 <vsrc>
///
///
/// The coalescer will begin at BB0 and eliminate its copy, then the resulting
/// code will look like this:
///
/// BB0:
///   %vreg0 <sgpr> = SCALAR_INST
///    ...
///    BRANCH %cond BB1, BB2
/// BB1:
///   %vreg2 <vgpr> = VECTOR_INST
///   %vreg3 <vsrc> = COPY %vreg2 <vgpr>
/// BB2:
///   %vreg4 <sgpr> = PHI %vreg0 <sgpr>, <BB#0>, %vreg3 <vsrc>, <BB#1>
///   %vreg5 <vgpr> = VECTOR_INST %vreg4 <sgpr>
///
/// Now that the result of the PHI instruction is an SGPR, the register
/// allocator is now forced to constrain the register class of %vreg3 to
/// <sgpr> so we end up with final code like this:
///
/// BB0:
///   %vreg0 <sgpr> = SCALAR_INST
///    ...
///    BRANCH %cond BB1, BB2
/// BB1:
///   %vreg2 <vgpr> = VECTOR_INST
///   %vreg3 <sgpr> = COPY %vreg2 <vgpr>
/// BB2:
///   %vreg4 <sgpr> = PHI %vreg0 <sgpr>, <BB#0>, %vreg3 <sgpr>, <BB#1>
///   %vreg5 <vgpr> = VECTOR_INST %vreg4 <sgpr>
///
/// Now this code contains an illegal copy from a VGPR to an SGPR.
///
/// In order to avoid this problem, this pass searches for PHI instructions
/// which define a <vsrc> register and constrains its definition class to
/// <vgpr> if the user of the PHI's definition register is a vector instruction.
/// If the PHI's definition class is constrained to <vgpr> then the coalescer
/// will be unable to perform the COPY removal from the above example  which
/// ultimately led to the creation of an illegal COPY.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sgpr-copies"
#include "AMDGPU.h"
#include "SIInstrInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

namespace {

class SIFixSGPRCopies : public MachineFunctionPass {

private:
  static char ID;
  const TargetRegisterClass *inferRegClassFromUses(const SIRegisterInfo *TRI,
                                           const MachineRegisterInfo &MRI,
                                           unsigned Reg,
                                           unsigned SubReg) const;
  const TargetRegisterClass *inferRegClassFromDef(const SIRegisterInfo *TRI,
                                                 const MachineRegisterInfo &MRI,
                                                 unsigned Reg,
                                                 unsigned SubReg) const;
  bool isVGPRToSGPRCopy(const MachineInstr &Copy, const SIRegisterInfo *TRI,
                        const MachineRegisterInfo &MRI) const;

public:
  SIFixSGPRCopies(TargetMachine &tm) : MachineFunctionPass(ID) { }

  virtual bool runOnMachineFunction(MachineFunction &MF);

  const char *getPassName() const {
    return "SI Fix SGPR copies";
  }

};

} // End anonymous namespace

char SIFixSGPRCopies::ID = 0;

FunctionPass *llvm::createSIFixSGPRCopiesPass(TargetMachine &tm) {
  return new SIFixSGPRCopies(tm);
}

static bool hasVGPROperands(const MachineInstr &MI, const SIRegisterInfo *TRI) {
  const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    if (!MI.getOperand(i).isReg() ||
        !TargetRegisterInfo::isVirtualRegister(MI.getOperand(i).getReg()))
      continue;

    if (TRI->hasVGPRs(MRI.getRegClass(MI.getOperand(i).getReg())))
      return true;
  }
  return false;
}

/// This functions walks the use list of Reg until it finds an Instruction
/// that isn't a COPY returns the register class of that instruction.
/// \param[out] The register defined by the first non-COPY instruction.
const TargetRegisterClass *SIFixSGPRCopies::inferRegClassFromUses(
                                                 const SIRegisterInfo *TRI,
                                                 const MachineRegisterInfo &MRI,
                                                 unsigned Reg,
                                                 unsigned SubReg) const {
  // The Reg parameter to the function must always be defined by either a PHI
  // or a COPY, therefore it cannot be a physical register.
  assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
         "Reg cannot be a physical register");

  const TargetRegisterClass *RC = MRI.getRegClass(Reg);
  RC = TRI->getSubRegClass(RC, SubReg);
  for (MachineRegisterInfo::use_iterator I = MRI.use_begin(Reg),
                                         E = MRI.use_end(); I != E; ++I) {
    switch (I->getOpcode()) {
    case AMDGPU::COPY:
      RC = TRI->getCommonSubClass(RC, inferRegClassFromUses(TRI, MRI,
                                  I->getOperand(0).getReg(),
                                  I->getOperand(0).getSubReg()));
      break;
    }
  }

  return RC;
}

const TargetRegisterClass *SIFixSGPRCopies::inferRegClassFromDef(
                                                 const SIRegisterInfo *TRI,
                                                 const MachineRegisterInfo &MRI,
                                                 unsigned Reg,
                                                 unsigned SubReg) const {
  if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
    const TargetRegisterClass *RC = TRI->getPhysRegClass(Reg);
    return TRI->getSubRegClass(RC, SubReg);
  }
  MachineInstr *Def = MRI.getVRegDef(Reg);
  if (Def->getOpcode() != AMDGPU::COPY) {
    return TRI->getSubRegClass(MRI.getRegClass(Reg), SubReg);
  }

  return inferRegClassFromDef(TRI, MRI, Def->getOperand(1).getReg(),
                                   Def->getOperand(1).getSubReg());
}

bool SIFixSGPRCopies::isVGPRToSGPRCopy(const MachineInstr &Copy,
                                      const SIRegisterInfo *TRI,
                                      const MachineRegisterInfo &MRI) const {

  unsigned DstReg = Copy.getOperand(0).getReg();
  unsigned SrcReg = Copy.getOperand(1).getReg();
  unsigned SrcSubReg = Copy.getOperand(1).getSubReg();
  const TargetRegisterClass *DstRC = MRI.getRegClass(DstReg);

  if (!TargetRegisterInfo::isVirtualRegister(SrcReg) ||
      DstRC == &AMDGPU::M0RegRegClass)
    return false;

  const TargetRegisterClass *SrcRC = TRI->getSubRegClass(
      MRI.getRegClass(SrcReg), SrcSubReg);

  return TRI->isSGPRClass(DstRC) &&
         !TRI->getCommonSubClass(DstRC, SrcRC);
}

bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
  MachineRegisterInfo &MRI = MF.getRegInfo();
  const SIRegisterInfo *TRI = static_cast<const SIRegisterInfo *>(
      MF.getTarget().getRegisterInfo());
  const SIInstrInfo *TII = static_cast<const SIInstrInfo *>(
      MF.getTarget().getInstrInfo());
  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
                                                  BI != BE; ++BI) {

    MachineBasicBlock &MBB = *BI;
    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
                                                      I != E; ++I) {
      MachineInstr &MI = *I;
      if (MI.getOpcode() == AMDGPU::COPY && isVGPRToSGPRCopy(MI, TRI, MRI)) {
        DEBUG(dbgs() << "Fixing VGPR -> SGPR copy:\n");
        DEBUG(MI.print(dbgs()));
        TII->moveToVALU(MI);

      }

      switch (MI.getOpcode()) {
      default: continue;
      case AMDGPU::PHI: {
        DEBUG(dbgs() << " Fixing PHI:\n");
        DEBUG(MI.print(dbgs()));

        for (unsigned i = 1; i < MI.getNumOperands(); i+=2) {
          unsigned Reg = MI.getOperand(i).getReg();
          const TargetRegisterClass *RC = inferRegClassFromDef(TRI, MRI, Reg,
                                                  MI.getOperand(0).getSubReg());
          MRI.constrainRegClass(Reg, RC);
        }
        unsigned Reg = MI.getOperand(0).getReg();
        const TargetRegisterClass *RC = inferRegClassFromUses(TRI, MRI, Reg,
                                                  MI.getOperand(0).getSubReg());
        if (TRI->getCommonSubClass(RC, &AMDGPU::VReg_32RegClass)) {
          MRI.constrainRegClass(Reg, &AMDGPU::VReg_32RegClass);
        }

        if (!TRI->isSGPRClass(MRI.getRegClass(Reg)))
          break;

        // If a PHI node defines an SGPR and any of its operands are VGPRs,
        // then we need to move it to the VALU.
        for (unsigned i = 1; i < MI.getNumOperands(); i+=2) {
          unsigned Reg = MI.getOperand(i).getReg();
          if (TRI->hasVGPRs(MRI.getRegClass(Reg))) {
            TII->moveToVALU(MI);
            break;
          }
        }

        break;
      }
      case AMDGPU::REG_SEQUENCE: {
        if (TRI->hasVGPRs(TII->getOpRegClass(MI, 0)) ||
            !hasVGPROperands(MI, TRI))
          continue;

        DEBUG(dbgs() << "Fixing REG_SEQUENCE: \n");
        DEBUG(MI.print(dbgs()));

        TII->moveToVALU(MI);
        TII->legalizeOperands(&MI);
        break;
      }
      }
    }
  }
  return false;
}
<commit_msg>R600/SIFixSGPRCopies.cpp: Fix \param to \return. [-Wdocumentation]<commit_after>//===-- SIFixSGPRCopies.cpp - Remove potential VGPR => SGPR copies --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Copies from VGPR to SGPR registers are illegal and the register coalescer
/// will sometimes generate these illegal copies in situations like this:
///
///  Register Class <vsrc> is the union of <vgpr> and <sgpr>
///
/// BB0:
///   %vreg0 <sgpr> = SCALAR_INST
///   %vreg1 <vsrc> = COPY %vreg0 <sgpr>
///    ...
///    BRANCH %cond BB1, BB2
///  BB1:
///    %vreg2 <vgpr> = VECTOR_INST
///    %vreg3 <vsrc> = COPY %vreg2 <vgpr>
///  BB2:
///    %vreg4 <vsrc> = PHI %vreg1 <vsrc>, <BB#0>, %vreg3 <vrsc>, <BB#1>
///    %vreg5 <vgpr> = VECTOR_INST %vreg4 <vsrc>
///
///
/// The coalescer will begin at BB0 and eliminate its copy, then the resulting
/// code will look like this:
///
/// BB0:
///   %vreg0 <sgpr> = SCALAR_INST
///    ...
///    BRANCH %cond BB1, BB2
/// BB1:
///   %vreg2 <vgpr> = VECTOR_INST
///   %vreg3 <vsrc> = COPY %vreg2 <vgpr>
/// BB2:
///   %vreg4 <sgpr> = PHI %vreg0 <sgpr>, <BB#0>, %vreg3 <vsrc>, <BB#1>
///   %vreg5 <vgpr> = VECTOR_INST %vreg4 <sgpr>
///
/// Now that the result of the PHI instruction is an SGPR, the register
/// allocator is now forced to constrain the register class of %vreg3 to
/// <sgpr> so we end up with final code like this:
///
/// BB0:
///   %vreg0 <sgpr> = SCALAR_INST
///    ...
///    BRANCH %cond BB1, BB2
/// BB1:
///   %vreg2 <vgpr> = VECTOR_INST
///   %vreg3 <sgpr> = COPY %vreg2 <vgpr>
/// BB2:
///   %vreg4 <sgpr> = PHI %vreg0 <sgpr>, <BB#0>, %vreg3 <sgpr>, <BB#1>
///   %vreg5 <vgpr> = VECTOR_INST %vreg4 <sgpr>
///
/// Now this code contains an illegal copy from a VGPR to an SGPR.
///
/// In order to avoid this problem, this pass searches for PHI instructions
/// which define a <vsrc> register and constrains its definition class to
/// <vgpr> if the user of the PHI's definition register is a vector instruction.
/// If the PHI's definition class is constrained to <vgpr> then the coalescer
/// will be unable to perform the COPY removal from the above example  which
/// ultimately led to the creation of an illegal COPY.
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sgpr-copies"
#include "AMDGPU.h"
#include "SIInstrInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

namespace {

class SIFixSGPRCopies : public MachineFunctionPass {

private:
  static char ID;
  const TargetRegisterClass *inferRegClassFromUses(const SIRegisterInfo *TRI,
                                           const MachineRegisterInfo &MRI,
                                           unsigned Reg,
                                           unsigned SubReg) const;
  const TargetRegisterClass *inferRegClassFromDef(const SIRegisterInfo *TRI,
                                                 const MachineRegisterInfo &MRI,
                                                 unsigned Reg,
                                                 unsigned SubReg) const;
  bool isVGPRToSGPRCopy(const MachineInstr &Copy, const SIRegisterInfo *TRI,
                        const MachineRegisterInfo &MRI) const;

public:
  SIFixSGPRCopies(TargetMachine &tm) : MachineFunctionPass(ID) { }

  virtual bool runOnMachineFunction(MachineFunction &MF);

  const char *getPassName() const {
    return "SI Fix SGPR copies";
  }

};

} // End anonymous namespace

char SIFixSGPRCopies::ID = 0;

FunctionPass *llvm::createSIFixSGPRCopiesPass(TargetMachine &tm) {
  return new SIFixSGPRCopies(tm);
}

static bool hasVGPROperands(const MachineInstr &MI, const SIRegisterInfo *TRI) {
  const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
  for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
    if (!MI.getOperand(i).isReg() ||
        !TargetRegisterInfo::isVirtualRegister(MI.getOperand(i).getReg()))
      continue;

    if (TRI->hasVGPRs(MRI.getRegClass(MI.getOperand(i).getReg())))
      return true;
  }
  return false;
}

/// This functions walks the use list of Reg until it finds an Instruction
/// that isn't a COPY returns the register class of that instruction.
/// \return The register defined by the first non-COPY instruction.
const TargetRegisterClass *SIFixSGPRCopies::inferRegClassFromUses(
                                                 const SIRegisterInfo *TRI,
                                                 const MachineRegisterInfo &MRI,
                                                 unsigned Reg,
                                                 unsigned SubReg) const {
  // The Reg parameter to the function must always be defined by either a PHI
  // or a COPY, therefore it cannot be a physical register.
  assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
         "Reg cannot be a physical register");

  const TargetRegisterClass *RC = MRI.getRegClass(Reg);
  RC = TRI->getSubRegClass(RC, SubReg);
  for (MachineRegisterInfo::use_iterator I = MRI.use_begin(Reg),
                                         E = MRI.use_end(); I != E; ++I) {
    switch (I->getOpcode()) {
    case AMDGPU::COPY:
      RC = TRI->getCommonSubClass(RC, inferRegClassFromUses(TRI, MRI,
                                  I->getOperand(0).getReg(),
                                  I->getOperand(0).getSubReg()));
      break;
    }
  }

  return RC;
}

const TargetRegisterClass *SIFixSGPRCopies::inferRegClassFromDef(
                                                 const SIRegisterInfo *TRI,
                                                 const MachineRegisterInfo &MRI,
                                                 unsigned Reg,
                                                 unsigned SubReg) const {
  if (!TargetRegisterInfo::isVirtualRegister(Reg)) {
    const TargetRegisterClass *RC = TRI->getPhysRegClass(Reg);
    return TRI->getSubRegClass(RC, SubReg);
  }
  MachineInstr *Def = MRI.getVRegDef(Reg);
  if (Def->getOpcode() != AMDGPU::COPY) {
    return TRI->getSubRegClass(MRI.getRegClass(Reg), SubReg);
  }

  return inferRegClassFromDef(TRI, MRI, Def->getOperand(1).getReg(),
                                   Def->getOperand(1).getSubReg());
}

bool SIFixSGPRCopies::isVGPRToSGPRCopy(const MachineInstr &Copy,
                                      const SIRegisterInfo *TRI,
                                      const MachineRegisterInfo &MRI) const {

  unsigned DstReg = Copy.getOperand(0).getReg();
  unsigned SrcReg = Copy.getOperand(1).getReg();
  unsigned SrcSubReg = Copy.getOperand(1).getSubReg();
  const TargetRegisterClass *DstRC = MRI.getRegClass(DstReg);

  if (!TargetRegisterInfo::isVirtualRegister(SrcReg) ||
      DstRC == &AMDGPU::M0RegRegClass)
    return false;

  const TargetRegisterClass *SrcRC = TRI->getSubRegClass(
      MRI.getRegClass(SrcReg), SrcSubReg);

  return TRI->isSGPRClass(DstRC) &&
         !TRI->getCommonSubClass(DstRC, SrcRC);
}

bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
  MachineRegisterInfo &MRI = MF.getRegInfo();
  const SIRegisterInfo *TRI = static_cast<const SIRegisterInfo *>(
      MF.getTarget().getRegisterInfo());
  const SIInstrInfo *TII = static_cast<const SIInstrInfo *>(
      MF.getTarget().getInstrInfo());
  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
                                                  BI != BE; ++BI) {

    MachineBasicBlock &MBB = *BI;
    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
                                                      I != E; ++I) {
      MachineInstr &MI = *I;
      if (MI.getOpcode() == AMDGPU::COPY && isVGPRToSGPRCopy(MI, TRI, MRI)) {
        DEBUG(dbgs() << "Fixing VGPR -> SGPR copy:\n");
        DEBUG(MI.print(dbgs()));
        TII->moveToVALU(MI);

      }

      switch (MI.getOpcode()) {
      default: continue;
      case AMDGPU::PHI: {
        DEBUG(dbgs() << " Fixing PHI:\n");
        DEBUG(MI.print(dbgs()));

        for (unsigned i = 1; i < MI.getNumOperands(); i+=2) {
          unsigned Reg = MI.getOperand(i).getReg();
          const TargetRegisterClass *RC = inferRegClassFromDef(TRI, MRI, Reg,
                                                  MI.getOperand(0).getSubReg());
          MRI.constrainRegClass(Reg, RC);
        }
        unsigned Reg = MI.getOperand(0).getReg();
        const TargetRegisterClass *RC = inferRegClassFromUses(TRI, MRI, Reg,
                                                  MI.getOperand(0).getSubReg());
        if (TRI->getCommonSubClass(RC, &AMDGPU::VReg_32RegClass)) {
          MRI.constrainRegClass(Reg, &AMDGPU::VReg_32RegClass);
        }

        if (!TRI->isSGPRClass(MRI.getRegClass(Reg)))
          break;

        // If a PHI node defines an SGPR and any of its operands are VGPRs,
        // then we need to move it to the VALU.
        for (unsigned i = 1; i < MI.getNumOperands(); i+=2) {
          unsigned Reg = MI.getOperand(i).getReg();
          if (TRI->hasVGPRs(MRI.getRegClass(Reg))) {
            TII->moveToVALU(MI);
            break;
          }
        }

        break;
      }
      case AMDGPU::REG_SEQUENCE: {
        if (TRI->hasVGPRs(TII->getOpRegClass(MI, 0)) ||
            !hasVGPROperands(MI, TRI))
          continue;

        DEBUG(dbgs() << "Fixing REG_SEQUENCE: \n");
        DEBUG(MI.print(dbgs()));

        TII->moveToVALU(MI);
        TII->legalizeOperands(&MI);
        break;
      }
      }
    }
  }
  return false;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MCatalog.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 02:55:08 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#ifndef _CONNECTIVITY_MOZAB_CATALOG_HXX_
#include "MCatalog.hxx"
#endif
#ifndef _CONNECTIVITY_MOZAB_BCONNECTION_HXX_
#include "MConnection.hxx"
#endif
#ifndef _CONNECTIVITY_MOZAB_TABLES_HXX_
#include "MTables.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif

// -------------------------------------------------------------------------
using namespace connectivity::mozab;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::cppu;

// -------------------------------------------------------------------------
OCatalog::OCatalog(OConnection* _pCon) : connectivity::sdbcx::OCatalog(_pCon)
                ,m_pConnection(_pCon)
                ,m_xMetaData(m_pConnection->getMetaData(  ))
{
//  osl_incrementInterlockedCount( &m_refCount );
//  refreshTables();
//  refreshViews();
//  refreshGroups();
//  refreshUsers();
//  osl_decrementInterlockedCount( &m_refCount );
}
// -------------------------------------------------------------------------
void OCatalog::refreshTables()
{
    TStringVector aVector;
    Sequence< ::rtl::OUString > aTypes(1);
    aTypes[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("%"));
    Reference< XResultSet > xResult = m_xMetaData->getTables(Any(),
        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("%")),::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("%")),aTypes);

    if(xResult.is())
    {
        Reference< XRow > xRow(xResult,UNO_QUERY);
        ::rtl::OUString aName;
        while(xResult->next())
        {
            aName = xRow->getString(3);
            aVector.push_back(aName);
        }
    }
    if(m_pTables)
        m_pTables->reFill(aVector);
    else
        m_pTables = new OTables(m_xMetaData,*this,m_aMutex,aVector);
}
// -------------------------------------------------------------------------
void OCatalog::refreshViews()
{
}
// -------------------------------------------------------------------------
void OCatalog::refreshGroups()
{
}
// -------------------------------------------------------------------------
void OCatalog::refreshUsers()
{
}
// -------------------------------------------------------------------------
const ::rtl::OUString& OCatalog::getDot()
{
    static const ::rtl::OUString sDot = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("."));
    return sDot;
}
// -----------------------------------------------------------------------------

// XTablesSupplier
Reference< XNameAccess > SAL_CALL OCatalog::getTables(  ) throw(RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(rBHelper.bDisposed);

    try
    {
        if(!m_pTables || m_pConnection->getForceLoadTables())
            refreshTables();
    }
    catch( const RuntimeException& )
    {
        // allowed to leave this method
        throw;
    }
    catch( const Exception& )
    {
        // allowed
    }

    return const_cast<OCatalog*>(this)->m_pTables;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.5.216); FILE MERGED 2008/04/01 15:08:56 thb 1.5.216.3: #i85898# Stripping all external header guards 2008/04/01 10:53:10 thb 1.5.216.2: #i85898# Stripping all external header guards 2008/03/28 15:23:50 rt 1.5.216.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: MCatalog.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#include "MCatalog.hxx"
#ifndef _CONNECTIVITY_MOZAB_BCONNECTION_HXX_
#include "MConnection.hxx"
#endif
#include "MTables.hxx"
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/sdbc/XResultSet.hpp>
#include <cppuhelper/interfacecontainer.h>

// -------------------------------------------------------------------------
using namespace connectivity::mozab;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::cppu;

// -------------------------------------------------------------------------
OCatalog::OCatalog(OConnection* _pCon) : connectivity::sdbcx::OCatalog(_pCon)
                ,m_pConnection(_pCon)
                ,m_xMetaData(m_pConnection->getMetaData(  ))
{
//  osl_incrementInterlockedCount( &m_refCount );
//  refreshTables();
//  refreshViews();
//  refreshGroups();
//  refreshUsers();
//  osl_decrementInterlockedCount( &m_refCount );
}
// -------------------------------------------------------------------------
void OCatalog::refreshTables()
{
    TStringVector aVector;
    Sequence< ::rtl::OUString > aTypes(1);
    aTypes[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("%"));
    Reference< XResultSet > xResult = m_xMetaData->getTables(Any(),
        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("%")),::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("%")),aTypes);

    if(xResult.is())
    {
        Reference< XRow > xRow(xResult,UNO_QUERY);
        ::rtl::OUString aName;
        while(xResult->next())
        {
            aName = xRow->getString(3);
            aVector.push_back(aName);
        }
    }
    if(m_pTables)
        m_pTables->reFill(aVector);
    else
        m_pTables = new OTables(m_xMetaData,*this,m_aMutex,aVector);
}
// -------------------------------------------------------------------------
void OCatalog::refreshViews()
{
}
// -------------------------------------------------------------------------
void OCatalog::refreshGroups()
{
}
// -------------------------------------------------------------------------
void OCatalog::refreshUsers()
{
}
// -------------------------------------------------------------------------
const ::rtl::OUString& OCatalog::getDot()
{
    static const ::rtl::OUString sDot = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("."));
    return sDot;
}
// -----------------------------------------------------------------------------

// XTablesSupplier
Reference< XNameAccess > SAL_CALL OCatalog::getTables(  ) throw(RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(rBHelper.bDisposed);

    try
    {
        if(!m_pTables || m_pConnection->getForceLoadTables())
            refreshTables();
    }
    catch( const RuntimeException& )
    {
        // allowed to leave this method
        throw;
    }
    catch( const Exception& )
    {
        // allowed
    }

    return const_cast<OCatalog*>(this)->m_pTables;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: MCatalog.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 06:15:33 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_MOZAB_CATALOG_HXX_
#define _CONNECTIVITY_MOZAB_CATALOG_HXX_

#ifndef _CONNECTIVITY_SDBCX_CATALOG_HXX_
#include "connectivity/sdbcx/VCatalog.hxx"
#endif
// #ifndef _CONNECTIVITY_OFUNCTIONDEFS_HXX_
// #include "odbc/OFunctiondefs.hxx"
// #endif

namespace connectivity
{
    namespace mozab
    {
        // please don't name the class the same name as in an other namespaces
        // some compilers have problems with this task as I noticed on windows
        class OConnection;
        class OCatalog : public connectivity::sdbcx::OCatalog
        {
            OConnection*    m_pConnection;      // used to get the metadata
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData; // just to make things easier

        public:
            // implementation of the pure virtual methods
            virtual void refreshTables();
            virtual void refreshViews() ;
            virtual void refreshGroups();
            virtual void refreshUsers() ;
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTables(  ) throw(::com::sun::star::uno::RuntimeException);
        public:
            OCatalog(OConnection* _pCon);

            OConnection*            getConnection()     const { return m_pConnection; }
            sdbcx::OCollection*     getPrivateTables()  const { return m_pTables;}
            sdbcx::OCollection*     getPrivateViews()   const { return m_pViews; }

            static const ::rtl::OUString& getDot();
        };
    }
}
#endif // _CONNECTIVITY_MOZAB_CATALOG_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.3.372); FILE MERGED 2008/04/01 10:53:10 thb 1.3.372.2: #i85898# Stripping all external header guards 2008/03/28 15:23:50 rt 1.3.372.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: MCatalog.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_MOZAB_CATALOG_HXX_
#define _CONNECTIVITY_MOZAB_CATALOG_HXX_

#include "connectivity/sdbcx/VCatalog.hxx"
// #ifndef _CONNECTIVITY_OFUNCTIONDEFS_HXX_
// #include "odbc/OFunctiondefs.hxx"
// #endif

namespace connectivity
{
    namespace mozab
    {
        // please don't name the class the same name as in an other namespaces
        // some compilers have problems with this task as I noticed on windows
        class OConnection;
        class OCatalog : public connectivity::sdbcx::OCatalog
        {
            OConnection*    m_pConnection;      // used to get the metadata
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData; // just to make things easier

        public:
            // implementation of the pure virtual methods
            virtual void refreshTables();
            virtual void refreshViews() ;
            virtual void refreshGroups();
            virtual void refreshUsers() ;
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getTables(  ) throw(::com::sun::star::uno::RuntimeException);
        public:
            OCatalog(OConnection* _pCon);

            OConnection*            getConnection()     const { return m_pConnection; }
            sdbcx::OCollection*     getPrivateTables()  const { return m_pTables;}
            sdbcx::OCollection*     getPrivateViews()   const { return m_pViews; }

            static const ::rtl::OUString& getDot();
        };
    }
}
#endif // _CONNECTIVITY_MOZAB_CATALOG_HXX_

<|endoftext|>