<commit_before>#include <fcntl.h>

#include <netinet/in.h>
#include <sys/socket.h>

#include "server.h"
#include "net/length.h"

#include "xapian.h"

const int MSECS_IDLE_TIMEOUT_DEFAULT = 60000;
const int MSECS_ACTIVE_TIMEOUT_DEFAULT = 15000;

void print_string(const std::string &string) {
	const char *p = string.c_str();
	const char *p_end = p + string.size();
	printf("'");
	while (p != p_end) {
		if (*p >= ' ' && *p <= '~') {
			printf("%c", *p++);
		} else {
			printf("\\x%02x", *p++ & 0xff);
		}
	}
	printf("'\n");
}

class XapianWorker : public Task {
private:
	XapiandClient *client;

public:
	XapianWorker(XapiandClient *client_) : Task(), client(client_) {}

	~XapianWorker() {}

	virtual void run() {
		client->run();
	}
};

//
//   Buffer class - allow for output buffering such that it can be written out
//                                 into async pieces
//
struct Buffer {
	char type;
	char *data;
	ssize_t len;
	ssize_t pos;

	Buffer(char type_, const char *bytes, ssize_t nbytes) {
		pos = 0;
		len = nbytes;
		type = type_;
		data = new char[nbytes];
		memcpy(data, bytes, nbytes);
	}

	virtual ~Buffer() {
		delete [] data;
	}

	char *dpos() {
		return data + pos;
	}

	ssize_t nbytes() {
		return len - pos;
	}
};

void XapiandClient::callback(ev::io &watcher, int revents)
{
	if (EV_ERROR & revents) {
		perror("got invalid event");
		return;
	}

	if (revents & EV_READ)
		read_cb(watcher);

	if (revents & EV_WRITE)
		write_cb(watcher);

	pthread_mutex_lock(&qmtx);
	if (write_queue.empty()) {
		io.set(ev::READ);
	} else {
		io.set(ev::READ|ev::WRITE);
	}
	pthread_mutex_unlock(&qmtx);
}

void XapiandClient::async_cb(ev::async &watcher, int revents)
{
	pthread_mutex_lock(&qmtx);
	if (!write_queue.empty()) {
		io.set(ev::READ|ev::WRITE);
	}
	pthread_mutex_unlock(&qmtx);
}

void XapiandClient::write_cb(ev::io &watcher)
{
	pthread_mutex_lock(&qmtx);

	if (write_queue.empty()) {
		io.set(ev::READ);
	} else {
		Buffer* buffer = write_queue.front();

		// printf("sent:");
		// print_string(std::string(buffer->dpos(), buffer->nbytes()));

		ssize_t written = write(watcher.fd, buffer->dpos(), buffer->nbytes());
		if (written < 0) {
			perror("read error");
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				write_queue.pop_front();
				delete buffer;
			}
		}
	}

	pthread_mutex_unlock(&qmtx);
}

void XapiandClient::read_cb(ev::io &watcher)
{
	char buf[1024];

	ssize_t received = recv(watcher.fd, buf, sizeof(buf), 0);

	if (received < 0) {
		perror("read error");
		return;
	}

	if (received == 0) {
		// Gack - we're deleting ourself inside of ourself!
		delete this;
	} else {
		buffer.append(buf, received);
		if (buffer.length() >= 2) {
			const char *o = buffer.data();
			const char *p = o;
			const char *p_end = p + buffer.size();

			message_type required_type = static_cast<message_type>(*p++);
			size_t len;
			try {
				len = decode_length(&p, p_end, true);
			} catch (const Xapian::NetworkError & e) {
				return;
			}
			std::string data = std::string(p, len);
			buffer.erase(0, p - o + len);

			// printf("received:");
			// print_string(data);

			Buffer *msg = new Buffer(required_type, data.c_str(), data.size());

			messages_queue.push(msg);

			if (required_type == MSG_QUERY) {
				thread_pool->addTask(new XapianWorker(this));
			}

		}
	}
}

void XapiandClient::signal_cb(ev::sig &signal, int revents)
{
	delete this;
}

message_type XapiandClient::get_message(double timeout, std::string & result, message_type required_type)
{
	Buffer* msg;
	if (!messages_queue.pop(msg)) {
		throw Xapian::NetworkError("No message available");
	}

	std::string buf(&msg->type, 1);
	buf += encode_length(msg->nbytes());
	buf += std::string(msg->dpos(), msg->nbytes());
	printf("get_message:");
	print_string(buf);

	message_type type = static_cast<message_type>(msg->type);
	result.assign(msg->dpos(), msg->nbytes());

	delete msg;
	return type;
}

void XapiandClient::send_message(reply_type type, const std::string &message) {
	char type_as_char = static_cast<char>(type);
	std::string buf(&type_as_char, 1);
	buf += encode_length(message.size());
	buf += message;

	printf("send_message:");
	print_string(buf);

	pthread_mutex_lock(&qmtx);
	write_queue.push_back(new Buffer(type, buf.c_str(), buf.size()));
	pthread_mutex_unlock(&qmtx);

	async.send();
}

void XapiandClient::send_message(reply_type type, const std::string &message, double end_time)
{
	send_message(type, message);
}

Xapian::Database * XapiandClient::get_db(bool writable_)
{
	if (writable_) {
		return new Xapian::WritableDatabase(dbpaths[0], Xapian::DB_CREATE_OR_OPEN);
	} else {
		return new Xapian::Database(dbpaths[0], Xapian::DB_CREATE_OR_OPEN);
	}
}

void XapiandClient::release_db(Xapian::Database *db_)
{
	delete db_;
}

Xapian::Database * XapiandClient::select_db(const std::vector<std::string> &dbpaths_, bool writable_)
{
	dbpaths = dbpaths_;
	return get_db(writable_);
}

void XapiandClient::run()
{
	try {
		run_one();
	} catch (const Xapian::NetworkError &e) {
		printf("ERROR: %s\n", e.get_msg().c_str());
	} catch (...) {
		printf("ERROR!\n");
	}
}

XapiandClient::XapiandClient(int sock_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: RemoteProtocol(std::vector<std::string>(), active_timeout_, idle_timeout_, true),
	  sock(sock_),
	  thread_pool(thread_pool_)
{
	pthread_mutex_init(&qmtx, 0);

	fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);

	printf("Got connection, %d client(s) connected.\n", ++total_clients);

	io.set<XapiandClient, &XapiandClient::callback>(this);
	io.start(sock, ev::READ);

	sig.set<XapiandClient, &XapiandClient::signal_cb>(this);
	sig.start(SIGINT);

	async.set<XapiandClient, &XapiandClient::async_cb>(this);
	async.start();

	dbpaths.push_back("/Users/kronuz/Development/Dubalu/Xapian/xapian-core-1.3.2/bin/Xapiand/test");

	try {
		msg_update(std::string());
	} catch (const Xapian::NetworkError &e) {
		printf("ERROR: %s\n", e.get_msg().c_str());
	} catch (...) {
		printf("ERROR!\n");
	}
}

XapiandClient::~XapiandClient()
{
	shutdown(sock, SHUT_RDWR);

	// Stop and free watcher if client socket is closing
	io.stop();
	sig.stop();
	async.stop();

	close(sock);

	printf("Lost connection, %d client(s) connected.\n", --total_clients);

	pthread_mutex_destroy(&qmtx);
}

void XapiandServer::io_accept(ev::io &watcher, int revents)
{
	if (EV_ERROR & revents) {
		perror("got invalid event");
		return;
	}

	struct sockaddr_in client_addr;
	socklen_t client_len = sizeof(client_addr);

	int client_sock = accept(watcher.fd, (struct sockaddr *)&client_addr, &client_len);

	if (client_sock < 0) {
		perror("accept error");
		return;
	}

	double active_timeout = MSECS_ACTIVE_TIMEOUT_DEFAULT * 1e-3;
	double idle_timeout = MSECS_IDLE_TIMEOUT_DEFAULT * 1e-3;
	new XapiandClient(client_sock, this->thread_pool, active_timeout, idle_timeout);
}

void XapiandServer::signal_cb(ev::sig &signal, int revents)
{
	signal.loop.break_loop();
}

XapiandServer::XapiandServer(int port, ThreadPool *thread_pool_)
	: thread_pool(thread_pool_)
{
	int optval = 1;
	struct sockaddr_in addr;

	sock = socket(PF_INET, SOCK_STREAM, 0);
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval));

	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = INADDR_ANY;

	if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		perror("bind");
		close(sock);
		sock = 0;
	} else {
		printf("Listening on port %d\n", port);
		fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);

		listen(sock, 5);

		io.set<XapiandServer, &XapiandServer::io_accept>(this);
		io.start(sock, ev::READ);

		sig.set<&XapiandServer::signal_cb>();
		sig.start(SIGINT);
	}
}

XapiandServer::~XapiandServer()
{
	shutdown(sock, SHUT_RDWR);

	io.stop();
	sig.stop();

	close(sock);

	printf("Done with all work!\n");
}

int XapiandClient::total_clients = 0;
<commit_msg>Pass all messages to a worker thread (except for MSG_GETMSET and MSG_SHUTDOWN)<commit_after>#include <fcntl.h>

#include <netinet/in.h>
#include <sys/socket.h>

#include "server.h"
#include "net/length.h"

#include "xapian.h"

const int MSECS_IDLE_TIMEOUT_DEFAULT = 60000;
const int MSECS_ACTIVE_TIMEOUT_DEFAULT = 15000;

void print_string(const std::string &string) {
	const char *p = string.c_str();
	const char *p_end = p + string.size();
	printf("'");
	while (p != p_end) {
		if (*p >= ' ' && *p <= '~') {
			printf("%c", *p++);
		} else {
			printf("\\x%02x", *p++ & 0xff);
		}
	}
	printf("'\n");
}

class XapianWorker : public Task {
private:
	XapiandClient *client;

public:
	XapianWorker(XapiandClient *client_) : Task(), client(client_) {}

	~XapianWorker() {}

	virtual void run() {
		client->run();
	}
};

//
//   Buffer class - allow for output buffering such that it can be written out
//                                 into async pieces
//
struct Buffer {
	char type;
	char *data;
	ssize_t len;
	ssize_t pos;

	Buffer(char type_, const char *bytes, ssize_t nbytes) {
		pos = 0;
		len = nbytes;
		type = type_;
		data = new char[nbytes];
		memcpy(data, bytes, nbytes);
	}

	virtual ~Buffer() {
		delete [] data;
	}

	char *dpos() {
		return data + pos;
	}

	ssize_t nbytes() {
		return len - pos;
	}
};

void XapiandClient::callback(ev::io &watcher, int revents)
{
	if (EV_ERROR & revents) {
		perror("got invalid event");
		return;
	}

	if (revents & EV_READ)
		read_cb(watcher);

	if (revents & EV_WRITE)
		write_cb(watcher);

	pthread_mutex_lock(&qmtx);
	if (write_queue.empty()) {
		io.set(ev::READ);
	} else {
		io.set(ev::READ|ev::WRITE);
	}
	pthread_mutex_unlock(&qmtx);
}

void XapiandClient::async_cb(ev::async &watcher, int revents)
{
	pthread_mutex_lock(&qmtx);
	if (!write_queue.empty()) {
		io.set(ev::READ|ev::WRITE);
	}
	pthread_mutex_unlock(&qmtx);
}

void XapiandClient::write_cb(ev::io &watcher)
{
	pthread_mutex_lock(&qmtx);

	if (write_queue.empty()) {
		io.set(ev::READ);
	} else {
		Buffer* buffer = write_queue.front();

		// printf("sent:");
		// print_string(std::string(buffer->dpos(), buffer->nbytes()));

		ssize_t written = write(watcher.fd, buffer->dpos(), buffer->nbytes());
		if (written < 0) {
			perror("read error");
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				write_queue.pop_front();
				delete buffer;
			}
		}
	}

	pthread_mutex_unlock(&qmtx);
}

void XapiandClient::read_cb(ev::io &watcher)
{
	char buf[1024];

	ssize_t received = recv(watcher.fd, buf, sizeof(buf), 0);

	if (received < 0) {
		perror("read error");
		return;
	}

	if (received == 0) {
		// Gack - we're deleting ourself inside of ourself!
		delete this;
	} else {
		buffer.append(buf, received);
		if (buffer.length() >= 2) {
			const char *o = buffer.data();
			const char *p = o;
			const char *p_end = p + buffer.size();

			message_type type = static_cast<message_type>(*p++);
			size_t len;
			try {
				len = decode_length(&p, p_end, true);
			} catch (const Xapian::NetworkError & e) {
				return;
			}
			std::string data = std::string(p, len);
			buffer.erase(0, p - o + len);

			// printf("received:");
			// print_string(data);

			Buffer *msg = new Buffer(type, data.c_str(), data.size());

			messages_queue.push(msg);

			if (type != MSG_GETMSET && type != MSG_SHUTDOWN) {
				thread_pool->addTask(new XapianWorker(this));
			}

		}
	}
}

void XapiandClient::signal_cb(ev::sig &signal, int revents)
{
	delete this;
}

message_type XapiandClient::get_message(double timeout, std::string & result, message_type required_type)
{
	Buffer* msg;
	if (!messages_queue.pop(msg)) {
		throw Xapian::NetworkError("No message available");
	}

	std::string buf(&msg->type, 1);
	buf += encode_length(msg->nbytes());
	buf += std::string(msg->dpos(), msg->nbytes());
	printf("get_message:");
	print_string(buf);

	message_type type = static_cast<message_type>(msg->type);
	result.assign(msg->dpos(), msg->nbytes());

	delete msg;
	return type;
}

void XapiandClient::send_message(reply_type type, const std::string &message) {
	char type_as_char = static_cast<char>(type);
	std::string buf(&type_as_char, 1);
	buf += encode_length(message.size());
	buf += message;

	printf("send_message:");
	print_string(buf);

	pthread_mutex_lock(&qmtx);
	write_queue.push_back(new Buffer(type, buf.c_str(), buf.size()));
	pthread_mutex_unlock(&qmtx);

	async.send();
}

void XapiandClient::send_message(reply_type type, const std::string &message, double end_time)
{
	send_message(type, message);
}

Xapian::Database * XapiandClient::get_db(bool writable_)
{
	if (writable_) {
		return new Xapian::WritableDatabase(dbpaths[0], Xapian::DB_CREATE_OR_OPEN);
	} else {
		return new Xapian::Database(dbpaths[0], Xapian::DB_CREATE_OR_OPEN);
	}
}

void XapiandClient::release_db(Xapian::Database *db_)
{
	delete db_;
}

Xapian::Database * XapiandClient::select_db(const std::vector<std::string> &dbpaths_, bool writable_)
{
	dbpaths = dbpaths_;
	return get_db(writable_);
}

void XapiandClient::run()
{
	try {
		run_one();
	} catch (const Xapian::NetworkError &e) {
		printf("ERROR: %s\n", e.get_msg().c_str());
	} catch (...) {
		printf("ERROR!\n");
	}
}

XapiandClient::XapiandClient(int sock_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: RemoteProtocol(std::vector<std::string>(), active_timeout_, idle_timeout_, true),
	  sock(sock_),
	  thread_pool(thread_pool_)
{
	pthread_mutex_init(&qmtx, 0);

	fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);

	printf("Got connection, %d client(s) connected.\n", ++total_clients);

	io.set<XapiandClient, &XapiandClient::callback>(this);
	io.start(sock, ev::READ);

	sig.set<XapiandClient, &XapiandClient::signal_cb>(this);
	sig.start(SIGINT);

	async.set<XapiandClient, &XapiandClient::async_cb>(this);
	async.start();

	dbpaths.push_back("/Users/kronuz/Development/Dubalu/Xapian/xapian-core-1.3.2/bin/Xapiand/test");

	try {
		msg_update(std::string());
	} catch (const Xapian::NetworkError &e) {
		printf("ERROR: %s\n", e.get_msg().c_str());
	} catch (...) {
		printf("ERROR!\n");
	}
}

XapiandClient::~XapiandClient()
{
	shutdown(sock, SHUT_RDWR);

	// Stop and free watcher if client socket is closing
	io.stop();
	sig.stop();
	async.stop();

	close(sock);

	printf("Lost connection, %d client(s) connected.\n", --total_clients);

	pthread_mutex_destroy(&qmtx);
}

void XapiandServer::io_accept(ev::io &watcher, int revents)
{
	if (EV_ERROR & revents) {
		perror("got invalid event");
		return;
	}

	struct sockaddr_in client_addr;
	socklen_t client_len = sizeof(client_addr);

	int client_sock = accept(watcher.fd, (struct sockaddr *)&client_addr, &client_len);

	if (client_sock < 0) {
		perror("accept error");
		return;
	}

	double active_timeout = MSECS_ACTIVE_TIMEOUT_DEFAULT * 1e-3;
	double idle_timeout = MSECS_IDLE_TIMEOUT_DEFAULT * 1e-3;
	new XapiandClient(client_sock, this->thread_pool, active_timeout, idle_timeout);
}

void XapiandServer::signal_cb(ev::sig &signal, int revents)
{
	signal.loop.break_loop();
}

XapiandServer::XapiandServer(int port, ThreadPool *thread_pool_)
	: thread_pool(thread_pool_)
{
	int optval = 1;
	struct sockaddr_in addr;

	sock = socket(PF_INET, SOCK_STREAM, 0);
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval));

	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = INADDR_ANY;

	if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		perror("bind");
		close(sock);
		sock = 0;
	} else {
		printf("Listening on port %d\n", port);
		fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);

		listen(sock, 5);

		io.set<XapiandServer, &XapiandServer::io_accept>(this);
		io.start(sock, ev::READ);

		sig.set<&XapiandServer::signal_cb>();
		sig.start(SIGINT);
	}
}

XapiandServer::~XapiandServer()
{
	shutdown(sock, SHUT_RDWR);

	io.stop();
	sig.stop();

	close(sock);

	printf("Done with all work!\n");
}

int XapiandClient::total_clients = 0;
<|endoftext|>


<commit_before>// Copyright 2009, Squish Tech, LLC.

#include "xml_node.h"
#include "xml_document.h"
#include "xml_namespace.h"
#include "xml_element.h"
#include "xml_attribute.h"

namespace libxmljs {

v8::Persistent<v8::FunctionTemplate> XmlNode::constructor_template;

v8::Handle<v8::Value>
XmlNode::Doc(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_doc());
}

v8::Handle<v8::Value>
XmlNode::Namespace(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  // #namespace() Get the node's namespace
  if (args.Length() == 0)
      return scope.Close(node->get_namespace());

  if (args[0]->IsNull())
      return scope.Close(node->remove_namespace());

  XmlNamespace *ns = NULL;

  // #namespace(ns) libxml.Namespace object was provided
  // TODO(sprsquish): check that it was actually given a namespace obj
  if (args[0]->IsObject())
    ns = LibXmlObj::Unwrap<XmlNamespace>(args[0]->ToObject());

  // #namespace(href) or #namespace(prefix, href)
  // if the namespace has already been defined on the node, just set it
  if (args[0]->IsString()) {
    v8::String::Utf8Value ns_to_find(args[0]->ToString());
    xmlNs* found_ns = node->find_namespace(*ns_to_find);
    if (found_ns) {
      ns = LibXmlObj::Unwrap<XmlNamespace>(
             LibXmlObj::GetMaybeBuild<XmlNamespace, xmlNs>(found_ns));
    }
  }

  // Namespace does not seem to exist, so create it.
  if (!ns) {
    int argc = 3;
    v8::Handle<v8::Value> argv[argc];
    argv[0] = args.This();

    if (args.Length() == 1) {
      argv[1] = v8::Null();
      argv[2] = args[0];
    } else {
      argv[1] = args[0];
      argv[2] = args[1];
    }

    v8::Handle<v8::Function> define_namespace =
      XmlNamespace::constructor_template->GetFunction();

    v8::Handle<v8::Value> new_ns = define_namespace->Call(args.This(), argc, argv);
    ns = LibXmlObj::Unwrap<XmlNamespace>(new_ns->ToObject());
  }

  node->set_namespace(ns->xml_obj);

  return scope.Close(node->get_namespace());
}

v8::Handle<v8::Value>
XmlNode::Parent(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_parent());
}

v8::Handle<v8::Value>
XmlNode::PrevSibling(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_prev_sibling());
}

v8::Handle<v8::Value>
XmlNode::NextSibling(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_next_sibling());
}

v8::Handle<v8::Value>
XmlNode::Type(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_type());
}

v8::Handle<v8::Value>
XmlNode::ToString(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->to_string());
}

v8::Handle<v8::Value>
XmlNode::Remove(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  node->remove();

  return scope.Close(args.This());
}

v8::Handle<v8::Value>
XmlNode::Clone(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  bool recurse = true;

  if (args.Length() == 1 && args[0]->IsBoolean())
      recurse = *(args[0]->ToBoolean());

  return scope.Close(node->clone(recurse));
}

XmlNode::XmlNode(xmlNode* node) : xml_obj(node) {
    xml_obj->_private = this;
    if(xml_obj->doc) {
        doc = v8::Persistent<v8::Value>::New(LibXmlObj::GetMaybeBuild<XmlDocument, xmlDoc>(xml_obj->doc));
    }
}

XmlNode::~XmlNode() {
    xml_obj->_private = NULL;
    doc.Dispose();
    doc.Clear();

  // We do not free the xmlNode here. It could still be part of a document
  // It will be freed when the doc is freed
  // xmlFree(xml_obj);
}

v8::Handle<v8::Value>
XmlNode::get_doc() {
  v8::HandleScope scope;
  return scope.Close(LibXmlObj::GetMaybeBuild<XmlDocument, xmlDoc>(xml_obj->doc));
}

v8::Handle<v8::Value>
XmlNode::remove_namespace() {
  xml_obj->ns = NULL;
  return v8::Null();
}

v8::Handle<v8::Value>
XmlNode::get_namespace() {
  v8::HandleScope scope;
  if (!xml_obj->ns)
    return v8::Null();

  return scope.Close(LibXmlObj::GetMaybeBuild<XmlNamespace, xmlNs>(xml_obj->ns));
}

void
XmlNode::set_namespace(xmlNs* ns) {
  xmlSetNs(xml_obj, ns);
}

xmlNs*
XmlNode::find_namespace(const char* search_str) {
  xmlNs* ns = NULL;

  // Find by prefix first
  ns = xmlSearchNs(xml_obj->doc, xml_obj, (const xmlChar*)search_str);

  // Or find by href
  if (!ns)
    ns = xmlSearchNsByHref(xml_obj->doc, xml_obj, (const xmlChar*)search_str);

  return ns;
}

v8::Handle<v8::Value>
XmlNode::get_parent() {
  v8::HandleScope scope;
  if (xml_obj->parent) {
      return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xml_obj->parent));
  }

  return scope.Close(LibXmlObj::GetMaybeBuild<XmlDocument, xmlDoc>(xml_obj->doc));
}

v8::Handle<v8::Value>
XmlNode::get_prev_sibling() {
  v8::HandleScope scope;
  if (xml_obj->prev) {
      return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xml_obj->prev));
  }

  return v8::Null();
}

v8::Handle<v8::Value>
XmlNode::get_next_sibling() {
  v8::HandleScope scope;
  if (xml_obj->next) {
      return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xml_obj->next));
  }

  return v8::Null();
}

v8::Handle<v8::Value>
XmlNode::clone(bool recurse) {
  v8::HandleScope scope;

  return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xmlCopyNode(xml_obj, recurse)));
}

v8::Handle<v8::Value>
XmlNode::to_string() {
  v8::HandleScope scope;

  xmlBuffer* buf = xmlBufferCreate();
  const char* enc = "UTF-8";

  xmlSaveCtxt* savectx = xmlSaveToBuffer(buf, enc, NULL);
  xmlSaveTree(savectx, xml_obj);
  xmlSaveFlush(savectx);

  const xmlChar* xmlstr = xmlBufferContent(buf);

  if(xmlstr) {
      v8::Handle<v8::String> str = v8::String::New((char*)xmlstr, xmlBufferLength(buf));
      xmlSaveClose(savectx);

      xmlBufferFree(buf);

      return scope.Close(str);
  } else {
      xmlSaveClose(savectx);

      xmlBufferFree(buf);

      return v8::Null();
  }
}

void
XmlNode::remove() {
  xmlUnlinkNode(xml_obj);
}

v8::Handle<v8::Value>
XmlNode::get_type() {
  switch (xml_obj->type) {
  case  XML_ELEMENT_NODE:
    return v8::String::NewSymbol("element");
  case XML_ATTRIBUTE_NODE:
    return v8::String::NewSymbol("attribute");
  case XML_TEXT_NODE:
    return v8::String::NewSymbol("text");
  case XML_CDATA_SECTION_NODE:
    return v8::String::NewSymbol("cdata");
  case XML_ENTITY_REF_NODE:
    return v8::String::NewSymbol("entity_ref");
  case XML_ENTITY_NODE:
    return v8::String::NewSymbol("entity");
  case XML_PI_NODE:
    return v8::String::NewSymbol("pi");
  case XML_COMMENT_NODE:
    return v8::String::NewSymbol("comment");
  case XML_DOCUMENT_NODE:
    return v8::String::NewSymbol("document");
  case XML_DOCUMENT_TYPE_NODE:
    return v8::String::NewSymbol("document_type");
  case XML_DOCUMENT_FRAG_NODE:
    return v8::String::NewSymbol("document_frag");
  case XML_NOTATION_NODE:
    return v8::String::NewSymbol("notation");
  case XML_HTML_DOCUMENT_NODE:
    return v8::String::NewSymbol("html_document");
  case XML_DTD_NODE:
    return v8::String::NewSymbol("dtd");
  case XML_ELEMENT_DECL:
    return v8::String::NewSymbol("element_decl");
  case XML_ATTRIBUTE_DECL:
    return v8::String::NewSymbol("attribute_decl");
  case XML_ENTITY_DECL:
    return v8::String::NewSymbol("entity_decl");
  case XML_NAMESPACE_DECL:
    return v8::String::NewSymbol("namespace_decl");
  case XML_XINCLUDE_START:
    return v8::String::NewSymbol("xinclude_start");
  case XML_XINCLUDE_END:
    return v8::String::NewSymbol("xinclude_end");
  case XML_DOCB_DOCUMENT_NODE:
    return v8::String::NewSymbol("docb_document");
  }

  return v8::Null();
}

void
XmlNode::Initialize(v8::Handle<v8::Object> target) {
  v8::HandleScope scope;
  constructor_template =
    v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
  constructor_template->InstanceTemplate()->SetInternalFieldCount(1);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "doc",
                        XmlNode::Doc);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "parent",
                        XmlNode::Parent);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "namespace",
                        XmlNode::Namespace);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "prevSibling",
                        XmlNode::PrevSibling);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "nextSibling",
                        XmlNode::NextSibling);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "type",
                        XmlNode::Type);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "remove",
                        XmlNode::Remove);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "clone",
                        XmlNode::Clone);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "toString",
                        XmlNode::ToString);

  XmlElement::Initialize(target);
  XmlAttribute::Initialize(target);
}
}  // namespace libxmljs
<commit_msg>Use prettier BooleanValue()<commit_after>// Copyright 2009, Squish Tech, LLC.

#include "xml_node.h"
#include "xml_document.h"
#include "xml_namespace.h"
#include "xml_element.h"
#include "xml_attribute.h"

namespace libxmljs {

v8::Persistent<v8::FunctionTemplate> XmlNode::constructor_template;

v8::Handle<v8::Value>
XmlNode::Doc(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_doc());
}

v8::Handle<v8::Value>
XmlNode::Namespace(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  // #namespace() Get the node's namespace
  if (args.Length() == 0)
      return scope.Close(node->get_namespace());

  if (args[0]->IsNull())
      return scope.Close(node->remove_namespace());

  XmlNamespace *ns = NULL;

  // #namespace(ns) libxml.Namespace object was provided
  // TODO(sprsquish): check that it was actually given a namespace obj
  if (args[0]->IsObject())
    ns = LibXmlObj::Unwrap<XmlNamespace>(args[0]->ToObject());

  // #namespace(href) or #namespace(prefix, href)
  // if the namespace has already been defined on the node, just set it
  if (args[0]->IsString()) {
    v8::String::Utf8Value ns_to_find(args[0]->ToString());
    xmlNs* found_ns = node->find_namespace(*ns_to_find);
    if (found_ns) {
      ns = LibXmlObj::Unwrap<XmlNamespace>(
             LibXmlObj::GetMaybeBuild<XmlNamespace, xmlNs>(found_ns));
    }
  }

  // Namespace does not seem to exist, so create it.
  if (!ns) {
    int argc = 3;
    v8::Handle<v8::Value> argv[argc];
    argv[0] = args.This();

    if (args.Length() == 1) {
      argv[1] = v8::Null();
      argv[2] = args[0];
    } else {
      argv[1] = args[0];
      argv[2] = args[1];
    }

    v8::Handle<v8::Function> define_namespace =
      XmlNamespace::constructor_template->GetFunction();

    v8::Handle<v8::Value> new_ns = define_namespace->Call(args.This(), argc, argv);
    ns = LibXmlObj::Unwrap<XmlNamespace>(new_ns->ToObject());
  }

  node->set_namespace(ns->xml_obj);

  return scope.Close(node->get_namespace());
}

v8::Handle<v8::Value>
XmlNode::Parent(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_parent());
}

v8::Handle<v8::Value>
XmlNode::PrevSibling(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_prev_sibling());
}

v8::Handle<v8::Value>
XmlNode::NextSibling(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_next_sibling());
}

v8::Handle<v8::Value>
XmlNode::Type(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->get_type());
}

v8::Handle<v8::Value>
XmlNode::ToString(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  return scope.Close(node->to_string());
}

v8::Handle<v8::Value>
XmlNode::Remove(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  node->remove();

  return scope.Close(args.This());
}

v8::Handle<v8::Value>
XmlNode::Clone(const v8::Arguments& args) {
  v8::HandleScope scope;
  XmlNode *node = LibXmlObj::Unwrap<XmlNode>(args.This());
  assert(node);

  bool recurse = true;

  if (args.Length() == 1 && args[0]->IsBoolean())
      recurse = args[0]->ToBoolean()->BooleanValue();

  return scope.Close(node->clone(recurse));
}

XmlNode::XmlNode(xmlNode* node) : xml_obj(node) {
    xml_obj->_private = this;
    if(xml_obj->doc) {
        doc = v8::Persistent<v8::Value>::New(LibXmlObj::GetMaybeBuild<XmlDocument, xmlDoc>(xml_obj->doc));
    }
}

XmlNode::~XmlNode() {
    xml_obj->_private = NULL;
    doc.Dispose();
    doc.Clear();

  // We do not free the xmlNode here. It could still be part of a document
  // It will be freed when the doc is freed
  // xmlFree(xml_obj);
}

v8::Handle<v8::Value>
XmlNode::get_doc() {
  v8::HandleScope scope;
  return scope.Close(LibXmlObj::GetMaybeBuild<XmlDocument, xmlDoc>(xml_obj->doc));
}

v8::Handle<v8::Value>
XmlNode::remove_namespace() {
  xml_obj->ns = NULL;
  return v8::Null();
}

v8::Handle<v8::Value>
XmlNode::get_namespace() {
  v8::HandleScope scope;
  if (!xml_obj->ns)
    return v8::Null();

  return scope.Close(LibXmlObj::GetMaybeBuild<XmlNamespace, xmlNs>(xml_obj->ns));
}

void
XmlNode::set_namespace(xmlNs* ns) {
  xmlSetNs(xml_obj, ns);
}

xmlNs*
XmlNode::find_namespace(const char* search_str) {
  xmlNs* ns = NULL;

  // Find by prefix first
  ns = xmlSearchNs(xml_obj->doc, xml_obj, (const xmlChar*)search_str);

  // Or find by href
  if (!ns)
    ns = xmlSearchNsByHref(xml_obj->doc, xml_obj, (const xmlChar*)search_str);

  return ns;
}

v8::Handle<v8::Value>
XmlNode::get_parent() {
  v8::HandleScope scope;
  if (xml_obj->parent) {
      return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xml_obj->parent));
  }

  return scope.Close(LibXmlObj::GetMaybeBuild<XmlDocument, xmlDoc>(xml_obj->doc));
}

v8::Handle<v8::Value>
XmlNode::get_prev_sibling() {
  v8::HandleScope scope;
  if (xml_obj->prev) {
      return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xml_obj->prev));
  }

  return v8::Null();
}

v8::Handle<v8::Value>
XmlNode::get_next_sibling() {
  v8::HandleScope scope;
  if (xml_obj->next) {
      return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xml_obj->next));
  }

  return v8::Null();
}

v8::Handle<v8::Value>
XmlNode::clone(bool recurse) {
  v8::HandleScope scope;

  return scope.Close(LibXmlObj::GetMaybeBuild<XmlElement, xmlNode>(xmlCopyNode(xml_obj, recurse)));
}

v8::Handle<v8::Value>
XmlNode::to_string() {
  v8::HandleScope scope;

  xmlBuffer* buf = xmlBufferCreate();
  const char* enc = "UTF-8";

  xmlSaveCtxt* savectx = xmlSaveToBuffer(buf, enc, NULL);
  xmlSaveTree(savectx, xml_obj);
  xmlSaveFlush(savectx);

  const xmlChar* xmlstr = xmlBufferContent(buf);

  if(xmlstr) {
      v8::Handle<v8::String> str = v8::String::New((char*)xmlstr, xmlBufferLength(buf));
      xmlSaveClose(savectx);

      xmlBufferFree(buf);

      return scope.Close(str);
  } else {
      xmlSaveClose(savectx);

      xmlBufferFree(buf);

      return v8::Null();
  }
}

void
XmlNode::remove() {
  xmlUnlinkNode(xml_obj);
}

v8::Handle<v8::Value>
XmlNode::get_type() {
  switch (xml_obj->type) {
  case  XML_ELEMENT_NODE:
    return v8::String::NewSymbol("element");
  case XML_ATTRIBUTE_NODE:
    return v8::String::NewSymbol("attribute");
  case XML_TEXT_NODE:
    return v8::String::NewSymbol("text");
  case XML_CDATA_SECTION_NODE:
    return v8::String::NewSymbol("cdata");
  case XML_ENTITY_REF_NODE:
    return v8::String::NewSymbol("entity_ref");
  case XML_ENTITY_NODE:
    return v8::String::NewSymbol("entity");
  case XML_PI_NODE:
    return v8::String::NewSymbol("pi");
  case XML_COMMENT_NODE:
    return v8::String::NewSymbol("comment");
  case XML_DOCUMENT_NODE:
    return v8::String::NewSymbol("document");
  case XML_DOCUMENT_TYPE_NODE:
    return v8::String::NewSymbol("document_type");
  case XML_DOCUMENT_FRAG_NODE:
    return v8::String::NewSymbol("document_frag");
  case XML_NOTATION_NODE:
    return v8::String::NewSymbol("notation");
  case XML_HTML_DOCUMENT_NODE:
    return v8::String::NewSymbol("html_document");
  case XML_DTD_NODE:
    return v8::String::NewSymbol("dtd");
  case XML_ELEMENT_DECL:
    return v8::String::NewSymbol("element_decl");
  case XML_ATTRIBUTE_DECL:
    return v8::String::NewSymbol("attribute_decl");
  case XML_ENTITY_DECL:
    return v8::String::NewSymbol("entity_decl");
  case XML_NAMESPACE_DECL:
    return v8::String::NewSymbol("namespace_decl");
  case XML_XINCLUDE_START:
    return v8::String::NewSymbol("xinclude_start");
  case XML_XINCLUDE_END:
    return v8::String::NewSymbol("xinclude_end");
  case XML_DOCB_DOCUMENT_NODE:
    return v8::String::NewSymbol("docb_document");
  }

  return v8::Null();
}

void
XmlNode::Initialize(v8::Handle<v8::Object> target) {
  v8::HandleScope scope;
  constructor_template =
    v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
  constructor_template->InstanceTemplate()->SetInternalFieldCount(1);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "doc",
                        XmlNode::Doc);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "parent",
                        XmlNode::Parent);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "namespace",
                        XmlNode::Namespace);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "prevSibling",
                        XmlNode::PrevSibling);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "nextSibling",
                        XmlNode::NextSibling);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "type",
                        XmlNode::Type);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "remove",
                        XmlNode::Remove);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "clone",
                        XmlNode::Clone);

  LXJS_SET_PROTO_METHOD(constructor_template,
                        "toString",
                        XmlNode::ToString);

  XmlElement::Initialize(target);
  XmlAttribute::Initialize(target);
}
}  // namespace libxmljs
<|endoftext|>


<commit_before>#include "music.h"
#include <string>
#include <iostream>
#include "globals.h"
// #include "defs.h"
#include "dumb/include/aldumb.h"

#ifdef _WIN32
#include <winalleg.h>
#endif

#include <pthread.h>
#include "util/funcs.h"
#include "util/file-system.h"

using namespace std;

static Music * instance = NULL;

static double volume = 1.0;
// static bool muted = false;
static pthread_t musicThread;
static pthread_mutex_t musicMutex;
static bool alive = true;

static void * playMusic( void * );

#define synchronized for( int __l( ! pthread_mutex_lock( &musicMutex ) ); __l; __l = 0, pthread_mutex_unlock( &musicMutex ) )

#define LOCK pthread_mutex_lock( &musicMutex );
#define UNLOCK pthread_mutex_unlock( &musicMutex );

/*
#undef LOCK
#undef UNLOCK
#define LOCK
#define UNLOCK
*/

static void * bogus_thread( void * x){
	return NULL;
}

Music::Music( bool on ):
playing( false ),
fading( 0 ),
player( NULL ),
music_file( NULL ),
currentSong(""){

	if ( instance != NULL ){
		cerr << "Trying to instantiate music object twice!" << endl;
		return;
	}

	instance = this;

	pthread_mutex_init( &musicMutex, NULL );
	if ( on ){
		pthread_create( &musicThread, NULL, playMusic, (void *)instance );
	} else {
		pthread_create( &musicThread, NULL, bogus_thread, NULL );
	}
}

/*
static bool isAlive(){
	bool f = false;
	synchronized{
		f = alive;
	}
	return f;
}
*/

static void * playMusic( void * _music ){
    Music * music = (Music *) _music;

    Global::debug( 1 ) << "Playing music" << endl;

    /*
       unsigned int tick = 0;
       unsigned int counter;
       */

    bool playing = true;
    while ( playing ){

        LOCK;{
            playing = alive;
            music->doPlay();
        }
        UNLOCK;
        rest( 10 );

        // Util::YIELD();
        // pthread_yield();
    }

    // cout << "Done with music thread" << endl;

    return NULL;
}

double Music::getVolume(){
    double vol = 0;
    LOCK;{
        vol = volume;
    }
    UNLOCK;
    return vol;
}

void Music::doPlay(){
    if ( this->playing ){
        double f = fading / 500.0;
        switch ( fading ){
            case -1 : {
                          if ( volume + f < 0 ){
                              fading = 0;
                              volume = 0;
                          } else {
                              volume += f;
                              this->_setVolume( volume );
                          }
                          break;
                      }
            case 1 : {
                         if ( volume + f > 1.0 ){
                             fading = 0;
                             volume = 1.0;
                         } else {
                             volume += f;
                             this->_setVolume( volume );
                         }
                         break;
                     }
        }
        if ( al_poll_duh( this->player ) != 0 ){
        }
    }
}

/*
Music::Music( const char * song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){

	loadSong( song );

}

Music::Music( const string & song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){
	loadSong( song );
}
*/

void Music::fadeIn( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeIn();
    }
    UNLOCK;
}

void Music::fadeOut( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeOut();
    }
    UNLOCK;
}

void Music::_fadeIn(){
    fading = 1;
}

void Music::_fadeOut(){
    fading = -1;
}

bool Music::loadSong( const char * song ){
    bool loaded = false;
    LOCK;{
        loaded = instance->internal_loadSong( song );
    }
    UNLOCK;
    return loaded;
    // muted = false;
}

/* remove an element from a vector at index 'pos' and return it */
template< class Tx_ >
static Tx_ removeVectorElement( vector< Tx_ > & toRemove, int pos ){
    int count = 0;
    typename vector< Tx_ >::iterator it;
    for ( it = toRemove.begin(); it != toRemove.end() && count < pos; count++, it++ );

    if ( it == toRemove.end() ){
        /* this isnt right, but whatever */
        return toRemove.front();
    }

    const Tx_ & removed = toRemove[ pos ];
    toRemove.erase( it );
    return removed;

}

void Music::loadSong( const vector< string > & Songs ){

    /*
       cout << "Songs = " << &Songs << endl;
       if ( ! loadSong( "music/song5.xm" ) ){
       cerr << "Could not load music/song5.xm" << endl;
       }
       return;
       */

    vector< string > _songs = Songs;
    vector< string > songs;
    while ( ! _songs.empty() ){
        int i = Util::rnd( _songs.size() );
        songs.push_back( removeVectorElement< string >( _songs, i ) );
    }

    /*
       songs.clear();
       songs.push_back( "music/song3.xm" );
       */

    for ( vector< string >::iterator it = songs.begin(); it != songs.end(); it++ ){
        Global::debug( 1 ) << "Trying to load song " << *it << endl;
        if (loadSong(*it)){
            break;
        }
    }
}

bool Music::loadSong( const string & song ){
    return loadSong( song.c_str() );
}

void Music::_play(){
    if ( playing == false && this->player != NULL ){
        al_resume_duh( this->player );
        playing = true;
    }
}

void Music::play(){
    LOCK;{
        instance->_play();
    }
    UNLOCK;
}

void Music::_pause(){
    playing = false;
    if ( this->player != NULL ){
        al_pause_duh( this->player );
    }
}

void Music::pause(){
    LOCK;{
        instance->_pause();
    }
    UNLOCK;
}

void Music::soften(){
    LOCK;{
        instance->_soften();
    }
    UNLOCK;
}

void Music::_soften(){
    if ( volume > 0.1 ){
        volume -= 0.1;
    } else {
        volume = 0.0;
    }

    _setVolume( volume );
}

void Music::louden(){
    LOCK;{
        instance->_louden();
    }
    UNLOCK;
}

void Music::_louden(){
    if ( volume < 0.9 ){
        volume += 0.1;
    } else {
        volume = 1.0;
    }

    _setVolume( volume );
}

void Music::mute(){
    setVolume( 0 );
}

void Music::setVolume( double vol ){

    LOCK;{
        volume = vol;
        if ( volume > 1.0 ){
            volume = 1.0;
        }
        if ( volume < 0 ){
            volume = 0;
        }
        instance->_setVolume( volume );
    }
    UNLOCK;
}

void Music::_setVolume( double vol ){

    if ( player ){
        al_duh_set_volume( player, vol );
    }

}

Music::~Music(){

    LOCK;{
        if ( player ){
            al_stop_duh( player );
            unload_duh( music_file );
        }

        alive = false;
        playing = false;
    }
    UNLOCK;

    Global::debug( 1 ) << "Waiting for music thread to die" << endl;
    pthread_join( musicThread, NULL );

}

/*
void Music::pause(){
	al_pause_duh( player );
}
*/

/*
void Music::resume(){
	al_resume_duh( player );
}
*/

static const char * typeToExtension( int i ){
    switch (i){
        case 0 : return ".xm";
        case 1 : return ".s3m";
        case 2 : return ".it";
        case 3 : return ".mod";
        default : return "";
    }
}

bool Music::internal_loadSong( const char * path ){

    // cout << "Trying to load '" << path << "'" << endl;

    // Check current song and/or set it
    if (currentSong.compare(std::string(path))==0){
        return true;
    } else {
        currentSong = std::string(path);
    }

    if ( player != NULL ){
        al_stop_duh( player );
        unload_duh( music_file );
        player = NULL;
        music_file = NULL;
    }

    // music_file = dumb_load_mod( path );
    /*
       music_file = dumb_load_mod( path );
       if ( !music_file ){
       music_file = dumb_load_xm( path );
       }
       if ( !music_file ){
       music_file = dumb_load_s3m( path );
       }
       if ( !music_file ){
       music_file = dumb_load_it( path );
       }
       */

    for ( int i = 0; i < 4; i++ ){
        /* the order of trying xm/s3m/it/mod matters because mod could be
         * confused with one of the other formats, so load it last.
         */
        switch (i){
            case 0 : {
                         music_file = dumb_load_xm_quick( path );
                         break;
                     }
            case 1 : {
                         music_file = dumb_load_s3m_quick( path );
                         break;
                     }
            case 2 : {
                         music_file = dumb_load_it_quick( path );
                         break;
                     }
            case 3 : {
                         music_file = dumb_load_mod_quick( path );
                         break;
                     }
        }
        if ( music_file != NULL ){
            Global::debug(0) << "Loaded " << path << " type " << typeToExtension( i ) << "(" << i << ")" << endl;
            break;
        }
    }

    if (music_file){
        int buf = 1 << 11;
        player = al_start_duh( music_file, 2, 0, volume, buf, 22050 );
        // cout << "Loaded music player " << player << endl;

        /*
           while ( 1 ){
           al_poll_duh( player );
           rest( 1 );
           }
           */

        if (player != NULL){
            playing = true;
        } else {
            Global::debug(0) << "*BUG* Could not create music player" << endl;
        }
    } else {
        Global::debug( 0 )<<"Could not load "<<path<<endl;
        return false;
    }
    return true;

}

void Music::changeSong(){
    pause();
    fadeIn(0.3);
    loadSong(Util::getFiles(Filesystem::find(Filesystem::RelativePath("music/")), "*"));
    play();
}

#undef synchronized
#undef LOCK
#undef UNLOCK
<commit_msg>add LitBitmap dummy sdl functions<commit_after>#include "music.h"
#include <string>
#include <iostream>
#include "globals.h"
// #include "defs.h"
#include "dumb/include/aldumb.h"

#ifdef _WIN32
#include <winalleg.h>
#endif

#include <pthread.h>
#include "util/funcs.h"
#include "util/file-system.h"

using namespace std;

static Music * instance = NULL;

static double volume = 1.0;
// static bool muted = false;
static pthread_t musicThread;
static pthread_mutex_t musicMutex;
static bool alive = true;

static void * playMusic( void * );

#define synchronized for( int __l( ! pthread_mutex_lock( &musicMutex ) ); __l; __l = 0, pthread_mutex_unlock( &musicMutex ) )

#define LOCK pthread_mutex_lock( &musicMutex );
#define UNLOCK pthread_mutex_unlock( &musicMutex );

/*
#undef LOCK
#undef UNLOCK
#define LOCK
#define UNLOCK
*/

static void * bogus_thread( void * x){
	return NULL;
}

Music::Music( bool on ):
playing( false ),
fading( 0 ),
player( NULL ),
music_file( NULL ),
currentSong(""){

	if ( instance != NULL ){
		cerr << "Trying to instantiate music object twice!" << endl;
		return;
	}

	instance = this;

	pthread_mutex_init( &musicMutex, NULL );
	if ( on ){
		pthread_create( &musicThread, NULL, playMusic, (void *)instance );
	} else {
		pthread_create( &musicThread, NULL, bogus_thread, NULL );
	}
}

/*
static bool isAlive(){
	bool f = false;
	synchronized{
		f = alive;
	}
	return f;
}
*/

static void * playMusic( void * _music ){
    Music * music = (Music *) _music;

    Global::debug( 1 ) << "Playing music" << endl;

    /*
       unsigned int tick = 0;
       unsigned int counter;
       */

    bool playing = true;
    while ( playing ){

        LOCK;{
            playing = alive;
            music->doPlay();
        }
        UNLOCK;
        Util::rest( 10 );

        // Util::YIELD();
        // pthread_yield();
    }

    // cout << "Done with music thread" << endl;

    return NULL;
}

double Music::getVolume(){
    double vol = 0;
    LOCK;{
        vol = volume;
    }
    UNLOCK;
    return vol;
}

void Music::doPlay(){
    if ( this->playing ){
        double f = fading / 500.0;
        switch ( fading ){
            case -1 : {
                          if ( volume + f < 0 ){
                              fading = 0;
                              volume = 0;
                          } else {
                              volume += f;
                              this->_setVolume( volume );
                          }
                          break;
                      }
            case 1 : {
                         if ( volume + f > 1.0 ){
                             fading = 0;
                             volume = 1.0;
                         } else {
                             volume += f;
                             this->_setVolume( volume );
                         }
                         break;
                     }
        }
        if ( al_poll_duh( this->player ) != 0 ){
        }
    }
}

/*
Music::Music( const char * song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){

	loadSong( song );

}

Music::Music( const string & song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){
	loadSong( song );
}
*/

void Music::fadeIn( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeIn();
    }
    UNLOCK;
}

void Music::fadeOut( double vol ){
    LOCK;{
        volume = vol;
        instance->_fadeOut();
    }
    UNLOCK;
}

void Music::_fadeIn(){
    fading = 1;
}

void Music::_fadeOut(){
    fading = -1;
}

bool Music::loadSong( const char * song ){
    bool loaded = false;
    LOCK;{
        loaded = instance->internal_loadSong( song );
    }
    UNLOCK;
    return loaded;
    // muted = false;
}

/* remove an element from a vector at index 'pos' and return it */
template< class Tx_ >
static Tx_ removeVectorElement( vector< Tx_ > & toRemove, int pos ){
    int count = 0;
    typename vector< Tx_ >::iterator it;
    for ( it = toRemove.begin(); it != toRemove.end() && count < pos; count++, it++ );

    if ( it == toRemove.end() ){
        /* this isnt right, but whatever */
        return toRemove.front();
    }

    const Tx_ & removed = toRemove[ pos ];
    toRemove.erase( it );
    return removed;

}

void Music::loadSong( const vector< string > & Songs ){

    /*
       cout << "Songs = " << &Songs << endl;
       if ( ! loadSong( "music/song5.xm" ) ){
       cerr << "Could not load music/song5.xm" << endl;
       }
       return;
       */

    vector< string > _songs = Songs;
    vector< string > songs;
    while ( ! _songs.empty() ){
        int i = Util::rnd( _songs.size() );
        songs.push_back( removeVectorElement< string >( _songs, i ) );
    }

    /*
       songs.clear();
       songs.push_back( "music/song3.xm" );
       */

    for ( vector< string >::iterator it = songs.begin(); it != songs.end(); it++ ){
        Global::debug( 1 ) << "Trying to load song " << *it << endl;
        if (loadSong(*it)){
            break;
        }
    }
}

bool Music::loadSong( const string & song ){
    return loadSong( song.c_str() );
}

void Music::_play(){
    if ( playing == false && this->player != NULL ){
        al_resume_duh( this->player );
        playing = true;
    }
}

void Music::play(){
    LOCK;{
        instance->_play();
    }
    UNLOCK;
}

void Music::_pause(){
    playing = false;
    if ( this->player != NULL ){
        al_pause_duh( this->player );
    }
}

void Music::pause(){
    LOCK;{
        instance->_pause();
    }
    UNLOCK;
}

void Music::soften(){
    LOCK;{
        instance->_soften();
    }
    UNLOCK;
}

void Music::_soften(){
    if ( volume > 0.1 ){
        volume -= 0.1;
    } else {
        volume = 0.0;
    }

    _setVolume( volume );
}

void Music::louden(){
    LOCK;{
        instance->_louden();
    }
    UNLOCK;
}

void Music::_louden(){
    if ( volume < 0.9 ){
        volume += 0.1;
    } else {
        volume = 1.0;
    }

    _setVolume( volume );
}

void Music::mute(){
    setVolume( 0 );
}

void Music::setVolume( double vol ){

    LOCK;{
        volume = vol;
        if ( volume > 1.0 ){
            volume = 1.0;
        }
        if ( volume < 0 ){
            volume = 0;
        }
        instance->_setVolume( volume );
    }
    UNLOCK;
}

void Music::_setVolume( double vol ){

    if ( player ){
        al_duh_set_volume( player, vol );
    }

}

Music::~Music(){

    LOCK;{
        if ( player ){
            al_stop_duh( player );
            unload_duh( music_file );
        }

        alive = false;
        playing = false;
    }
    UNLOCK;

    Global::debug( 1 ) << "Waiting for music thread to die" << endl;
    pthread_join( musicThread, NULL );

}

/*
void Music::pause(){
	al_pause_duh( player );
}
*/

/*
void Music::resume(){
	al_resume_duh( player );
}
*/

static const char * typeToExtension( int i ){
    switch (i){
        case 0 : return ".xm";
        case 1 : return ".s3m";
        case 2 : return ".it";
        case 3 : return ".mod";
        default : return "";
    }
}

bool Music::internal_loadSong( const char * path ){

    // cout << "Trying to load '" << path << "'" << endl;

    // Check current song and/or set it
    if (currentSong.compare(std::string(path))==0){
        return true;
    } else {
        currentSong = std::string(path);
    }

    if ( player != NULL ){
        al_stop_duh( player );
        unload_duh( music_file );
        player = NULL;
        music_file = NULL;
    }

    // music_file = dumb_load_mod( path );
    /*
       music_file = dumb_load_mod( path );
       if ( !music_file ){
       music_file = dumb_load_xm( path );
       }
       if ( !music_file ){
       music_file = dumb_load_s3m( path );
       }
       if ( !music_file ){
       music_file = dumb_load_it( path );
       }
       */

    for ( int i = 0; i < 4; i++ ){
        /* the order of trying xm/s3m/it/mod matters because mod could be
         * confused with one of the other formats, so load it last.
         */
        switch (i){
            case 0 : {
                         music_file = dumb_load_xm_quick( path );
                         break;
                     }
            case 1 : {
                         music_file = dumb_load_s3m_quick( path );
                         break;
                     }
            case 2 : {
                         music_file = dumb_load_it_quick( path );
                         break;
                     }
            case 3 : {
                         music_file = dumb_load_mod_quick( path );
                         break;
                     }
        }
        if ( music_file != NULL ){
            Global::debug(0) << "Loaded " << path << " type " << typeToExtension( i ) << "(" << i << ")" << endl;
            break;
        }
    }

    if (music_file){
        int buf = 1 << 11;
        player = al_start_duh( music_file, 2, 0, volume, buf, 22050 );
        // cout << "Loaded music player " << player << endl;

        /*
           while ( 1 ){
           al_poll_duh( player );
           rest( 1 );
           }
           */

        if (player != NULL){
            playing = true;
        } else {
            Global::debug(0) << "*BUG* Could not create music player" << endl;
        }
    } else {
        Global::debug( 0 )<<"Could not load "<<path<<endl;
        return false;
    }
    return true;

}

void Music::changeSong(){
    pause();
    fadeIn(0.3);
    loadSong(Util::getFiles(Filesystem::find(Filesystem::RelativePath("music/")), "*"));
    play();
}

#undef synchronized
#undef LOCK
#undef UNLOCK
<|endoftext|>


<commit_before>#include "music.h"
#include "dumb/include/aldumb.h"
#include <string>
#include <iostream>
#include "globals.h"
// #include "defs.h"

#ifdef WINDOWS
#include <winalleg.h>
#endif

#include <pthread.h>
#include "util/funcs.h"

using namespace std;

static Music * instance = NULL;

static double volume = 1.0;
// static bool muted = false;
static pthread_t musicThread;
static pthread_mutex_t musicMutex;
static bool alive = true;

static void * playMusic( void * );

#define synchronized for( int __l( ! pthread_mutex_lock( &musicMutex ) ); __l; __l = 0, pthread_mutex_unlock( &musicMutex ) )

#define LOCK pthread_mutex_lock( &musicMutex );
#define UNLOCK pthread_mutex_unlock( &musicMutex );

/*
#undef LOCK
#undef UNLOCK
#define LOCK
#define UNLOCK
*/

Music::Music():
playing( false ),
fading( 0 ),
player( NULL ),
music_file( NULL ){

	if ( instance != NULL ){
		cerr << "Trying to instantiate music object twice!" << endl;
		return;
	}

	instance = this;

	pthread_mutex_init( &musicMutex, NULL );
	pthread_create( &musicThread, NULL, playMusic, (void *)instance );
}

/*
static bool isAlive(){
	bool f = false;
	synchronized{
		f = alive;
	}
	return f;
}
*/

static void * playMusic( void * _music ){
	Music * music = (Music *) _music;

	Global::debug( 1 ) << "Playing music" << endl;

	/*
	unsigned int tick = 0;
	unsigned int counter;
	*/

	bool playing = true;
	while ( playing ){

		LOCK;{
			playing = alive;
			music->doPlay();
		}
		UNLOCK;
		rest( 10 );

		// Util::YIELD();
		// pthread_yield();
	}

	// cout << "Done with music thread" << endl;

	return NULL;
}

double Music::getVolume(){
	LOCK;{
		return volume;
	}
	UNLOCK;
}

void Music::doPlay(){
	if ( this->playing ){
		double f = fading / 500.0;
		switch ( fading ){
			case -1 : {
				if ( volume + f < 0 ){
					fading = 0;
					volume = 0;
				} else {
					volume += f;
					this->_setVolume( volume );
				}
				break;
			}
			case 1 : {
				if ( volume + f > 1.0 ){
					fading = 0;
					volume = 1.0;
				} else {
					volume += f;
					this->_setVolume( volume );
				}
				break;
			}
		}
		if ( al_poll_duh( this->player ) != 0 ){
		}
	}
}

/*
Music::Music( const char * song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){

	loadSong( song );

}

Music::Music( const string & song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){
	loadSong( song );
}
*/

void Music::fadeIn( double vol ){
	LOCK;{
		volume = vol;
		instance->_fadeIn();
	}
	UNLOCK;
}

void Music::fadeOut( double vol ){
	LOCK;{
		volume = vol;
		instance->_fadeOut();
	}
	UNLOCK;
}

void Music::_fadeIn(){
	fading = 1;
}

void Music::_fadeOut(){
	fading = -1;
}

bool Music::loadSong( const char * song ){
	bool loaded = false;
	LOCK;{
		loaded = instance->internal_loadSong( song );
	}
	UNLOCK;
	return loaded;
	// muted = false;
}

/* remove an element from a vector at index 'pos' and return it */
template< class Tx_ >
static Tx_ removeVectorElement( vector< Tx_ > & toRemove, int pos ){
	int count = 0;
	typename vector< Tx_ >::iterator it;
	for ( it = toRemove.begin(); it != toRemove.end() && count < pos; count++, it++ );

	if ( it == toRemove.end() ){
		/* this isnt right, but whatever */
		return toRemove.front();
	}

	const Tx_ & removed = toRemove[ pos ];
	toRemove.erase( it );
	return removed;

}

void Music::loadSong( const vector< string > & Songs ){

	/*
	cout << "Songs = " << &Songs << endl;
	if ( ! loadSong( "music/song5.xm" ) ){
		cerr << "Could not load music/song5.xm" << endl;
	}
	return;
	*/

	vector< string > _songs = Songs;
	vector< string > songs;
	while ( ! _songs.empty() ){
		int i = Util::rnd( _songs.size() );
		songs.push_back( removeVectorElement< string >( _songs, i ) );
	}

	/*
	songs.clear();
	songs.push_back( "music/song3.xm" );
	*/

	for ( vector< string >::iterator it = songs.begin(); it != songs.end(); it++ ){
		Global::debug( 1 ) << "Trying to load song " << *it << endl;
		if ( loadSong( *it ) ){
			break;
		}
	}
}

bool Music::loadSong( const string & song ){
	return loadSong( song.c_str() );
}

void Music::_play(){
	if ( playing == false && this->player != NULL ){
		al_resume_duh( this->player );
	}
	playing = true;
}

void Music::play(){
	LOCK;{
		instance->_play();
	}
	UNLOCK;
}

void Music::_pause(){
	playing = false;
	if ( this->player != NULL ){
		al_pause_duh( this->player );
	}
}

void Music::pause(){
	LOCK;{
		instance->_pause();
	}
	UNLOCK;
}

void Music::soften(){
	LOCK;{
		instance->_soften();
	}
	UNLOCK;
}

void Music::_soften(){
	if ( volume > 0.1 ){
		volume -= 0.1;
	} else {
		volume = 0.0;
	}

	_setVolume( volume );
}

void Music::louden(){
	LOCK;{
		instance->_louden();
	}
	UNLOCK;
}

void Music::_louden(){
	if ( volume < 0.9 ){
		volume += 0.1;
	} else {
		volume = 1.0;
	}

	_setVolume( volume );
}

void Music::mute(){
	setVolume( 0 );
}

void Music::setVolume( double vol ){

	LOCK;{
		volume = vol;
		if ( volume > 1.0 ){
			volume = 1.0;
		}
		if ( volume < 0 ){
			volume = 0;
		}
		instance->_setVolume( volume );
	}
	UNLOCK;
}

void Music::_setVolume( double vol ){

	if ( player ){
		al_duh_set_volume( player, vol );
	}

}

Music::~Music(){

	LOCK;{
		if ( player ){
			al_stop_duh( player );
			unload_duh( music_file );
		}

		alive = false;
		playing = false;
	}
	UNLOCK;

	Global::debug( 1 ) << "Waiting for music thread to die" << endl;
	pthread_join( musicThread, NULL );

}

/*
void Music::pause(){
	al_pause_duh( player );
}
*/

/*
void Music::resume(){
	al_resume_duh( player );
}
*/

static const char * typeToExtension( int i ){
	switch ( i ){
		case 0 : return ".xm";
		case 1 : return ".s3m";
		case 2 : return ".it";
		case 3 : return ".mod";
		default : return "";
	}
}

bool Music::internal_loadSong( const char * path ){

	// cout << "Trying to load '" << path << "'" << endl;

	if ( player != NULL ){
		al_stop_duh( player );
		unload_duh( music_file );
		player = NULL;
		music_file = NULL;
	}

	// music_file = dumb_load_mod( path );
	/*
	music_file = dumb_load_mod( path );
	if ( !music_file ){
		music_file = dumb_load_xm( path );
	}
	if ( !music_file ){
		music_file = dumb_load_s3m( path );
	}
	if ( !music_file ){
		music_file = dumb_load_it( path );
	}
	*/

	for ( int i = 0; i < 4; i++ ){
		switch ( i ){
			case 0 : {
				music_file = dumb_load_xm( path );
				break;
			}
			case 1 : {
				music_file = dumb_load_s3m( path );
				break;
			}
			case 2 : {
				music_file = dumb_load_it( path );
				break;
			}
			case 3 : {
				music_file = dumb_load_mod( path );
				break;
			}
		}
		if ( music_file != NULL ){
			Global::debug( 0 ) << "Loaded " << path << " type " << typeToExtension( i ) << "( " << i << " )" << endl;
			break;
		}
	}

	if ( music_file ){
		int buf = 1 << 11;
		player = al_start_duh( music_file, 2, 0, volume, buf, 22050 );
		// cout << "Loaded music player " << player << endl;

		/*
		while ( 1 ){
			al_poll_duh( player );
			rest( 1 );
		}
		*/

		playing = true;
	} else {
		Global::debug( 0 )<<"Could not load "<<path<<endl;
		return false;
	}
	return true;

}

#undef synchronized
#undef LOCK
#undef UNLOCK
<commit_msg>use dumb quick loading functions<commit_after>#include "music.h"
#include "dumb/include/aldumb.h"
#include <string>
#include <iostream>
#include "globals.h"
// #include "defs.h"

#ifdef WINDOWS
#include <winalleg.h>
#endif

#include <pthread.h>
#include "util/funcs.h"

using namespace std;

static Music * instance = NULL;

static double volume = 1.0;
// static bool muted = false;
static pthread_t musicThread;
static pthread_mutex_t musicMutex;
static bool alive = true;

static void * playMusic( void * );

#define synchronized for( int __l( ! pthread_mutex_lock( &musicMutex ) ); __l; __l = 0, pthread_mutex_unlock( &musicMutex ) )

#define LOCK pthread_mutex_lock( &musicMutex );
#define UNLOCK pthread_mutex_unlock( &musicMutex );

/*
#undef LOCK
#undef UNLOCK
#define LOCK
#define UNLOCK
*/

Music::Music():
playing( false ),
fading( 0 ),
player( NULL ),
music_file( NULL ){

	if ( instance != NULL ){
		cerr << "Trying to instantiate music object twice!" << endl;
		return;
	}

	instance = this;

	pthread_mutex_init( &musicMutex, NULL );
	pthread_create( &musicThread, NULL, playMusic, (void *)instance );
}

/*
static bool isAlive(){
	bool f = false;
	synchronized{
		f = alive;
	}
	return f;
}
*/

static void * playMusic( void * _music ){
	Music * music = (Music *) _music;

	Global::debug( 1 ) << "Playing music" << endl;

	/*
	unsigned int tick = 0;
	unsigned int counter;
	*/

	bool playing = true;
	while ( playing ){

		LOCK;{
			playing = alive;
			music->doPlay();
		}
		UNLOCK;
		rest( 10 );

		// Util::YIELD();
		// pthread_yield();
	}

	// cout << "Done with music thread" << endl;

	return NULL;
}

double Music::getVolume(){
	LOCK;{
		return volume;
	}
	UNLOCK;
}

void Music::doPlay(){
	if ( this->playing ){
		double f = fading / 500.0;
		switch ( fading ){
			case -1 : {
				if ( volume + f < 0 ){
					fading = 0;
					volume = 0;
				} else {
					volume += f;
					this->_setVolume( volume );
				}
				break;
			}
			case 1 : {
				if ( volume + f > 1.0 ){
					fading = 0;
					volume = 1.0;
				} else {
					volume += f;
					this->_setVolume( volume );
				}
				break;
			}
		}
		if ( al_poll_duh( this->player ) != 0 ){
		}
	}
}

/*
Music::Music( const char * song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){

	loadSong( song );

}

Music::Music( const string & song ):
volume( 1.0 ),
muted( false ),
player( NULL ),
music_file( NULL ){
	loadSong( song );
}
*/

void Music::fadeIn( double vol ){
	LOCK;{
		volume = vol;
		instance->_fadeIn();
	}
	UNLOCK;
}

void Music::fadeOut( double vol ){
	LOCK;{
		volume = vol;
		instance->_fadeOut();
	}
	UNLOCK;
}

void Music::_fadeIn(){
	fading = 1;
}

void Music::_fadeOut(){
	fading = -1;
}

bool Music::loadSong( const char * song ){
	bool loaded = false;
	LOCK;{
		loaded = instance->internal_loadSong( song );
	}
	UNLOCK;
	return loaded;
	// muted = false;
}

/* remove an element from a vector at index 'pos' and return it */
template< class Tx_ >
static Tx_ removeVectorElement( vector< Tx_ > & toRemove, int pos ){
	int count = 0;
	typename vector< Tx_ >::iterator it;
	for ( it = toRemove.begin(); it != toRemove.end() && count < pos; count++, it++ );

	if ( it == toRemove.end() ){
		/* this isnt right, but whatever */
		return toRemove.front();
	}

	const Tx_ & removed = toRemove[ pos ];
	toRemove.erase( it );
	return removed;

}

void Music::loadSong( const vector< string > & Songs ){

	/*
	cout << "Songs = " << &Songs << endl;
	if ( ! loadSong( "music/song5.xm" ) ){
		cerr << "Could not load music/song5.xm" << endl;
	}
	return;
	*/

	vector< string > _songs = Songs;
	vector< string > songs;
	while ( ! _songs.empty() ){
		int i = Util::rnd( _songs.size() );
		songs.push_back( removeVectorElement< string >( _songs, i ) );
	}

	/*
	songs.clear();
	songs.push_back( "music/song3.xm" );
	*/

	for ( vector< string >::iterator it = songs.begin(); it != songs.end(); it++ ){
		Global::debug( 1 ) << "Trying to load song " << *it << endl;
		if ( loadSong( *it ) ){
			break;
		}
	}
}

bool Music::loadSong( const string & song ){
	return loadSong( song.c_str() );
}

void Music::_play(){
	if ( playing == false && this->player != NULL ){
		al_resume_duh( this->player );
	}
	playing = true;
}

void Music::play(){
	LOCK;{
		instance->_play();
	}
	UNLOCK;
}

void Music::_pause(){
	playing = false;
	if ( this->player != NULL ){
		al_pause_duh( this->player );
	}
}

void Music::pause(){
	LOCK;{
		instance->_pause();
	}
	UNLOCK;
}

void Music::soften(){
	LOCK;{
		instance->_soften();
	}
	UNLOCK;
}

void Music::_soften(){
	if ( volume > 0.1 ){
		volume -= 0.1;
	} else {
		volume = 0.0;
	}

	_setVolume( volume );
}

void Music::louden(){
	LOCK;{
		instance->_louden();
	}
	UNLOCK;
}

void Music::_louden(){
	if ( volume < 0.9 ){
		volume += 0.1;
	} else {
		volume = 1.0;
	}

	_setVolume( volume );
}

void Music::mute(){
	setVolume( 0 );
}

void Music::setVolume( double vol ){

	LOCK;{
		volume = vol;
		if ( volume > 1.0 ){
			volume = 1.0;
		}
		if ( volume < 0 ){
			volume = 0;
		}
		instance->_setVolume( volume );
	}
	UNLOCK;
}

void Music::_setVolume( double vol ){

	if ( player ){
		al_duh_set_volume( player, vol );
	}

}

Music::~Music(){

	LOCK;{
		if ( player ){
			al_stop_duh( player );
			unload_duh( music_file );
		}

		alive = false;
		playing = false;
	}
	UNLOCK;

	Global::debug( 1 ) << "Waiting for music thread to die" << endl;
	pthread_join( musicThread, NULL );

}

/*
void Music::pause(){
	al_pause_duh( player );
}
*/

/*
void Music::resume(){
	al_resume_duh( player );
}
*/

static const char * typeToExtension( int i ){
	switch ( i ){
		case 0 : return ".xm";
		case 1 : return ".s3m";
		case 2 : return ".it";
		case 3 : return ".mod";
		default : return "";
	}
}

bool Music::internal_loadSong( const char * path ){

	// cout << "Trying to load '" << path << "'" << endl;

	if ( player != NULL ){
		al_stop_duh( player );
		unload_duh( music_file );
		player = NULL;
		music_file = NULL;
	}

	// music_file = dumb_load_mod( path );
	/*
	music_file = dumb_load_mod( path );
	if ( !music_file ){
		music_file = dumb_load_xm( path );
	}
	if ( !music_file ){
		music_file = dumb_load_s3m( path );
	}
	if ( !music_file ){
		music_file = dumb_load_it( path );
	}
	*/

	for ( int i = 0; i < 4; i++ ){
		switch ( i ){
			case 0 : {
				music_file = dumb_load_xm_quick( path );
				break;
			}
			case 1 : {
				music_file = dumb_load_s3m_quick( path );
				break;
			}
			case 2 : {
				music_file = dumb_load_it_quick( path );
				break;
			}
			case 3 : {
				music_file = dumb_load_mod_quick( path );
				break;
			}
		}
		if ( music_file != NULL ){
			Global::debug( 0 ) << "Loaded " << path << " type " << typeToExtension( i ) << "( " << i << " )" << endl;
			break;
		}
	}

	if ( music_file ){
		int buf = 1 << 11;
		player = al_start_duh( music_file, 2, 0, volume, buf, 22050 );
		// cout << "Loaded music player " << player << endl;

		/*
		while ( 1 ){
			al_poll_duh( player );
			rest( 1 );
		}
		*/

		playing = true;
	} else {
		Global::debug( 0 )<<"Could not load "<<path<<endl;
		return false;
	}
	return true;

}

#undef synchronized
#undef LOCK
#undef UNLOCK
<|endoftext|>


<commit_before>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/

#include "otbConcatenateImages.h"

#include <iostream>
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbObjectList.h"
#include "otbImageList.h"
#include "otbImageListToVectorImageFilter.h"
#include "otbStreamingImageFileWriter.h"
#include "otbStandardFilterWatcher.h"

namespace otb
{

template<typename PixelType>
int generic_main_concatenate(otb::ApplicationOptionsResult* parseResult)
{
  const unsigned int NbImages = parseResult->GetNumberOfParameters("InputImagesList");

  std::ofstream textFile;

  if (parseResult->IsOptionPresent("OutputNameList"))
    {
    std::string textName = parseResult->GetParameterString("OutputNameList");
    textFile.open(textName.c_str());
    }

  std::cout << "Concat of " << NbImages << " images into a multi-band image " << std::endl;

  const unsigned int Dimension = 2;
  typedef otb::Image<PixelType, Dimension>     InputImageType;
  typedef otb::ImageFileReader<InputImageType> ImageReaderType;
  typedef otb::ObjectList<ImageReaderType>     ReaderListType;

  typename ReaderListType::Pointer readerList = ReaderListType::New();

  typedef otb::ImageList<InputImageType> ImageListType;
  typename ImageListType::Pointer imageList = ImageListType::New();

  for (unsigned int i = 0; i < NbImages; i++)
    {
    typename ImageReaderType::Pointer imageReader = ImageReaderType::New();
    imageReader->SetFileName(parseResult->GetParameterString("InputImagesList", i).c_str());

    std::cout << "Adding image " << parseResult->GetParameterString("InputImagesList", i).c_str() << std::endl;
    textFile << parseResult->GetParameterString("InputImagesList", i) << "\n";

    imageReader->UpdateOutputInformation();

    imageList->PushBack(imageReader->GetOutput());
    readerList->PushBack(imageReader);
    }

  textFile.close();

  typedef otb::VectorImage<PixelType, Dimension> VectorImageType;
  typedef otb::ImageListToVectorImageFilter<ImageListType, VectorImageType> ImageListToVectorImageFilterType;
  typename ImageListToVectorImageFilterType::Pointer iL2VI = ImageListToVectorImageFilterType::New();

  iL2VI->SetInput(imageList);

  typedef otb::StreamingImageFileWriter<VectorImageType> ImageWriterType;
  typename ImageWriterType::Pointer imageWriter = ImageWriterType::New();
  imageWriter->SetFileName(parseResult->GetOutputImage().c_str());

  unsigned long size = (10000 * 10000 * sizeof(PixelType)) / NbImages;

  std::cout << "Streaming size: " << size << std::endl;

  imageWriter->SetBufferMemorySize(size);
  imageWriter->SetInput(iL2VI->GetOutput());

  otb::StandardFilterWatcher watcher(imageWriter, "Writing");
  imageWriter->Update();

  return EXIT_SUCCESS;
}

int ConcatenateImages::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("ConcatenateImages");
  descriptor->SetDescription("Concatenate n images in a multiband image");
  descriptor->AddOutputImage();
  descriptor->AddOptionNParams("InputImagesList", "Images list to concatenate", "il", true,ApplicationDescriptor::InputImage);
  descriptor->AddOption("OutputPixelType",
                        "OutputPixelType: unsigned char (1), short int (2), int (3), float (4),"
                        " double (5), unsigned short int (12), unsigned int (13); default 2",
                        "t", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("OutputNameList",
                        "Text file containing the name of the images used to generate the output in the same order",
                        "ot", 1, false,ApplicationDescriptor::String);

  return EXIT_SUCCESS;
}

int ConcatenateImages::Execute(otb::ApplicationOptionsResult* parseResult)
{
  unsigned int type = 2; //default to short int as the original
                         //program

  if (parseResult->IsOptionPresent("OutputPixelType"))
    {
    type = parseResult->GetParameterUInt("OutputPixelType");
    }

  switch (type)
    {
    case 1:
      generic_main_concatenate<unsigned char> (parseResult);
      break;
    case 2:
      generic_main_concatenate<short int> (parseResult);
      break;
    case 3:
      generic_main_concatenate<int> (parseResult);
      break;
    case 4:
      generic_main_concatenate<float> (parseResult);
      break;
    case 5:
      generic_main_concatenate<double> (parseResult);
      break;
    case 12:
      generic_main_concatenate<unsigned short int> (parseResult);
      break;
    case 13:
      generic_main_concatenate<unsigned int> (parseResult);
      break;
    default:
      generic_main_concatenate<unsigned char> (parseResult);
      break;
    }

  return EXIT_SUCCESS;
}
}
<commit_msg>ENH: update parameters type for proper UI widget generation<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/

#include "otbConcatenateImages.h"

#include <iostream>
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbObjectList.h"
#include "otbImageList.h"
#include "otbImageListToVectorImageFilter.h"
#include "otbStreamingImageFileWriter.h"
#include "otbStandardFilterWatcher.h"

namespace otb
{

template<typename PixelType>
int generic_main_concatenate(otb::ApplicationOptionsResult* parseResult)
{
  const unsigned int NbImages = parseResult->GetNumberOfParameters("InputImagesList");

  std::ofstream textFile;

  if (parseResult->IsOptionPresent("OutputNameList"))
    {
    std::string textName = parseResult->GetParameterString("OutputNameList");
    textFile.open(textName.c_str());
    }

  std::cout << "Concat of " << NbImages << " images into a multi-band image " << std::endl;

  const unsigned int Dimension = 2;
  typedef otb::Image<PixelType, Dimension>     InputImageType;
  typedef otb::ImageFileReader<InputImageType> ImageReaderType;
  typedef otb::ObjectList<ImageReaderType>     ReaderListType;

  typename ReaderListType::Pointer readerList = ReaderListType::New();

  typedef otb::ImageList<InputImageType> ImageListType;
  typename ImageListType::Pointer imageList = ImageListType::New();

  for (unsigned int i = 0; i < NbImages; i++)
    {
    typename ImageReaderType::Pointer imageReader = ImageReaderType::New();
    imageReader->SetFileName(parseResult->GetParameterString("InputImagesList", i).c_str());

    std::cout << "Adding image " << parseResult->GetParameterString("InputImagesList", i).c_str() << std::endl;
    textFile << parseResult->GetParameterString("InputImagesList", i) << "\n";

    imageReader->UpdateOutputInformation();

    imageList->PushBack(imageReader->GetOutput());
    readerList->PushBack(imageReader);
    }

  textFile.close();

  typedef otb::VectorImage<PixelType, Dimension> VectorImageType;
  typedef otb::ImageListToVectorImageFilter<ImageListType, VectorImageType> ImageListToVectorImageFilterType;
  typename ImageListToVectorImageFilterType::Pointer iL2VI = ImageListToVectorImageFilterType::New();

  iL2VI->SetInput(imageList);

  typedef otb::StreamingImageFileWriter<VectorImageType> ImageWriterType;
  typename ImageWriterType::Pointer imageWriter = ImageWriterType::New();
  imageWriter->SetFileName(parseResult->GetOutputImage().c_str());

  unsigned long size = (10000 * 10000 * sizeof(PixelType)) / NbImages;

  std::cout << "Streaming size: " << size << std::endl;

  imageWriter->SetBufferMemorySize(size);
  imageWriter->SetInput(iL2VI->GetOutput());

  otb::StandardFilterWatcher watcher(imageWriter, "Writing");
  imageWriter->Update();

  return EXIT_SUCCESS;
}

int ConcatenateImages::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("ConcatenateImages");
  descriptor->SetDescription("Concatenate n images in a multiband image");
  descriptor->AddOptionNParams("InputImagesList", "Images list to concatenate", "il", true,ApplicationDescriptor::InputImage);
  descriptor->AddOutputImage();
  descriptor->AddOption("OutputPixelType",
                        "OutputPixelType: unsigned char (1), short int (2), int (3), float (4),"
                        " double (5), unsigned short int (12), unsigned int (13); default 2",
                        "t", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("OutputNameList",
                        "Text file containing the name of the images used to generate the output in the same order",
                        "ot", 1, false,ApplicationDescriptor::String);

  return EXIT_SUCCESS;
}

int ConcatenateImages::Execute(otb::ApplicationOptionsResult* parseResult)
{
  unsigned int type = 2; //default to short int as the original
                         //program

  if (parseResult->IsOptionPresent("OutputPixelType"))
    {
    type = parseResult->GetParameterUInt("OutputPixelType");
    }

  switch (type)
    {
    case 1:
      generic_main_concatenate<unsigned char> (parseResult);
      break;
    case 2:
      generic_main_concatenate<short int> (parseResult);
      break;
    case 3:
      generic_main_concatenate<int> (parseResult);
      break;
    case 4:
      generic_main_concatenate<float> (parseResult);
      break;
    case 5:
      generic_main_concatenate<double> (parseResult);
      break;
    case 12:
      generic_main_concatenate<unsigned short int> (parseResult);
      break;
    case 13:
      generic_main_concatenate<unsigned int> (parseResult);
      break;
    default:
      generic_main_concatenate<unsigned char> (parseResult);
      break;
    }

  return EXIT_SUCCESS;
}
}
<|endoftext|>


<commit_before>#include "snake.h"

//
// Snake implementation
//
Snake::Snake()
{
}

void Snake::reset()
{
    points.clear();
    int d = (rand() % 4) + 1;
    set_direction(d);

    Point p;
    p.x = 0.0f;
    p.y = GROUND_DIFF;
    p.z = 0.0f;

    points.push_front(p);

    grow();
}

void Snake::move()
{
    points.pop_back();
    grow();
}

void Snake::set_direction(int d)
{
    if ((d == DOWN && direction == UP) ||
        (direction == DOWN && d == UP) ||
        (d == LEFT && direction == RIGHT) ||
        (direction == LEFT && d == RIGHT))
    {
        return;
    }

    direction = d;
}

void Snake::draw()
{
     Point h = points[0];

    glColor3f(1.0, 1.0, 0.6);
    glPushMatrix();
        glTranslatef(h.x, h.y, h.z);
        glutSolidCube(0.5f);
    glPopMatrix();

    enable_2D_texture();
    glBindTexture(GL_TEXTURE_2D, textures[SNAKE_TEXTURE]);

    for (size_t i = 1; i < points.size(); ++i)
    {
        Point p = points.at(i);

        glPushMatrix();
            glTranslatef(p.x, p.y, p.z);
            glut2SolidCube(0.5f);
        glPopMatrix();
    }

    disable_2D_texture();
}

Point Snake::head()
{
    return points[0];
}

Point Snake::tail()
{
    return points[points.size() - 1];
}

void Snake::grow(bool back)
{
    Point p;
    p.x = points[0].x;
    p.y = points[0].y;
    p.z = points[0].z;

    switch (direction)
    {
        case DOWN:
            p.z += 0.5f;
        break;
        case UP:
            p.z -= 0.5f;
        break;
        case LEFT:
            p.x -= 0.5f;
        break;
        case RIGHT:
            p.x += 0.5f;
        break;
    }

    if (back)
    {
        points.push_back(p);
    }
    else
    {
        points.push_front(p);
    }
}

bool Snake::has_collision(Point p)
{
    // Skip head. It's the same point.
    for (size_t i = 1; i < points.size(); ++i)
    {
        Point b = points.at(i);

        if (p.x == b.x && p.z == b.z)
        {
            return BARRIER;
        }
    }

    return false;
}

int Snake::size()
{
    return points.size();
}<commit_msg>comment.<commit_after>#include "snake.h"

//
// Snake implementation
//
Snake::Snake()
{
}

void Snake::reset()
{
    points.clear();
    int d = (rand() % 4) + 1;
    set_direction(d);

    Point p;
    p.x = 0.0f;
    p.y = GROUND_DIFF;
    p.z = 0.0f;

    points.push_front(p);

    grow();
}

void Snake::move()
{
    points.pop_back();
    grow();
}

void Snake::set_direction(int d)
{
    if ((d == DOWN && direction == UP) ||
        (direction == DOWN && d == UP) ||
        (d == LEFT && direction == RIGHT) ||
        (direction == LEFT && d == RIGHT))
    {
        return;
    }

    direction = d;
}

void Snake::draw()
{
    // TODO: Draw cylindric snake.
    // It's more hard.
    // Use glut2Cylinder.
    Point h = points[0];

    glColor3f(1.0, 1.0, 0.6);
    glPushMatrix();
        glTranslatef(h.x, h.y, h.z);
        glutSolidCube(0.5f);
    glPopMatrix();

    enable_2D_texture();
    glBindTexture(GL_TEXTURE_2D, textures[SNAKE_TEXTURE]);

    for (size_t i = 1; i < points.size(); ++i)
    {
        Point p = points.at(i);

        glPushMatrix();
            glTranslatef(p.x, p.y, p.z);
            glut2SolidCube(0.5f);
        glPopMatrix();
    }

    disable_2D_texture();
}

Point Snake::head()
{
    return points[0];
}

Point Snake::tail()
{
    return points[points.size() - 1];
}

void Snake::grow(bool back)
{
    Point p;
    p.x = points[0].x;
    p.y = points[0].y;
    p.z = points[0].z;

    switch (direction)
    {
        case DOWN:
            p.z += 0.5f;
        break;
        case UP:
            p.z -= 0.5f;
        break;
        case LEFT:
            p.x -= 0.5f;
        break;
        case RIGHT:
            p.x += 0.5f;
        break;
    }

    if (back)
    {
        points.push_back(p);
    }
    else
    {
        points.push_front(p);
    }
}

bool Snake::has_collision(Point p)
{
    // Skip head. It's the same point.
    for (size_t i = 1; i < points.size(); ++i)
    {
        Point b = points.at(i);

        if (p.x == b.x && p.z == b.z)
        {
            return BARRIER;
        }
    }

    return false;
}

int Snake::size()
{
    return points.size();
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fuvect.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2004-01-06 18:46:08 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif
#ifndef _SVDOPATH_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SVX_SVDOGRAF_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SVX_SVDEDTV_HXX //autogen
#include <svx/svdedtv.hxx>
#endif

#pragma hdrstop

#include "sdview.hxx"
#include "viewshel.hxx"
#include "strings.hrc"
#include "sdresid.hxx"
#include "vectdlg.hxx"
#include "fuvect.hxx"

TYPEINIT1( FuVectorize, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuVectorize::FuVectorize( SdViewShell* pViewSh, SdWindow* pWin, SdView* pView,
                          SdDrawDocument* pDoc, SfxRequest& rReq ) :
            FuPoor (pViewSh, pWin, pView, pDoc, rReq)
{
    const SdrMarkList& rMarkList = pView->GetMarkList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

        if( pObj && pObj->ISA( SdrGrafObj ) )
        {
            SdVectorizeDlg aDlg( (Window*) pWin, ( (SdrGrafObj*) pObj )->GetGraphic().GetBitmap(), pDocSh );

            if( aDlg.Execute() == RET_OK )
            {
                const GDIMetaFile&  rMtf = aDlg.GetGDIMetaFile();
                SdrPageView*        pPageView = pView->GetPageViewPvNum( 0 );

                if( pPageView && rMtf.GetActionCount() )
                {
                    SdrGrafObj* pVectObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetMarkDescription() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( SdResId( STR_UNDO_VECTORIZE ) ) );
                    pView->BegUndo( aStr );
                    pVectObj->SetGraphic( rMtf );
                    pView->ReplaceObject( pObj, *pPageView, pVectObj );
                    pView->EndUndo();
                }
            }
        }
    }
}

<commit_msg>INTEGRATION: CWS impress1 (1.1.1.1.262); FILE MERGED 2003/09/17 09:02:40 af 1.1.1.1.262.1: #111996# Transition to stacked sub-shells. Introduction of namespace sd.<commit_after>/*************************************************************************
 *
 *  $RCSfile: fuvect.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2004-01-20 13:42:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "fuvect.hxx"

#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif
#ifndef _SVDOPATH_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SVX_SVDOGRAF_HXX //autogen
#include <svx/svdograf.hxx>
#endif
#ifndef _SVX_SVDEDTV_HXX //autogen
#include <svx/svdedtv.hxx>
#endif

#pragma hdrstop

#ifndef SD_VIEW_HXX
#include "View.hxx"
#endif
#ifndef SD_VIEW_SHELL_HXX
#include "ViewShell.hxx"
#endif
#ifndef SD_WINDOW_HXX
#include "Window.hxx"
#endif
#include "strings.hrc"
#include "sdresid.hxx"
#include "vectdlg.hxx"

namespace sd {

TYPEINIT1( FuVectorize, FuPoor );

/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

FuVectorize::FuVectorize (
    ViewShell* pViewSh,
    ::sd::Window* pWin,
    ::sd::View* pView,
    SdDrawDocument* pDoc,
    SfxRequest& rReq)
    : FuPoor (pViewSh, pWin, pView, pDoc, rReq)
{
    const SdrMarkList& rMarkList = pView->GetMarkList();

    if( rMarkList.GetMarkCount() == 1 )
    {
        SdrObject* pObj = rMarkList.GetMark( 0 )->GetObj();

        if( pObj && pObj->ISA( SdrGrafObj ) )
        {
            SdVectorizeDlg aDlg(pWin, ( (SdrGrafObj*) pObj )->GetGraphic().GetBitmap(), pDocSh );

            if( aDlg.Execute() == RET_OK )
            {
                const GDIMetaFile&  rMtf = aDlg.GetGDIMetaFile();
                SdrPageView*        pPageView = pView->GetPageViewPvNum( 0 );

                if( pPageView && rMtf.GetActionCount() )
                {
                    SdrGrafObj* pVectObj = (SdrGrafObj*) pObj->Clone();
                    String      aStr( pView->GetMarkDescription() );

                    aStr.Append( sal_Unicode(' ') );
                    aStr.Append( String( SdResId( STR_UNDO_VECTORIZE ) ) );
                    pView->BegUndo( aStr );
                    pVectObj->SetGraphic( rMtf );
                    pView->ReplaceObject( pObj, *pPageView, pVectObj );
                    pView->EndUndo();
                }
            }
        }
    }
}

} // end of namespace sd
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlgpage.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 17:42:32 $
 *
 *  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 _SD_DLGPAGE_HXX
#define _SD_DLGPAGE_HXX

#ifndef _SFXTABDLG_HXX //autogen
#include <sfx2/tabdlg.hxx>
#endif
#include "dlgpage.hrc"

class SfxObjectShell;
class XColorTable;
class XGradientList;
class XHatchList;
class XBitmapList;

typedef USHORT ChangeType;

/*************************************************************************
|*
|* Seite einrichten-Tab-Dialog
|*
\************************************************************************/
class SdPageDlg : public SfxTabDialog
{
private:
    const SfxItemSet&   mrOutAttrs;

    const SfxObjectShell* mpDocShell;

    XColorTable*        mpColorTab;
    XGradientList*      mpGradientList;
    XHatchList*         mpHatchingList;
    XBitmapList*        mpBitmapList;
public:

    SdPageDlg( SfxObjectShell* pDocSh, Window* pParent, const SfxItemSet* pAttr, BOOL bAreaPage = TRUE );
    ~SdPageDlg() {};

    virtual void PageCreated(USHORT nId, SfxTabPage& rPage);
};

#endif // _SD_DLGPAGE_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.3.298); FILE MERGED 2008/04/01 15:35:21 thb 1.3.298.2: #i85898# Stripping all external header guards 2008/03/31 13:58:13 rt 1.3.298.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: dlgpage.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 _SD_DLGPAGE_HXX
#define _SD_DLGPAGE_HXX

#include <sfx2/tabdlg.hxx>
#include "dlgpage.hrc"

class SfxObjectShell;
class XColorTable;
class XGradientList;
class XHatchList;
class XBitmapList;

typedef USHORT ChangeType;

/*************************************************************************
|*
|* Seite einrichten-Tab-Dialog
|*
\************************************************************************/
class SdPageDlg : public SfxTabDialog
{
private:
    const SfxItemSet&   mrOutAttrs;

    const SfxObjectShell* mpDocShell;

    XColorTable*        mpColorTab;
    XGradientList*      mpGradientList;
    XHatchList*         mpHatchingList;
    XBitmapList*        mpBitmapList;
public:

    SdPageDlg( SfxObjectShell* pDocSh, Window* pParent, const SfxItemSet* pAttr, BOOL bAreaPage = TRUE );
    ~SdPageDlg() {};

    virtual void PageCreated(USHORT nId, SfxTabPage& rPage);
};

#endif // _SD_DLGPAGE_HXX

<|endoftext|>