<commit_before>/* This file is part of Ingen.
 * Copyright (C) 2008-2009 Dave Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen 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 General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <list>
#include <cassert>
#include <cstring>
#include <sstream>
#include <sys/socket.h>
#include <errno.h>
#include "raul/log.hpp"
#include "raul/Atom.hpp"
#include "module/Module.hpp"
#include "module/World.hpp"
#include "HTTPClientReceiver.hpp"

#define LOG(s) s << "[HTTPClientReceiver] "

using namespace std;
using namespace Raul;

namespace Ingen {

using namespace Serialisation;

namespace Client {

static SoupSession*        client_session  = NULL;
static HTTPClientReceiver* client_receiver = NULL;

HTTPClientReceiver::HTTPClientReceiver(
		Shared::World*                     world,
		const std::string&                 url,
		SharedPtr<Shared::ClientInterface> target)
	: _target(target)
	, _world(world)
	, _url(url)
{
	start(false);
	client_receiver = this;
}

HTTPClientReceiver::~HTTPClientReceiver()
{
	stop();
	if (client_receiver == this)
		client_receiver = NULL;
}

HTTPClientReceiver::Listener::Listener(HTTPClientReceiver* receiver, const std::string uri)
	: _uri(uri)
	, _receiver(receiver)
{
	const string port_str = uri.substr(uri.find_last_of(":")+1);
	int port = atoi(port_str.c_str());

	LOG(info) << "Client HTTP listen: " << uri << " (port " << port << ")" << endl;

	struct sockaddr_in servaddr;

	// Create listen address
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_port        = htons(port);

	// Create listen socket
	if ((_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		LOG(error) << "Error creating listening socket: %s" << strerror(errno) << endl;
		_sock = -1;
		return;
	}

	// Set remote address (FIXME: always localhost)
	if (inet_aton("127.0.0.1", &servaddr.sin_addr) <= 0) {
		LOG(error) << "Invalid remote IP address" << endl;
		_sock = -1;
		return;
	}

	// Connect to server
	if (connect(_sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
		LOG(error) << "Error calling connect: " << strerror(errno) << endl;
		_sock = -1;
		return;
	}
}

HTTPClientReceiver::Listener::~Listener()
{
	close(_sock);
}

void
HTTPClientReceiver::send(SoupMessage* msg)
{
	if (!client_session) {
		LOG(debug) << "Starting session" << endl;
		client_session = soup_session_sync_new();
	}

	assert(SOUP_IS_MESSAGE(msg));
	soup_session_queue_message(client_session, msg, message_callback, client_receiver);
}

void
HTTPClientReceiver::close_session()
{
	if (client_session) {
		SoupSession* s = client_session;
		client_session = NULL;
		soup_session_abort(s);
	}
}

void
HTTPClientReceiver::update(const std::string& str)
{
	LOG(info) << _world->parser->parse_update(_world, _target.get(), str, _url);
}

void
HTTPClientReceiver::Listener::_run()
{
	char   in    = '\0';
	char   last  = '\0';
	char   llast = '\0';
	string recv  = "";

	while (true) {
		while (read(_sock, &in, 1) > 0 ) {
			recv += in;
			if (in == '\n' && last == '\n' && llast == '\n') {
				if (recv != "") {
					_receiver->update(recv);
					recv = "";
					last = '\0';
					llast = '\0';
				}
				break;
			}
			llast = last;
			last = in;
		}
	}

	LOG(info) << "HTTP listener finished" << endl;
}

void
HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, void* ptr)
{
	if (ptr == NULL)
		return;

	HTTPClientReceiver* me = (HTTPClientReceiver*)ptr;
	const string path = soup_message_get_uri(msg)->path;

	/*LOG(debug) << path << endl
			<< msg->response_body->data << endl;*/

	if (msg->response_body->data == NULL) {
		LOG(error) << "Empty client message" << endl;
		return;
	}

	if (path == Path::root.str()) {
		me->_target->response_ok(0);

	} else if (path == "/plugins") {
		if (msg->response_body->data == NULL) {
			LOG(error) << "Empty response" << endl;
		} else {
			Glib::Mutex::Lock lock(me->_mutex);
			me->_target->response_ok(0);
			me->_world->parser->parse_string(me->_world, me->_target.get(),
					Glib::ustring(msg->response_body->data), me->_url);
		}

	} else if (path == "/patch") {
		if (msg->response_body->data == NULL) {
			LOG(error) << "Empty response" << endl;
		} else {
			Glib::Mutex::Lock lock(me->_mutex);
			me->_target->response_ok(0);
			me->_world->parser->parse_string(me->_world, me->_target.get(),
					Glib::ustring(msg->response_body->data),
					Glib::ustring("/patch/"));
		}

	} else if (path == "/stream") {
		if (msg->response_body->data == NULL) {
			LOG(error) << "Empty response" << endl;
		} else {
			Glib::Mutex::Lock lock(me->_mutex);
			string uri = string(soup_uri_to_string(soup_message_get_uri(msg), false));
			uri = uri.substr(0, uri.find_last_of(":"));
			uri += string(":") + msg->response_body->data;
			LOG(info) << "Stream URI: " << uri << endl;
			me->_listener = boost::shared_ptr<Listener>(new Listener(me, uri));
			me->_listener->start();
		}

	} else {
		LOG(error) << "Unknown message: " << path << endl;
		me->update(msg->response_body->data);
	}
}

void
HTTPClientReceiver::start(bool dump)
{
	Glib::Mutex::Lock lock(_world->rdf_world->mutex());

	if (!_world->parser)
		_world->load("ingen_serialisation");

	SoupMessage* msg = soup_message_new("GET", (_url + "/stream").c_str());
	assert(SOUP_IS_MESSAGE(msg));
	soup_session_queue_message(client_session, msg, message_callback, this);
}

void
HTTPClientReceiver::stop()
{
	//unregister_client();
	close_session();
}

} // namespace Client
} // namespace Ingen

<commit_msg>Fix connecting via HTTP (partially, GUI shows up at least...).<commit_after>/* This file is part of Ingen.
 * Copyright (C) 2008-2009 Dave Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen 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 General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <list>
#include <cassert>
#include <cstring>
#include <sstream>
#include <sys/socket.h>
#include <errno.h>
#include "raul/log.hpp"
#include "raul/Atom.hpp"
#include "module/Module.hpp"
#include "module/World.hpp"
#include "HTTPClientReceiver.hpp"

#define LOG(s) s << "[HTTPClientReceiver] "

using namespace std;
using namespace Raul;

namespace Ingen {

using namespace Serialisation;

namespace Client {

static SoupSession*        client_session  = NULL;
static HTTPClientReceiver* client_receiver = NULL;

HTTPClientReceiver::HTTPClientReceiver(
		Shared::World*                     world,
		const std::string&                 url,
		SharedPtr<Shared::ClientInterface> target)
	: _target(target)
	, _world(world)
	, _url(url)
{
	start(false);
	client_receiver = this;
}

HTTPClientReceiver::~HTTPClientReceiver()
{
	stop();
	if (client_receiver == this)
		client_receiver = NULL;
}

HTTPClientReceiver::Listener::Listener(HTTPClientReceiver* receiver, const std::string uri)
	: _uri(uri)
	, _receiver(receiver)
{
	const string port_str = uri.substr(uri.find_last_of(":")+1);
	int port = atoi(port_str.c_str());

	LOG(info) << "Client HTTP listen: " << uri << " (port " << port << ")" << endl;

	struct sockaddr_in servaddr;

	// Create listen address
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family      = AF_INET;
	servaddr.sin_port        = htons(port);

	// Create listen socket
	if ((_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		LOG(error) << "Error creating listening socket: %s" << strerror(errno) << endl;
		_sock = -1;
		return;
	}

	// Set remote address (FIXME: always localhost)
	if (inet_aton("127.0.0.1", &servaddr.sin_addr) <= 0) {
		LOG(error) << "Invalid remote IP address" << endl;
		_sock = -1;
		return;
	}

	// Connect to server
	if (connect(_sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
		LOG(error) << "Error calling connect: " << strerror(errno) << endl;
		_sock = -1;
		return;
	}
}

HTTPClientReceiver::Listener::~Listener()
{
	close(_sock);
}

void
HTTPClientReceiver::send(SoupMessage* msg)
{
	if (!client_session) {
		LOG(debug) << "Starting session" << endl;
		client_session = soup_session_sync_new();
	}

	assert(SOUP_IS_MESSAGE(msg));
	soup_session_queue_message(client_session, msg, message_callback, client_receiver);
}

void
HTTPClientReceiver::close_session()
{
	if (client_session) {
		SoupSession* s = client_session;
		client_session = NULL;
		soup_session_abort(s);
	}
}

void
HTTPClientReceiver::update(const std::string& str)
{
	LOG(info) << _world->parser->parse_update(_world, _target.get(), str, _url);
}

void
HTTPClientReceiver::Listener::_run()
{
	char   in    = '\0';
	char   last  = '\0';
	char   llast = '\0';
	string recv  = "";

	while (true) {
		while (read(_sock, &in, 1) > 0 ) {
			recv += in;
			if (in == '\n' && last == '\n' && llast == '\n') {
				if (recv != "") {
					_receiver->update(recv);
					recv = "";
					last = '\0';
					llast = '\0';
				}
				break;
			}
			llast = last;
			last = in;
		}
	}

	LOG(info) << "HTTP listener finished" << endl;
}

void
HTTPClientReceiver::message_callback(SoupSession* session, SoupMessage* msg, void* ptr)
{
	if (ptr == NULL)
		return;

	HTTPClientReceiver* me = (HTTPClientReceiver*)ptr;
	const string path = soup_message_get_uri(msg)->path;

	if (msg->response_body->data == NULL) {
		LOG(error) << "Empty client message" << endl;
		return;
	}

	if (path == "/") {
		me->_target->response_ok(0);

	} else if (path == "/plugins") {
		if (msg->response_body->data == NULL) {
			LOG(error) << "Empty response" << endl;
		} else {
			Glib::Mutex::Lock lock(me->_mutex);
			me->_target->response_ok(0);
			me->_world->parser->parse_string(me->_world, me->_target.get(),
					Glib::ustring(msg->response_body->data), me->_url);
		}

	} else if (path == "/patch") {
		if (msg->response_body->data == NULL) {
			LOG(error) << "Empty response" << endl;
		} else {
			Glib::Mutex::Lock lock(me->_mutex);
			me->_target->response_ok(0);
			me->_world->parser->parse_string(me->_world, me->_target.get(),
					Glib::ustring(msg->response_body->data),
					Glib::ustring("/patch/"));
		}

	} else if (path == "/stream") {
		if (msg->response_body->data == NULL) {
			LOG(error) << "Empty response" << endl;
		} else {
			Glib::Mutex::Lock lock(me->_mutex);
			string uri = string(soup_uri_to_string(soup_message_get_uri(msg), false));
			uri = uri.substr(0, uri.find_last_of(":"));
			uri += string(":") + msg->response_body->data;
			LOG(info) << "Stream URI: " << uri << endl;
			me->_listener = boost::shared_ptr<Listener>(new Listener(me, uri));
			me->_listener->start();
		}

	} else {
		LOG(error) << "Unknown message: " << path << endl;
		me->update(msg->response_body->data);
	}
}

void
HTTPClientReceiver::start(bool dump)
{
	Glib::Mutex::Lock lock(_world->rdf_world->mutex());

	if (!_world->parser)
		_world->load("ingen_serialisation");

	SoupMessage* msg = soup_message_new("GET", (_url + "/stream").c_str());
	assert(SOUP_IS_MESSAGE(msg));
	soup_session_queue_message(client_session, msg, message_callback, this);
}

void
HTTPClientReceiver::stop()
{
	//unregister_client();
	close_session();
}

} // namespace Client
} // namespace Ingen

<|endoftext|>


<commit_before>// Copyright 2010-2012 Google
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <math.h>
#include <string.h>
#include <algorithm>
#include "base/hash.h"
#include <string>
#include <utility>
#include <vector>

#include "base/commandlineflags.h"
#include "base/hash.h"
#include "base/int-type-indexed-vector.h"
#include "base/int-type.h"
#include "base/integral_types.h"
#include "base/logging.h"
#include "base/map-util.h"
#include "base/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
#include "constraint_solver/constraint_solver.h"
#include "constraint_solver/constraint_solveri.h"
#include "util/bitset.h"
#include "util/const_int_array.h"

#include "core/Solver.cc"

namespace operations_research {
namespace {

class SatPropagator : public Constraint {
 public:
  SatPropagator(Solver* const solver) : Constraint(solver) {}

  ~SatPropagator() {}

  bool Check(IntExpr* const expr) const {
    IntVar* expr_var = NULL;
    bool expr_negated = false;
    return solver()->IsBooleanVar(expr, &expr_var, &expr_negated);
  }

  bool Check(const std::vector<IntVar*>& vars) const {
    for (int i = 0; i < vars.size(); ++i) {
      if (!Check(vars[i])) {
        return false;
      }
    }
    return true;
  }

  Minisat::Lit Literal(IntExpr* const expr) {
    IntVar* expr_var = NULL;
    bool expr_negated = false;
    if (!solver()->IsBooleanVar(expr, &expr_var, &expr_negated)) {
      return Minisat::lit_Error;
    }
    if (ContainsKey(indices_, expr_var)) {
      return Minisat::mkLit(indices_[expr_var], expr_negated);
    } else {
      const Minisat::Var var = minisat_.newVar(true, true);
      vars_.push_back(expr_var);
      return Minisat::mkLit(var, expr_negated);
    }
  }

  void VariableBound(int index) {
    // if (indices_[index]->Min() == 0) {
    //   Flip(Minisat::Var(-1 - index));
    // } else {
    //   Flip(Minisat::Var(1 + index));
    // }
  }

  virtual void Post() {
    for (int i = 0; i < vars_.size(); ++i) {
      Demon* const d = MakeConstraintDemon1(solver(),
                                            this,
                                            &SatPropagator::VariableBound,
                                            "VariableBound",
                                            indices_[vars_[i]]);
      vars_[i]->WhenDomain(d);
    }
  }

  virtual void InitialPropagate() {
    for (int i = 0; i < vars_.size(); ++i) {
      IntVar* const var = vars_[i];
      if (var->Bound()) {
        VariableBound(indices_[var]);
      }
    }
  }

  // Add a clause to the solver.
  bool AddClause (const vec<Lit>& ps) {
    return minisat_.addClause(ps);
  }

  // Add the empty clause, making the solver contradictory.
  bool AddEmptyClause() {
    return minisat_.addEmptyClause();
  }

  // Add a unit clause to the solver.
  bool AddClause (Lit p) {
    return minisat_.addClause(p);
  }

  // Add a binary clause to the solver.
  bool AddClause (Lit p, Lit q) {
    return minisat_.addClause(p, q);
  }

  // Add a ternary clause to the solver.
  bool AddClause (Lit p, Lit q, Lit r) {
    return minisat_.addClause(p, q, r);
  }

 private:
  Minisat::Solver minisat_;
  std::vector<IntVar*> vars_;
  hash_map<IntVar*, Minisat::Var> indices_;
};
}  // namespace

bool AddBoolEq(SatPropagator* const sat,
               IntExpr* const left,
               IntExpr* const right) {
  if (!sat->Check(left) || !sat->Check(right)) {
    return false;
  }
  Minisat::Lit left_lit = sat->Literal(left);
  Minisat::Lit right_lit = sat->Literal(right);

  return true;
}

bool AddBoolLe(SatPropagator* const sat, IntExpr* const left, IntExpr* const right) {
  if (!sat->Check(left) || !sat->Check(right)) {
    return false;
  }
  Minisat::Lit left_lit = sat->Literal(left);
  Minisat::Lit right_lit = sat->Literal(right);
  // sat->AddFlipAction(left_lit, right_lit);
  // sat->AddFlipAction(-right_lit, -left_lit);
  return true;
}

bool AddBoolNot(SatPropagator* const sat, IntExpr* const left, IntExpr* const right) {
  if (!sat->Check(left) || !sat->Check(right)) {
    return false;
  }
  Minisat::Lit left_lit = sat->Literal(left);
  Minisat::Lit right_lit = sat->Literal(right);
  // sat->AddFlipAction(left_lit, -right_lit);
  // sat->AddFlipAction(right_lit, -left_lit);
  // sat->AddFlipAction(-left_lit, right_lit);
  // sat->AddFlipAction(-right_lit, left_lit);
  return true;
}

bool AddBoolAndArrayEqVar(SatPropagator* const sat,
                          const std::vector<IntVar*>& vars,
                          IntVar* const target) {
  return false;

}

bool AddBoolOrArrayEqualTrue(SatPropagator* const sat,
                             const std::vector<IntVar*>& vars) {
  if (!sat->Check(vars)) {
    return false;
  }
  std::vector<Minisat::Lit> atoms(vars.size());
  for (int i = 0; i < vars.size(); ++i) {
    atoms[i] = sat->Literal(vars[i]);
  }
  return false;
}
}  // namespace operations_research
<commit_msg>more integration with the minisat<commit_after>// Copyright 2010-2012 Google
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <math.h>
#include <string.h>
#include <algorithm>
#include "base/hash.h"
#include <string>
#include <utility>
#include <vector>

#include "base/commandlineflags.h"
#include "base/hash.h"
#include "base/int-type-indexed-vector.h"
#include "base/int-type.h"
#include "base/integral_types.h"
#include "base/logging.h"
#include "base/map-util.h"
#include "base/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
#include "constraint_solver/constraint_solver.h"
#include "constraint_solver/constraint_solveri.h"
#include "util/bitset.h"
#include "util/const_int_array.h"

#include "core/Solver.cc"

namespace operations_research {
namespace {

class SatPropagator : public Constraint {
 public:
  SatPropagator(Solver* const solver) : Constraint(solver) {}

  ~SatPropagator() {}

  bool Check(IntExpr* const expr) const {
    IntVar* expr_var = NULL;
    bool expr_negated = false;
    return solver()->IsBooleanVar(expr, &expr_var, &expr_negated);
  }

  bool Check(const std::vector<IntVar*>& vars) const {
    for (int i = 0; i < vars.size(); ++i) {
      if (!Check(vars[i])) {
        return false;
      }
    }
    return true;
  }

  Minisat::Lit Literal(IntExpr* const expr) {
    IntVar* expr_var = NULL;
    bool expr_negated = false;
    if (!solver()->IsBooleanVar(expr, &expr_var, &expr_negated)) {
      return Minisat::lit_Error;
    }
    if (ContainsKey(indices_, expr_var)) {
      return Minisat::mkLit(indices_[expr_var], expr_negated);
    } else {
      const Minisat::Var var = minisat_.newVar(true, true);
      vars_.push_back(expr_var);
      return Minisat::mkLit(var, expr_negated);
    }
  }

  void VariableBound(int index) {
    // if (indices_[index]->Min() == 0) {
    //   Flip(Minisat::Var(-1 - index));
    // } else {
    //   Flip(Minisat::Var(1 + index));
    // }
  }

  virtual void Post() {
    for (int i = 0; i < vars_.size(); ++i) {
      Demon* const d = MakeConstraintDemon1(solver(),
                                            this,
                                            &SatPropagator::VariableBound,
                                            "VariableBound",
                                            indices_[vars_[i]]);
      vars_[i]->WhenDomain(d);
    }
  }

  virtual void InitialPropagate() {
    for (int i = 0; i < vars_.size(); ++i) {
      IntVar* const var = vars_[i];
      if (var->Bound()) {
        VariableBound(indices_[var]);
      }
    }
  }

  // Add a clause to the solver.
  bool AddClause (const vec<Lit>& ps) {
    return minisat_.addClause(ps);
  }

  // Add the empty clause, making the solver contradictory.
  bool AddEmptyClause() {
    return minisat_.addEmptyClause();
  }

  // Add a unit clause to the solver.
  bool AddClause (Lit p) {
    return minisat_.addClause(p);
  }

  // Add a binary clause to the solver.
  bool AddClause (Lit p, Lit q) {
    return minisat_.addClause(p, q);
  }

  // Add a ternary clause to the solver.
  bool AddClause (Lit p, Lit q, Lit r) {
    return minisat_.addClause(p, q, r);
  }

 private:
  Minisat::Solver minisat_;
  std::vector<IntVar*> vars_;
  hash_map<IntVar*, Minisat::Var> indices_;
};
}  // namespace

bool AddBoolEq(SatPropagator* const sat,
               IntExpr* const left,
               IntExpr* const right) {
  if (!sat->Check(left) || !sat->Check(right)) {
    return false;
  }
  Minisat::Lit left_lit = sat->Literal(left);
  Minisat::Lit right_lit = sat->Literal(right);
  sat->AddClause(~left_lit, right_lit);
  sat->AddClause(left_lit, ~right_lit);
  return true;
}

bool AddBoolLe(SatPropagator* const sat,
               IntExpr* const left,
               IntExpr* const right) {
  if (!sat->Check(left) || !sat->Check(right)) {
    return false;
  }
  Minisat::Lit left_lit = sat->Literal(left);
  Minisat::Lit right_lit = sat->Literal(right);
  sat->AddClause(~left_lit, right_lit);
  return true;
}

bool AddBoolNot(SatPropagator* const sat,
                IntExpr* const left,
                IntExpr* const right) {
  if (!sat->Check(left) || !sat->Check(right)) {
    return false;
  }
  Minisat::Lit left_lit = sat->Literal(left);
  Minisat::Lit right_lit = sat->Literal(right);
  sat->AddClause(~left_lit, ~right_lit);
  sat->AddClause(left_lit, right_lit);
  return true;
}

bool AddBoolAndArrayEqVar(SatPropagator* const sat,
                          const std::vector<IntVar*>& vars,
                          IntVar* const target) {
  return false;

}

bool AddBoolOrArrayEqualTrue(SatPropagator* const sat,
                             const std::vector<IntVar*>& vars) {
  if (!sat->Check(vars)) {
    return false;
  }
  std::vector<Minisat::Lit> atoms(vars.size());
  for (int i = 0; i < vars.size(); ++i) {
    atoms[i] = sat->Literal(vars[i]);
  }
  return false;
}
}  // namespace operations_research
<|endoftext|>


<commit_before>#define MS_CLASS "RTC::RtpStreamRecv"
// #define MS_LOG_DEV

#include "RTC/RtpStreamRecv.h"
#include "DepLibUV.h"
#include "Logger.h"

namespace RTC
{
	/* Instance methods. */

	RtpStreamRecv::RtpStreamRecv(uint32_t clockRate) :
		RtpStream::RtpStream(clockRate)
	{
		MS_TRACE();
	}

	RtpStreamRecv::~RtpStreamRecv()
	{
		MS_TRACE();
	}

	bool RtpStreamRecv::ReceivePacket(RTC::RtpPacket* packet)
	{
		MS_TRACE();

		// Call the parent method.
		if (!RtpStream::ReceivePacket(packet))
			return false;

		// Calculate Jitter.
		CalculateJitter(packet->GetTimestamp());

		return true;
	}

	RTC::RTCP::ReceiverReport* RtpStreamRecv::GetRtcpReceiverReport()
	{
		RTC::RTCP::ReceiverReport* report = new RTC::RTCP::ReceiverReport();

		// Calculate Packets Expected and Lost.
		uint32_t expected = (this->cycles + this->max_seq) - this->base_seq + 1;
		int32_t total_lost = expected - this->received;

		report->SetTotalLost(total_lost);

		// Calculate Fraction Lost.
		uint32_t expected_interval = expected - this->expected_prior;

		this->expected_prior = expected;

		uint32_t received_interval = this->received - this->received_prior;

		this->received_prior = this->received;

		int32_t lost_interval = expected_interval - received_interval;
		uint8_t fraction_lost;

		if (expected_interval == 0 || lost_interval <= 0)
			fraction_lost = 0;
		else
			fraction_lost = (lost_interval << 8) / expected_interval;

		report->SetFractionLost(fraction_lost);

		// Fill the rest of the report.
		report->SetLastSeq((uint32_t)this->max_seq + this->cycles);
		report->SetJitter(this->jitter);

		if (this->last_sr_received)
		{
			// Get delay in milliseconds.
			uint32_t delayMs = (DepLibUV::GetTime() - this->last_sr_received);

			// Express delay in units of 1/65536 seconds.
			uint32_t dlsr = (delayMs / 1000) << 16;
			dlsr |= (uint32_t)((delayMs % 1000) * 65536 / 1000);

			report->SetDelaySinceLastSenderReport(dlsr);
			report->SetLastSenderReport(this->last_sr_timestamp);
		}
		else
		{
			report->SetDelaySinceLastSenderReport(0);
			report->SetLastSenderReport(0);
		}

		return report;
	}

	void RtpStreamRecv::ReceiveRtcpSenderReport(RTC::RTCP::SenderReport* report)
	{
		this->last_sr_received = DepLibUV::GetTime();
		this->last_sr_timestamp = htonl(report->GetNtpSec()) << 16;
		this->last_sr_timestamp += htonl(report->GetNtpFrac()) >> 16;
	}

	void RtpStreamRecv::CalculateJitter(uint32_t rtpTimestamp)
	{
		if (!this->clockRate)
			return;

		int transit = DepLibUV::GetTime() - (rtpTimestamp * 1000 / this->clockRate);
		int d = transit - this->transit;

		this->transit = transit;
		if (d < 0) d = -d;
		this->jitter += (1./16.) * ((double)d - this->jitter);
	}
}
<commit_msg>rtcp: properly create lsr field out of Sender Report<commit_after>#define MS_CLASS "RTC::RtpStreamRecv"
// #define MS_LOG_DEV

#include "RTC/RtpStreamRecv.h"
#include "DepLibUV.h"
#include "Logger.h"

namespace RTC
{
	/* Instance methods. */

	RtpStreamRecv::RtpStreamRecv(uint32_t clockRate) :
		RtpStream::RtpStream(clockRate)
	{
		MS_TRACE();
	}

	RtpStreamRecv::~RtpStreamRecv()
	{
		MS_TRACE();
	}

	bool RtpStreamRecv::ReceivePacket(RTC::RtpPacket* packet)
	{
		MS_TRACE();

		// Call the parent method.
		if (!RtpStream::ReceivePacket(packet))
			return false;

		// Calculate Jitter.
		CalculateJitter(packet->GetTimestamp());

		return true;
	}

	RTC::RTCP::ReceiverReport* RtpStreamRecv::GetRtcpReceiverReport()
	{
		RTC::RTCP::ReceiverReport* report = new RTC::RTCP::ReceiverReport();

		// Calculate Packets Expected and Lost.
		uint32_t expected = (this->cycles + this->max_seq) - this->base_seq + 1;
		int32_t total_lost = expected - this->received;

		report->SetTotalLost(total_lost);

		// Calculate Fraction Lost.
		uint32_t expected_interval = expected - this->expected_prior;

		this->expected_prior = expected;

		uint32_t received_interval = this->received - this->received_prior;

		this->received_prior = this->received;

		int32_t lost_interval = expected_interval - received_interval;
		uint8_t fraction_lost;

		if (expected_interval == 0 || lost_interval <= 0)
			fraction_lost = 0;
		else
			fraction_lost = (lost_interval << 8) / expected_interval;

		report->SetFractionLost(fraction_lost);

		// Fill the rest of the report.
		report->SetLastSeq((uint32_t)this->max_seq + this->cycles);
		report->SetJitter(this->jitter);

		if (this->last_sr_received)
		{
			// Get delay in milliseconds.
			uint32_t delayMs = (DepLibUV::GetTime() - this->last_sr_received);

			// Express delay in units of 1/65536 seconds.
			uint32_t dlsr = (delayMs / 1000) << 16;
			dlsr |= (uint32_t)((delayMs % 1000) * 65536 / 1000);

			report->SetDelaySinceLastSenderReport(dlsr);
			report->SetLastSenderReport(this->last_sr_timestamp);
		}
		else
		{
			report->SetDelaySinceLastSenderReport(0);
			report->SetLastSenderReport(0);
		}

		return report;
	}

	void RtpStreamRecv::ReceiveRtcpSenderReport(RTC::RTCP::SenderReport* report)
	{
		this->last_sr_received = DepLibUV::GetTime();
		this->last_sr_timestamp = report->GetNtpSec() << 16;
		this->last_sr_timestamp += report->GetNtpFrac() >> 16;
	}

	void RtpStreamRecv::CalculateJitter(uint32_t rtpTimestamp)
	{
		if (!this->clockRate)
			return;

		int transit = DepLibUV::GetTime() - (rtpTimestamp * 1000 / this->clockRate);
		int d = transit - this->transit;

		this->transit = transit;
		if (d < 0) d = -d;
		this->jitter += (1./16.) * ((double)d - this->jitter);
	}
}
<|endoftext|>


<commit_before>#include <cassert>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <gtest/gtest.h>
#include <nonstd/optional.hpp>

#include "xchainer/array.h"
#include "xchainer/backend.h"
#include "xchainer/backprop.h"
#include "xchainer/device.h"
#include "xchainer/error.h"
#include "xchainer/native_backend.h"
#include "xchainer/native_device.h"
#include "xchainer/testing/context_session.h"

namespace xchainer {
namespace {

// Test configuration class
class TestConfig {
public:
    // backend <0> can transfer from backend <1> to backend <2>
    using Key = std::tuple<int, int, int>;

    TestConfig() {
        set_.insert({
            Key{0, 0, 0},  // backend0 can transfer with itself
            Key{0, 0, 1},  // backend0 can transfer to backend1
            Key{0, 2, 0},  // backend0 can transfer from backend2
                           // backend0 and backend3 are incompatible
        });
    }

    // Returns true if the backend `who` can transfer data from backend `from` to backend `to`
    bool CanTransfer(int who, int from, int to) { return set_.find(std::make_tuple(who, from, to)) != set_.end(); }

    // Return the number of test backends
    int num_backends() { return 4; }

private:
    std::set<Key> set_;
};

// Instantiate the global test configuration
static TestConfig g_config;

// Test backend class
class TestBackend : public NativeBackend {
public:
    TestBackend(Context& context, int num) : NativeBackend(context), num_(num) {}

    int num() const { return num_; }

    std::string GetName() const override { return "backend" + std::to_string(num_); }

    bool SupportsTransfer(Device& src_device, Device& dst_device) override {
        int src_num = dynamic_cast<TestBackend&>(src_device.backend()).num();
        int dst_num = dynamic_cast<TestBackend&>(dst_device.backend()).num();
        return g_config.CanTransfer(num_, src_num, dst_num);
    }

    int GetDeviceCount() const override { return 1; }

    std::unique_ptr<Device> CreateDevice(int index) override {
        assert(index == 0);
        return std::make_unique<NativeDevice>(*this, index);
    }

private:
    int num_;
};

// Test fixture for compatible transfer
class ArrayToDeviceCompatibleTest : public ::testing::TestWithParam<::testing::tuple<int, int, int>> {
protected:
    void SetUp() override {
        context_session_.emplace();

        default_backend_num_ = ::testing::get<0>(GetParam());
        src_backend_num_ = ::testing::get<1>(GetParam());
        dst_backend_num_ = ::testing::get<2>(GetParam());

        backends_.clear();
        for (int i = 0; i < g_config.num_backends(); ++i) {
            backends_.emplace_back(std::make_unique<TestBackend>(context_session_->context(), i));
        }

        // Set default backend (only if default_backend_num is non-negative)
        if (default_backend_num_ >= 0) {
            device_scope_ = std::make_unique<DeviceScope>(*GetDefaultDevice());
        }
    }

    void TearDown() override {
        device_scope_.reset();
        context_session_.reset();
        backends_.clear();
    }

    Device* GetDefaultDevice() {
        if (default_backend_num_ < 0) {
            return nullptr;
        } else {
            return &backends_[default_backend_num_]->GetDevice(0);
        }
    }

    Device& GetSourceDevice() { return backends_[src_backend_num_]->GetDevice(0); }

    Device& GetDestinationDevice() { return backends_[dst_backend_num_]->GetDevice(0); }

private:
    nonstd::optional<testing::ContextSession> context_session_;
    std::unique_ptr<DeviceScope> device_scope_;
    std::vector<std::unique_ptr<TestBackend>> backends_;
    int default_backend_num_{};
    int src_backend_num_{};
    int dst_backend_num_{};
};

void ExpectArraysEqual(const Array& expected, const Array& actual) {
    EXPECT_EQ(expected.dtype(), actual.dtype());
    EXPECT_EQ(expected.shape(), actual.shape());
    VisitDtype(expected.dtype(), [&expected, &actual](auto pt) {
        using T = typename decltype(pt)::type;
        int64_t total_size = expected.GetTotalSize();
        const T* data1 = static_cast<const T*>(expected.data().get());
        const T* data2 = static_cast<const T*>(actual.data().get());
        for (int64_t i = 0; i < total_size; ++i) {
            EXPECT_EQ(data1[i], data2[i]);
        }
    });
}

TEST_P(ArrayToDeviceCompatibleTest, ToDevice) {
    Device& src_dev = GetSourceDevice();
    Device& dst_dev = GetDestinationDevice();
    Device* default_device = internal::GetDefaultDeviceNoExcept();

    // Allocate the source array
    float data[] = {1.0f, 2.0f};
    auto nop = [](void* p) {
        (void)p;  // unused
    };
    Array a = Array::FromBuffer({2, 1}, Dtype::kFloat32, std::shared_ptr<float>(data, nop), src_dev);

    // Transfer
    Array b = a.ToDevice(dst_dev);

    EXPECT_EQ(&b.device(), &dst_dev) << "Array::ToDevice must allocate an array on the specified device.";
    EXPECT_EQ(&a.device(), &src_dev) << "Array::ToDevice must not alter the device of the original array.";
    EXPECT_NE(a.data().get(), b.data().get()) << "Array::ToDevice must not return an alias.";
    EXPECT_EQ(internal::GetDefaultDeviceNoExcept(), default_device) << "Array::ToDevice must not alter the default device.";
    ExpectArraysEqual(a, b);
}

INSTANTIATE_TEST_CASE_P(BackendCombination, ArrayToDeviceCompatibleTest,
                        ::testing::Values(std::make_tuple(-1, 0, 0),  // transfer between same devices
                                          std::make_tuple(-1, 0, 1),  // transfer to 1
                                          std::make_tuple(-1, 2, 0),  // transfer from 2
                                          std::make_tuple(2, 0, 1)    // checks default device does not change
                                          ));

// Test for incompatible transfer
TEST(ArrayToDeviceIncompatibleTest, ToDeviceIncompatible) {
    testing::ContextSession context_session;
    TestBackend src_backend{context_session.context(), 0};  // incompatible configuration
    TestBackend dst_backend{context_session.context(), 3};

    Device& src_dev = src_backend.GetDevice(0);
    Device& dst_dev = dst_backend.GetDevice(0);

    // Allocate the source array
    float data[] = {1.0f, 2.0f};
    auto nop = [](void* p) {
        (void)p;  // unused
    };
    Array a = Array::FromBuffer({2, 1}, Dtype::kFloat32, std::shared_ptr<float>(data, nop), src_dev);

    // Transfer
    EXPECT_THROW(a.ToDevice(dst_dev), XchainerError) << "Array::ToDevice must throw if incompatible device is given.";
}

TEST(ArrayToDeviceArithmeticTest, Arithmetic) {
    testing::ContextSession context_session;
    NativeBackend backend{context_session.context()};
    Device& dev0 = backend.GetDevice(0);
    Device& dev1 = backend.GetDevice(1);
    Device& dev2 = backend.GetDevice(2);  // default device
    DeviceScope device_scope{dev2};

    // Allocate the source array
    auto nop = [](void* p) {
        (void)p;  // unused
    };
    float data0[]{1.0f, 2.0f};
    float data1[]{3.0f, 4.0f};
    float data2[]{5.0f, 6.0f};
    float datay[]{8.0f, 14.0f};  // d0 * d1 + d2
    Shape shape{2, 1};
    Array a0 = Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data0, nop), dev0);
    Array a1 = Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data1, nop), dev0);
    Array a2 = Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data2, nop), dev1);
    Array ay = Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(datay, nop));

    a0.RequireGrad();
    a1.RequireGrad();
    a2.RequireGrad();

    // Test preconditions
    ASSERT_EQ(&dev0, &a0.device());
    ASSERT_EQ(&dev0, &a1.device());
    ASSERT_EQ(&dev1, &a2.device());

    Array b = a0 * a1;
    Array b_dev1 = b.ToDevice(dev1);
    Array c = b_dev1 + a2;

    // Check forward correctness
    EXPECT_EQ(&dev0, &b.device());
    EXPECT_EQ(&dev1, &b_dev1.device());
    EXPECT_EQ(&dev1, &c.device());
    EXPECT_EQ(&dev1, &c.device());
    EXPECT_TRUE(b.IsGradRequired());
    EXPECT_TRUE(b_dev1.IsGradRequired());
    EXPECT_TRUE(c.IsGradRequired());
    ExpectArraysEqual(ay, c);

    Backward(c);

    // Check backward correctness
    EXPECT_EQ(&dev0, &a0.GetGrad()->device());
    EXPECT_EQ(&dev0, &a1.GetGrad()->device());
    EXPECT_EQ(&dev1, &a2.GetGrad()->device());
}

}  // namespace
}  // namespace xchainer
<commit_msg>Add checks in ToDevice test<commit_after>#include <cassert>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <gtest/gtest.h>
#include <nonstd/optional.hpp>

#include "xchainer/array.h"
#include "xchainer/backend.h"
#include "xchainer/backprop.h"
#include "xchainer/device.h"
#include "xchainer/error.h"
#include "xchainer/native_backend.h"
#include "xchainer/native_device.h"
#include "xchainer/testing/context_session.h"

namespace xchainer {
namespace {

// Test configuration class
class TestConfig {
public:
    // backend <0> can transfer from backend <1> to backend <2>
    using Key = std::tuple<int, int, int>;

    TestConfig() {
        set_.insert({
            Key{0, 0, 0},  // backend0 can transfer with itself
            Key{0, 0, 1},  // backend0 can transfer to backend1
            Key{0, 2, 0},  // backend0 can transfer from backend2
                           // backend0 and backend3 are incompatible
        });
    }

    // Returns true if the backend `who` can transfer data from backend `from` to backend `to`
    bool CanTransfer(int who, int from, int to) { return set_.find(std::make_tuple(who, from, to)) != set_.end(); }

    // Return the number of test backends
    int num_backends() { return 4; }

private:
    std::set<Key> set_;
};

// Instantiate the global test configuration
static TestConfig g_config;

// Test backend class
class TestBackend : public NativeBackend {
public:
    TestBackend(Context& context, int num) : NativeBackend(context), num_(num) {}

    int num() const { return num_; }

    std::string GetName() const override { return "backend" + std::to_string(num_); }

    bool SupportsTransfer(Device& src_device, Device& dst_device) override {
        int src_num = dynamic_cast<TestBackend&>(src_device.backend()).num();
        int dst_num = dynamic_cast<TestBackend&>(dst_device.backend()).num();
        return g_config.CanTransfer(num_, src_num, dst_num);
    }

    int GetDeviceCount() const override { return 1; }

    std::unique_ptr<Device> CreateDevice(int index) override {
        assert(index == 0);
        return std::make_unique<NativeDevice>(*this, index);
    }

private:
    int num_;
};

// Test fixture for compatible transfer
class ArrayToDeviceCompatibleTest : public ::testing::TestWithParam<::testing::tuple<int, int, int>> {
protected:
    void SetUp() override {
        context_session_.emplace();

        default_backend_num_ = ::testing::get<0>(GetParam());
        src_backend_num_ = ::testing::get<1>(GetParam());
        dst_backend_num_ = ::testing::get<2>(GetParam());

        backends_.clear();
        for (int i = 0; i < g_config.num_backends(); ++i) {
            backends_.emplace_back(std::make_unique<TestBackend>(context_session_->context(), i));
        }

        // Set default backend (only if default_backend_num is non-negative)
        if (default_backend_num_ >= 0) {
            device_scope_ = std::make_unique<DeviceScope>(*GetDefaultDevice());
        }
    }

    void TearDown() override {
        device_scope_.reset();
        context_session_.reset();
        backends_.clear();
    }

    Device* GetDefaultDevice() {
        if (default_backend_num_ < 0) {
            return nullptr;
        } else {
            return &backends_[default_backend_num_]->GetDevice(0);
        }
    }

    Device& GetSourceDevice() { return backends_[src_backend_num_]->GetDevice(0); }

    Device& GetDestinationDevice() { return backends_[dst_backend_num_]->GetDevice(0); }

private:
    nonstd::optional<testing::ContextSession> context_session_;
    std::unique_ptr<DeviceScope> device_scope_;
    std::vector<std::unique_ptr<TestBackend>> backends_;
    int default_backend_num_{};
    int src_backend_num_{};
    int dst_backend_num_{};
};

void ExpectArraysEqual(const Array& expected, const Array& actual) {
    EXPECT_EQ(expected.dtype(), actual.dtype());
    EXPECT_EQ(expected.shape(), actual.shape());
    VisitDtype(expected.dtype(), [&expected, &actual](auto pt) {
        using T = typename decltype(pt)::type;
        int64_t total_size = expected.GetTotalSize();
        const T* data1 = static_cast<const T*>(expected.data().get());
        const T* data2 = static_cast<const T*>(actual.data().get());
        for (int64_t i = 0; i < total_size; ++i) {
            EXPECT_EQ(data1[i], data2[i]);
        }
    });
}

TEST_P(ArrayToDeviceCompatibleTest, ToDevice) {
    Device& src_dev = GetSourceDevice();
    Device& dst_dev = GetDestinationDevice();
    Device* default_device = internal::GetDefaultDeviceNoExcept();

    // Allocate the source array
    float data[] = {1.0f, 2.0f};
    auto nop = [](void* p) {
        (void)p;  // unused
    };
    Array a = Array::FromBuffer({2, 1}, Dtype::kFloat32, std::shared_ptr<float>(data, nop), src_dev);

    // Transfer
    Array b = a.ToDevice(dst_dev);

    EXPECT_EQ(&b.device(), &dst_dev) << "Array::ToDevice must allocate an array on the specified device.";
    EXPECT_EQ(&a.device(), &src_dev) << "Array::ToDevice must not alter the device of the original array.";
    EXPECT_NE(a.data().get(), b.data().get()) << "Array::ToDevice must not return an alias.";
    EXPECT_EQ(internal::GetDefaultDeviceNoExcept(), default_device) << "Array::ToDevice must not alter the default device.";
    ExpectArraysEqual(a, b);
}

INSTANTIATE_TEST_CASE_P(BackendCombination, ArrayToDeviceCompatibleTest,
                        ::testing::Values(std::make_tuple(-1, 0, 0),  // transfer between same devices
                                          std::make_tuple(-1, 0, 1),  // transfer to 1
                                          std::make_tuple(-1, 2, 0),  // transfer from 2
                                          std::make_tuple(2, 0, 1)    // checks default device does not change
                                          ));

// Test for incompatible transfer
TEST(ArrayToDeviceIncompatibleTest, ToDeviceIncompatible) {
    testing::ContextSession context_session;
    TestBackend src_backend{context_session.context(), 0};  // incompatible configuration
    TestBackend dst_backend{context_session.context(), 3};

    Device& src_dev = src_backend.GetDevice(0);
    Device& dst_dev = dst_backend.GetDevice(0);

    // Allocate the source array
    float data[] = {1.0f, 2.0f};
    auto nop = [](void* p) {
        (void)p;  // unused
    };
    Array a = Array::FromBuffer({2, 1}, Dtype::kFloat32, std::shared_ptr<float>(data, nop), src_dev);

    // Transfer
    EXPECT_THROW(a.ToDevice(dst_dev), XchainerError) << "Array::ToDevice must throw if incompatible device is given.";
}

TEST(ArrayToDeviceArithmeticTest, Arithmetic) {
    testing::ContextSession context_session;
    NativeBackend backend{context_session.context()};
    Device& dev0 = backend.GetDevice(0);
    Device& dev1 = backend.GetDevice(1);
    Device& dev2 = backend.GetDevice(2);  // default device
    DeviceScope device_scope{dev2};

    // Allocate the source array
    auto nop = [](void* p) {
        (void)p;  // unused
    };
    float data0[]{1.0f, 2.0f};
    float data1[]{3.0f, 4.0f};
    float data2[]{5.0f, 6.0f};
    Shape shape{2, 1};
    Array a0 = Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data0, nop), dev0);
    Array a1 = Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data1, nop), dev0);
    Array a2 = Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data2, nop), dev1);
    a0.RequireGrad();
    a1.RequireGrad();
    a2.RequireGrad();

    // Test preconditions
    ASSERT_EQ(&dev0, &a0.device());
    ASSERT_EQ(&dev0, &a1.device());
    ASSERT_EQ(&dev1, &a2.device());

    // Forward
    Array b = a0 * a1;
    Array b_dev1 = b.ToDevice(dev1);
    Array c = b_dev1 + a2;

    // Check forward correctness
    EXPECT_EQ(&dev0, &b.device());
    EXPECT_EQ(&dev1, &b_dev1.device());
    EXPECT_EQ(&dev1, &c.device());
    EXPECT_TRUE(b.IsGradRequired());
    EXPECT_TRUE(b_dev1.IsGradRequired());
    EXPECT_TRUE(c.IsGradRequired());
    float datay[]{8.0f, 14.0f};  // d0 * d1 + d2
    ExpectArraysEqual(c, Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(datay, nop)));

    // Backward
    Backward(c);

    // Check backward correctness
    ASSERT_TRUE(a0.GetGrad().has_value());
    ASSERT_TRUE(a1.GetGrad().has_value());
    ASSERT_TRUE(a2.GetGrad().has_value());
    EXPECT_EQ(&dev0, &a0.GetGrad()->device());
    EXPECT_EQ(&dev0, &a1.GetGrad()->device());
    EXPECT_EQ(&dev1, &a2.GetGrad()->device());
    float data0_grad[]{3.0f, 4.0f};
    float data1_grad[]{1.0f, 2.0f};
    float data2_grad[]{1.0f, 1.0f};
    ExpectArraysEqual(*a0.GetGrad(), Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data0_grad, nop)));
    ExpectArraysEqual(*a1.GetGrad(), Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data1_grad, nop)));
    ExpectArraysEqual(*a2.GetGrad(), Array::FromBuffer(shape, Dtype::kFloat32, std::shared_ptr<float>(data2_grad, nop)));
}

}  // namespace
}  // namespace xchainer
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: PropertySetMerger.hxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: cl $ $Date: 2000-11-08 11:28:10 $
 *
 *  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 _XMLOFF_PROPERTYSETMERGER_HXX_
#define _XMLOFF_PROPERTYSETMERGER_HXX_

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

extern ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
    PropertySetMerger_CreateInstance(
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rPropSet1,
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rPropSet2 ) throw();

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.1.650); FILE MERGED 2005/09/05 14:37:50 rt 1.1.650.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PropertySetMerger.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 12:40:22 $
 *
 *  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 _XMLOFF_PROPERTYSETMERGER_HXX_
#define _XMLOFF_PROPERTYSETMERGER_HXX_

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

extern ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
    PropertySetMerger_CreateInstance(
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rPropSet1,
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rPropSet2 ) throw();

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: contexts.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:30:43 $
 *
 *  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 _SCH_XML_CONTEXTS_HXX_
#define _SCH_XML_CONTEXTS_HXX_

#include "SchXMLImport.hxx"
#include "SchXMLTableContext.hxx"

#ifndef _XMLOFF_XMLICTXT_HXX
#include "xmlictxt.hxx"
#endif
#ifndef _XMLOFF_XMLTKMAP_HXX
#include "xmltkmap.hxx"
#endif

namespace com { namespace sun { namespace star { namespace xml { namespace sax {
        class XAttributeList;
}}}}}

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

   These contexts are only nedded by
   SchXMLImport not by the SchXMLImportHelper
   that is also used by other applications

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

class SchXMLDocContext : public SvXMLImportContext
{
private:
    SchXMLImportHelper& mrImportHelper;

public:
    SchXMLDocContext(
        SchXMLImportHelper& rImpHelper,
        SvXMLImport& rImport,
        sal_uInt16 nPrefix,
        const rtl::OUString& rLName );
    virtual ~SchXMLDocContext();

    TYPEINFO();

    virtual SvXMLImportContext* CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList );
};

// ========================================

class SchXMLBodyContext : public SvXMLImportContext
{
private:
    SchXMLImportHelper& mrImportHelper;

public:
    SchXMLBodyContext(
        SchXMLImportHelper& rImpHelper,
        SvXMLImport& rImport,
        sal_uInt16 nPrefix,
        const rtl::OUString& rLName );
    virtual ~SchXMLBodyContext();

    virtual void EndElement();
    virtual SvXMLImportContext* CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList );
};

// ========================================

#endif  // _SCH_XML_CONTEXTS_HXX_
<commit_msg>INTEGRATION: CWS vgbugs07 (1.3.274); FILE MERGED 2007/06/04 13:23:20 vg 1.3.274.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: contexts.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 14:53:45 $
 *
 *  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 _SCH_XML_CONTEXTS_HXX_
#define _SCH_XML_CONTEXTS_HXX_

#include "SchXMLImport.hxx"
#include "SchXMLTableContext.hxx"

#ifndef _XMLOFF_XMLICTXT_HXX
#include <xmloff/xmlictxt.hxx>
#endif
#ifndef _XMLOFF_XMLTKMAP_HXX
#include <xmloff/xmltkmap.hxx>
#endif

namespace com { namespace sun { namespace star { namespace xml { namespace sax {
        class XAttributeList;
}}}}}

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

   These contexts are only nedded by
   SchXMLImport not by the SchXMLImportHelper
   that is also used by other applications

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

class SchXMLDocContext : public SvXMLImportContext
{
private:
    SchXMLImportHelper& mrImportHelper;

public:
    SchXMLDocContext(
        SchXMLImportHelper& rImpHelper,
        SvXMLImport& rImport,
        sal_uInt16 nPrefix,
        const rtl::OUString& rLName );
    virtual ~SchXMLDocContext();

    TYPEINFO();

    virtual SvXMLImportContext* CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList );
};

// ========================================

class SchXMLBodyContext : public SvXMLImportContext
{
private:
    SchXMLImportHelper& mrImportHelper;

public:
    SchXMLBodyContext(
        SchXMLImportHelper& rImpHelper,
        SvXMLImport& rImport,
        sal_uInt16 nPrefix,
        const rtl::OUString& rLName );
    virtual ~SchXMLBodyContext();

    virtual void EndElement();
    virtual SvXMLImportContext* CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttrList );
};

// ========================================

#endif  // _SCH_XML_CONTEXTS_HXX_
<|endoftext|>


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

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

#ifndef _XMLOFF_PROPERTYHANDLERBASE_HXX
#include <xmlprhdl.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

XMLPropertyHandler::~XMLPropertyHandler()
{
     // does nothing
}

bool XMLPropertyHandler::equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const
{
    return (r1 == r2);
}
<commit_msg>INTEGRATION: CWS vgbugs07 (1.4.114); FILE MERGED 2007/06/04 13:23:33 vg 1.4.114.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xmlprhdl.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 15:48:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#ifndef _XMLOFF_PROPERTYHANDLERBASE_HXX
#include <xmloff/xmlprhdl.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif

XMLPropertyHandler::~XMLPropertyHandler()
{
     // does nothing
}

bool XMLPropertyHandler::equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const
{
    return (r1 == r2);
}
<|endoftext|>


<commit_before>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include <memory>
#include "audio/AudioDevice.hpp"

namespace ouzel
{
    class Engine;

    namespace audio
    {
        class Audio;

        class AudioDeviceEmpty: public AudioDevice
        {
            friend Audio;
        protected:
            AudioDeviceEmpty();
        };
    } // namespace audio
} // namespace ouzel
<commit_msg>Remove unused include<commit_after>// Copyright (C) 2018 Elviss Strazdins
// This file is part of the Ouzel engine.

#pragma once

#include "audio/AudioDevice.hpp"

namespace ouzel
{
    class Engine;

    namespace audio
    {
        class Audio;

        class AudioDeviceEmpty: public AudioDevice
        {
            friend Audio;
        protected:
            AudioDeviceEmpty();
        };
    } // namespace audio
} // namespace ouzel
<|endoftext|>


<commit_before>#ifndef MPACK_SOUND_HPP
#define MPACK_SOUND_HPP

#include "SoundService.hpp"
#include "OutputMixer.hpp"
#include "AudioPlayer.hpp"

#endif
<commit_msg>Added controllers to Sound.hpp<commit_after>#ifndef MPACK_SOUND_HPP
#define MPACK_SOUND_HPP

#include "SoundService.hpp"
#include "OutputMixer.hpp"
#include "AudioPlayer.hpp"
#include "AudioControllers.hpp"

#endif
<|endoftext|>


<commit_before>//
// TreeView.cpp
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "App.h"
#include "TreeView.h"
#include "MenuEnum.h"	// for TreeTest_Ctrl
#include "Frame.h"
#include "BuilderView.h"

DECLARE_APP(MyApp)

// Under Windows, the icons are in the .rc file; on Unix, they are included
// from .xpm files.
#ifndef __WXMSW__
#include "building.xpm"
#include "file1.xpm"
#include "file2.xpm"
#include "folder1.xpm"
#include "folder2.xpm"
#include "folder3.xpm"

#include "grid.xpm"
#include "image.xpm"
#include "raw.xpm"
#include "road.xpm"
#include "veg1.xpm"
#include "water.xpm"
#include "util.xpm"
#include "transit.xpm"
#endif

/////////////////////////////////////////////////

// MyTreeCtrl implementation
	IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl)

MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
	const wxPoint& pos, const wxSize& size,
	long style)
: wxTreeCtrl(parent, id, pos, size, style)
{
	m_reverseSort = false;
	m_imageListNormal = NULL;
	m_bShowPaths = true;

	CreateImageList(16);

	// Add some items to the tree
	RefreshTreeItems(NULL);
}

void MyTreeCtrl::CreateImageList(int size)
{
	delete m_imageListNormal;

	if ( size == -1 )
	{
		m_imageListNormal = NULL;
		return;
	}

	// Make an image list containing small icons
	m_imageListNormal = new wxImageList(size, size, TRUE);

	// should correspond to TreeCtrlIcon_xxx enum
	wxIcon icons[14];
	icons[0] = wxICON(file1);
	icons[1] = wxICON(file2);
	icons[2] = wxICON(folder1);
	icons[3] = wxICON(folder2);
	icons[4] = wxICON(folder3);
	icons[5] = wxICON(building);
	icons[6] = wxICON(road);
	icons[7] = wxICON(grid);
	icons[8] = wxICON(image);
	icons[9] = wxICON(veg1);
	icons[10] = wxICON(water);
	icons[11] = wxICON(transit);
	icons[12] = wxICON(util);
	icons[13] = wxICON(raw);

	int sizeOrig = icons[0].GetWidth();
	for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
	{
		if ( size == sizeOrig )
			m_imageListNormal->Add(icons[i]);
		else
			m_imageListNormal->Add(wxImage(icons[i]).Rescale(size, size).
				ConvertToBitmap());
	}

	SetImageList(m_imageListNormal);
}

MyTreeCtrl::~MyTreeCtrl()
{
	delete m_imageListNormal;
}

int MyTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
	const wxTreeItemId& item2)
{
	if ( m_reverseSort )
	{
		// just exchange 1st and 2nd items
		return wxTreeCtrl::OnCompareItems(item2, item1);
	}
	else
	{
		return wxTreeCtrl::OnCompareItems(item1, item2);
	}
}

wxTreeItemId rootId;

wxTreeItemId MyTreeCtrl::AddRootItem(int image, const char *text)
{
	wxTreeItemId id = AppendItem(rootId, text, image);
	SetItemBold(id);
	return id;
}

wxString MyTreeCtrl::MakeItemName(vtLayerPtr lp)
{
	wxString str;
	if (lp->GetModified())
		str += "(*) ";
	wxString fullpath = lp->GetFilename();
	if (!m_bShowPaths)
	{
		if (fullpath.Find('/') != -1)
			fullpath = fullpath.AfterLast('/');
		if (fullpath.Find('\\') != -1)
			fullpath = fullpath.AfterLast('\\');
		if (fullpath.Find(':') != -1)
			fullpath = fullpath.AfterLast(':');
	}
	str += fullpath;
	return str;
}

void MyTreeCtrl::RefreshTreeItems(MainFrame *pFrame)
{
	DeleteAllItems();

	rootId = AddRoot("Layers");
	SetItemBold(rootId);

	int	image, imageSel;

	wxTreeItemId elevId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Grid, "Elevation");
#ifndef ELEVATION_ONLY
//	wxTreeItemId imageId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Image, "Images");
	wxTreeItemId buildId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Building, "Structures");
	wxTreeItemId roadId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Road, "Roads");
	wxTreeItemId vegId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Veg1, "Vegetation");
	wxTreeItemId waterId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Water, "Water");
#if SUPPORT_TRANSIT
	wxTreeItemId transId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Transit, "Transit");
#endif
	wxTreeItemId utilityId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Utility, "Utilities");
	wxTreeItemId rawId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Raw, "Raw");
#endif

	image = TreeCtrlIcon_File;
	imageSel = TreeCtrlIcon_FileSelected;
	vtLayerPtr lp;
	int iLayers = 0;
	if (pFrame) iLayers = pFrame->m_Layers.GetSize();
	for (int i = 0; i < iLayers; i++)
	{
		lp = pFrame->m_Layers.GetAt(i);

		wxString str = MakeItemName(lp);

		wxTreeItemId hItem = -1;
		switch (lp->GetType())
		{
			case LT_ELEVATION:
				hItem = AppendItem(elevId, str, image, imageSel);
				break;
#ifndef ELEVATION_ONLY
			case LT_ROAD:
				hItem = AppendItem(roadId, str, image, imageSel);
				break;
			case LT_STRUCTURE:
				hItem = AppendItem(buildId, str, image, imageSel);
				break;
			case LT_VEG:
				hItem = AppendItem(vegId, str, image, imageSel);
				break;
			case LT_WATER:
				hItem = AppendItem(waterId, str, image, imageSel);
				break;
#if SUPPORT_TRANSIT
			case LT_TRANSIT:
				hItem = AppendItem(transId, str, image, imageSel);
				break;
#endif
			case LT_UTILITY:
				hItem = AppendItem(utilityId, str, image, imageSel);
				break;
			case LT_RAW:
				hItem = AppendItem(rawId, str, image, imageSel);
				break;
#endif
		}
		if (hItem != -1)
		{
			SetItemData(hItem, new MyTreeItemData(lp));

			if (lp == pFrame->GetActiveLayer())
				SelectItem(hItem);
		}
	}

	Expand(rootId);
	Expand(elevId);
#ifndef ELEVATION_ONLY
//	Expand(imageId);
	Expand(roadId);
	Expand(buildId);
	Expand(vegId);
	Expand(waterId);
#if SUPPORT_TRANSIT
	Expand(transId);
#endif
	Expand(utilityId);
	Expand(rawId);
#endif
}

void MyTreeCtrl::RefreshTreeStatus(MainFrame *pFrame)
{
	wxTreeItemId root = GetRootItem();
	wxTreeItemId parent, item;
	long cookie = 0, cookie2 = 1;

	for (parent = GetFirstChild(root, cookie); parent; parent = GetNextChild(root, cookie))
	{
//		wxString str = GetItemText(parent);
		for (item = GetFirstChild(parent, cookie2); item; item = GetNextChild(parent, cookie2))
		{
			MyTreeItemData *data = (MyTreeItemData *)GetItemData(item);
//			wxString str2 = GetItemText(item);
			if (data)
			{
				SetItemText(item, MakeItemName(data->m_pLayer));
				if (data->m_pLayer == pFrame->GetActiveLayer())
					SelectItem(item);
			}
		}
	}
}

// avoid repetition
#define TREE_EVENT_HANDLER(name)			\
void MyTreeCtrl::name(wxTreeEvent& event)	\
{											\
 /*	wxLogMessage(#name); */					\
	event.Skip();							\
}

TREE_EVENT_HANDLER(OnBeginRDrag)
	TREE_EVENT_HANDLER(OnDeleteItem)
	TREE_EVENT_HANDLER(OnGetInfo)
	TREE_EVENT_HANDLER(OnSetInfo)
	TREE_EVENT_HANDLER(OnItemExpanded)
	TREE_EVENT_HANDLER(OnItemExpanding)
	TREE_EVENT_HANDLER(OnItemCollapsed)
	TREE_EVENT_HANDLER(OnSelChanging)
	TREE_EVENT_HANDLER(OnTreeKeyDown)

#undef TREE_EVENT_HANDLER

	void MyTreeCtrl::OnSelChanged(wxTreeEvent& event)
{
	wxTreeItemId item = event.GetItem();
	MyTreeItemData *data = (MyTreeItemData *)GetItemData(item);
	vtLayerPtr lp = NULL;
	if (data)
		lp = data->m_pLayer;

	vtLayerPtr last = GetMainFrame()->GetActiveLayer();
	if (lp != last)
		GetMainFrame()->GetView()->SetActiveLayer(lp);

	LayerType last_ltype = last ? last->GetType() : LT_UNKNOWN;
	if (lp && lp->GetType() != last_ltype)
		GetMainFrame()->RefreshToolbar();
}

void MyTreeCtrl::OnBeginDrag(wxTreeEvent& event)
{
}

void MyTreeCtrl::OnEndDrag(wxTreeEvent& event)
{
}

void MyTreeCtrl::OnBeginLabelEdit(wxTreeEvent& event)
{
#if 0
	wxLogMessage("OnBeginLabelEdit");

	// for testing, prevent this items label editing
	wxTreeItemId itemId = event.GetItem();
	if ( IsTestItem(itemId) )
	{
		wxMessageBox("You can't edit this item.");

		event.Veto();
	}
#endif
}

void MyTreeCtrl::OnEndLabelEdit(wxTreeEvent& event)
{
#if 0
	wxLogMessage("OnEndLabelEdit");

	// don't allow anything except letters in the labels
	if ( !event.GetLabel().IsWord() )
	{
		wxMessageBox("The label should contain only letters.");

		event.Veto();
	}
#endif
}

void MyTreeCtrl::OnItemCollapsing(wxTreeEvent& event)
{
#if 0
	wxLogMessage("OnItemCollapsing");

	// for testing, prevent the user from collapsing the first child folder
	wxTreeItemId itemId = event.GetItem();
	if ( IsTestItem(itemId) )
	{
		wxMessageBox("You can't collapse this item.");

		event.Veto();
	}
#endif
}

void MyTreeCtrl::OnItemActivated(wxTreeEvent& event)
{
#if 0
	// show some info about this item
	wxTreeItemId itemId = event.GetItem();
	MyTreeItemData *item = (MyTreeItemData *)GetItemData(itemId);

	if ( item != NULL )
	{
		item->ShowInfo(this);
	}
	wxLogMessage("OnItemActivated");
#endif
}

void MyTreeCtrl::OnRMouseDClick(wxMouseEvent& event)
{
#if 0
	wxTreeItemId id = HitTest(event.GetPosition());
	if ( !id )
		wxLogMessage("No item under mouse");
	else
	{
		MyTreeItemData *item = (MyTreeItemData *)GetItemData(id);
		if ( item )
			wxLogMessage("Item '%s' under mouse", item->GetDesc());
	}
#endif
}

/////////////////////////////////////////////////

BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
EVT_TREE_BEGIN_DRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginDrag)
EVT_TREE_BEGIN_RDRAG(TreeTest_Ctrl, MyTreeCtrl::OnBeginRDrag)
EVT_TREE_END_DRAG(TreeTest_Ctrl, MyTreeCtrl::OnEndDrag)
EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnBeginLabelEdit)
EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnEndLabelEdit)
EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, MyTreeCtrl::OnDeleteItem)
EVT_TREE_SET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnSetInfo)
EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanded)
EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanding)
EVT_TREE_ITEM_COLLAPSED(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsed)
EVT_TREE_ITEM_COLLAPSING(TreeTest_Ctrl, MyTreeCtrl::OnItemCollapsing)
EVT_TREE_SEL_CHANGED(TreeTest_Ctrl, MyTreeCtrl::OnSelChanged)
EVT_TREE_SEL_CHANGING(TreeTest_Ctrl, MyTreeCtrl::OnSelChanging)
EVT_TREE_KEY_DOWN(TreeTest_Ctrl, MyTreeCtrl::OnTreeKeyDown)
EVT_TREE_ITEM_ACTIVATED(TreeTest_Ctrl, MyTreeCtrl::OnItemActivated)
EVT_RIGHT_DCLICK(MyTreeCtrl::OnRMouseDClick)
END_EVENT_TABLE()
<commit_msg>renamed control ID<commit_after>//
// TreeView.cpp
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "App.h"
#include "TreeView.h"
#include "MenuEnum.h"	// for LayerTree_Ctrl
#include "Frame.h"
#include "BuilderView.h"

DECLARE_APP(MyApp)

// Under Windows, the icons are in the .rc file; on Unix, they are included
// from .xpm files.
#ifndef __WXMSW__
#include "building.xpm"
#include "file1.xpm"
#include "file2.xpm"
#include "folder1.xpm"
#include "folder2.xpm"
#include "folder3.xpm"

#include "grid.xpm"
#include "image.xpm"
#include "raw.xpm"
#include "road.xpm"
#include "veg1.xpm"
#include "water.xpm"
#include "util.xpm"
#include "transit.xpm"
#endif

/////////////////////////////////////////////////

// MyTreeCtrl implementation
	IMPLEMENT_DYNAMIC_CLASS(MyTreeCtrl, wxTreeCtrl)

MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
	const wxPoint& pos, const wxSize& size,
	long style)
: wxTreeCtrl(parent, id, pos, size, style)
{
	m_reverseSort = false;
	m_imageListNormal = NULL;
	m_bShowPaths = true;

	CreateImageList(16);

	// Add some items to the tree
	RefreshTreeItems(NULL);
}

void MyTreeCtrl::CreateImageList(int size)
{
	delete m_imageListNormal;

	if ( size == -1 )
	{
		m_imageListNormal = NULL;
		return;
	}

	// Make an image list containing small icons
	m_imageListNormal = new wxImageList(size, size, TRUE);

	// should correspond to TreeCtrlIcon_xxx enum
	wxIcon icons[14];
	icons[0] = wxICON(file1);
	icons[1] = wxICON(file2);
	icons[2] = wxICON(folder1);
	icons[3] = wxICON(folder2);
	icons[4] = wxICON(folder3);
	icons[5] = wxICON(building);
	icons[6] = wxICON(road);
	icons[7] = wxICON(grid);
	icons[8] = wxICON(image);
	icons[9] = wxICON(veg1);
	icons[10] = wxICON(water);
	icons[11] = wxICON(transit);
	icons[12] = wxICON(util);
	icons[13] = wxICON(raw);

	int sizeOrig = icons[0].GetWidth();
	for ( size_t i = 0; i < WXSIZEOF(icons); i++ )
	{
		if ( size == sizeOrig )
			m_imageListNormal->Add(icons[i]);
		else
			m_imageListNormal->Add(wxImage(icons[i]).Rescale(size, size).
				ConvertToBitmap());
	}

	SetImageList(m_imageListNormal);
}

MyTreeCtrl::~MyTreeCtrl()
{
	delete m_imageListNormal;
}

int MyTreeCtrl::OnCompareItems(const wxTreeItemId& item1,
	const wxTreeItemId& item2)
{
	if ( m_reverseSort )
	{
		// just exchange 1st and 2nd items
		return wxTreeCtrl::OnCompareItems(item2, item1);
	}
	else
	{
		return wxTreeCtrl::OnCompareItems(item1, item2);
	}
}

wxTreeItemId rootId;

wxTreeItemId MyTreeCtrl::AddRootItem(int image, const char *text)
{
	wxTreeItemId id = AppendItem(rootId, text, image);
	SetItemBold(id);
	return id;
}

wxString MyTreeCtrl::MakeItemName(vtLayerPtr lp)
{
	wxString str;
	if (lp->GetModified())
		str += "(*) ";
	wxString fullpath = lp->GetFilename();
	if (!m_bShowPaths)
	{
		if (fullpath.Find('/') != -1)
			fullpath = fullpath.AfterLast('/');
		if (fullpath.Find('\\') != -1)
			fullpath = fullpath.AfterLast('\\');
		if (fullpath.Find(':') != -1)
			fullpath = fullpath.AfterLast(':');
	}
	str += fullpath;
	return str;
}

void MyTreeCtrl::RefreshTreeItems(MainFrame *pFrame)
{
	DeleteAllItems();

	rootId = AddRoot("Layers");
	SetItemBold(rootId);

	int	image, imageSel;

	wxTreeItemId elevId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Grid, "Elevation");
#ifndef ELEVATION_ONLY
//	wxTreeItemId imageId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Image, "Images");
	wxTreeItemId buildId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Building, "Structures");
	wxTreeItemId roadId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Road, "Roads");
	wxTreeItemId vegId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Veg1, "Vegetation");
	wxTreeItemId waterId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Water, "Water");
#if SUPPORT_TRANSIT
	wxTreeItemId transId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Transit, "Transit");
#endif
	wxTreeItemId utilityId = AddRootItem(MyTreeCtrl::TreeCtrlIcon_Utility, "Utilities");
	wxTreeItemId rawId =	AddRootItem(MyTreeCtrl::TreeCtrlIcon_Raw, "Raw");
#endif

	image = TreeCtrlIcon_File;
	imageSel = TreeCtrlIcon_FileSelected;
	vtLayerPtr lp;
	int iLayers = 0;
	if (pFrame) iLayers = pFrame->m_Layers.GetSize();
	for (int i = 0; i < iLayers; i++)
	{
		lp = pFrame->m_Layers.GetAt(i);

		wxString str = MakeItemName(lp);

		wxTreeItemId hItem = -1;
		switch (lp->GetType())
		{
			case LT_ELEVATION:
				hItem = AppendItem(elevId, str, image, imageSel);
				break;
#ifndef ELEVATION_ONLY
			case LT_ROAD:
				hItem = AppendItem(roadId, str, image, imageSel);
				break;
			case LT_STRUCTURE:
				hItem = AppendItem(buildId, str, image, imageSel);
				break;
			case LT_VEG:
				hItem = AppendItem(vegId, str, image, imageSel);
				break;
			case LT_WATER:
				hItem = AppendItem(waterId, str, image, imageSel);
				break;
#if SUPPORT_TRANSIT
			case LT_TRANSIT:
				hItem = AppendItem(transId, str, image, imageSel);
				break;
#endif
			case LT_UTILITY:
				hItem = AppendItem(utilityId, str, image, imageSel);
				break;
			case LT_RAW:
				hItem = AppendItem(rawId, str, image, imageSel);
				break;
#endif
		}
		if (hItem != -1)
		{
			SetItemData(hItem, new MyTreeItemData(lp));

			if (lp == pFrame->GetActiveLayer())
				SelectItem(hItem);
		}
	}

	Expand(rootId);
	Expand(elevId);
#ifndef ELEVATION_ONLY
//	Expand(imageId);
	Expand(roadId);
	Expand(buildId);
	Expand(vegId);
	Expand(waterId);
#if SUPPORT_TRANSIT
	Expand(transId);
#endif
	Expand(utilityId);
	Expand(rawId);
#endif
}

void MyTreeCtrl::RefreshTreeStatus(MainFrame *pFrame)
{
	wxTreeItemId root = GetRootItem();
	wxTreeItemId parent, item;
	long cookie = 0, cookie2 = 1;

	for (parent = GetFirstChild(root, cookie); parent; parent = GetNextChild(root, cookie))
	{
//		wxString str = GetItemText(parent);
		for (item = GetFirstChild(parent, cookie2); item; item = GetNextChild(parent, cookie2))
		{
			MyTreeItemData *data = (MyTreeItemData *)GetItemData(item);
//			wxString str2 = GetItemText(item);
			if (data)
			{
				SetItemText(item, MakeItemName(data->m_pLayer));
				if (data->m_pLayer == pFrame->GetActiveLayer())
					SelectItem(item);
			}
		}
	}
}

// avoid repetition
#define TREE_EVENT_HANDLER(name)			\
void MyTreeCtrl::name(wxTreeEvent& event)	\
{											\
 /*	wxLogMessage(#name); */					\
	event.Skip();							\
}

TREE_EVENT_HANDLER(OnBeginRDrag)
	TREE_EVENT_HANDLER(OnDeleteItem)
	TREE_EVENT_HANDLER(OnGetInfo)
	TREE_EVENT_HANDLER(OnSetInfo)
	TREE_EVENT_HANDLER(OnItemExpanded)
	TREE_EVENT_HANDLER(OnItemExpanding)
	TREE_EVENT_HANDLER(OnItemCollapsed)
	TREE_EVENT_HANDLER(OnSelChanging)
	TREE_EVENT_HANDLER(OnTreeKeyDown)

#undef TREE_EVENT_HANDLER

	void MyTreeCtrl::OnSelChanged(wxTreeEvent& event)
{
	wxTreeItemId item = event.GetItem();
	MyTreeItemData *data = (MyTreeItemData *)GetItemData(item);
	vtLayerPtr lp = NULL;
	if (data)
		lp = data->m_pLayer;

	vtLayerPtr last = GetMainFrame()->GetActiveLayer();
	if (lp != last)
		GetMainFrame()->GetView()->SetActiveLayer(lp);

	LayerType last_ltype = last ? last->GetType() : LT_UNKNOWN;
	if (lp && lp->GetType() != last_ltype)
		GetMainFrame()->RefreshToolbar();
}

void MyTreeCtrl::OnBeginDrag(wxTreeEvent& event)
{
}

void MyTreeCtrl::OnEndDrag(wxTreeEvent& event)
{
}

void MyTreeCtrl::OnBeginLabelEdit(wxTreeEvent& event)
{
#if 0
	wxLogMessage("OnBeginLabelEdit");

	// for testing, prevent this items label editing
	wxTreeItemId itemId = event.GetItem();
	if ( IsTestItem(itemId) )
	{
		wxMessageBox("You can't edit this item.");

		event.Veto();
	}
#endif
}

void MyTreeCtrl::OnEndLabelEdit(wxTreeEvent& event)
{
#if 0
	wxLogMessage("OnEndLabelEdit");

	// don't allow anything except letters in the labels
	if ( !event.GetLabel().IsWord() )
	{
		wxMessageBox("The label should contain only letters.");

		event.Veto();
	}
#endif
}

void MyTreeCtrl::OnItemCollapsing(wxTreeEvent& event)
{
#if 0
	wxLogMessage("OnItemCollapsing");

	// for testing, prevent the user from collapsing the first child folder
	wxTreeItemId itemId = event.GetItem();
	if ( IsTestItem(itemId) )
	{
		wxMessageBox("You can't collapse this item.");

		event.Veto();
	}
#endif
}

void MyTreeCtrl::OnItemActivated(wxTreeEvent& event)
{
#if 0
	// show some info about this item
	wxTreeItemId itemId = event.GetItem();
	MyTreeItemData *item = (MyTreeItemData *)GetItemData(itemId);

	if ( item != NULL )
	{
		item->ShowInfo(this);
	}
	wxLogMessage("OnItemActivated");
#endif
}

void MyTreeCtrl::OnRMouseDClick(wxMouseEvent& event)
{
#if 0
	wxTreeItemId id = HitTest(event.GetPosition());
	if ( !id )
		wxLogMessage("No item under mouse");
	else
	{
		MyTreeItemData *item = (MyTreeItemData *)GetItemData(id);
		if ( item )
			wxLogMessage("Item '%s' under mouse", item->GetDesc());
	}
#endif
}

/////////////////////////////////////////////////

BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
EVT_TREE_BEGIN_DRAG(LayerTree_Ctrl, MyTreeCtrl::OnBeginDrag)
EVT_TREE_BEGIN_RDRAG(LayerTree_Ctrl, MyTreeCtrl::OnBeginRDrag)
EVT_TREE_END_DRAG(LayerTree_Ctrl, MyTreeCtrl::OnEndDrag)
EVT_TREE_BEGIN_LABEL_EDIT(LayerTree_Ctrl, MyTreeCtrl::OnBeginLabelEdit)
EVT_TREE_END_LABEL_EDIT(LayerTree_Ctrl, MyTreeCtrl::OnEndLabelEdit)
EVT_TREE_DELETE_ITEM(LayerTree_Ctrl, MyTreeCtrl::OnDeleteItem)
EVT_TREE_SET_INFO(LayerTree_Ctrl, MyTreeCtrl::OnSetInfo)
EVT_TREE_ITEM_EXPANDED(LayerTree_Ctrl, MyTreeCtrl::OnItemExpanded)
EVT_TREE_ITEM_EXPANDING(LayerTree_Ctrl, MyTreeCtrl::OnItemExpanding)
EVT_TREE_ITEM_COLLAPSED(LayerTree_Ctrl, MyTreeCtrl::OnItemCollapsed)
EVT_TREE_ITEM_COLLAPSING(LayerTree_Ctrl, MyTreeCtrl::OnItemCollapsing)
EVT_TREE_SEL_CHANGED(LayerTree_Ctrl, MyTreeCtrl::OnSelChanged)
EVT_TREE_SEL_CHANGING(LayerTree_Ctrl, MyTreeCtrl::OnSelChanging)
EVT_TREE_KEY_DOWN(LayerTree_Ctrl, MyTreeCtrl::OnTreeKeyDown)
EVT_TREE_ITEM_ACTIVATED(LayerTree_Ctrl, MyTreeCtrl::OnItemActivated)
EVT_RIGHT_DCLICK(MyTreeCtrl::OnRMouseDClick)
END_EVENT_TABLE()
<|endoftext|>


<commit_before>/*
 * GarageInstallationImplementation.cpp
 *
 *  Created on: Dec 6, 2010
 *      Author: crush
 */

#include "server/zone/objects/installation/garage/GarageInstallation.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/ZoneServer.h"
#include "server/zone/Zone.h"

void GarageInstallationImplementation::createChildObjects() {
	float positionX = coordinates.getPositionX();
	float positionY = coordinates.getPositionY();
	float positionZ = coordinates.getPositionZ();

	uint32 garageAreaTemplateCRC = String("object/garage_area.iff").hashCode();
	ManagedReference<SceneObject*> obj = server->getZoneServer()->createObject(garageAreaTemplateCRC, 1);

	if (obj == NULL)
		return;

	ActiveArea* activeArea = cast<ActiveArea*>( obj.get());

	activeArea->setRadius(64);
	activeArea->initializePosition(getPositionX(), getPositionZ(), getPositionY());
	//activeArea->insertToZone(getZone());
	getZone()->transferObject(activeArea, -1, true);

	garageArea = activeArea;

	TangibleObjectImplementation::createChildObjects();
}

void GarageInstallationImplementation::notifyRemoveFromZone() {
	InstallationObjectImplementation::notifyRemoveFromZone();

	if (garageArea != NULL) {
		garageArea->destroyObjectFromWorld(false);
	}
}

void GarageInstallationImplementation::destroyObjectFromDatabase(bool destroyContainedObjects) {
	InstallationObjectImplementation::destroyObjectFromDatabase(destroyContainedObjects);

	if (!destroyContainedObjects)
		return;

	if (garageArea != NULL)
		garageArea->destroyObjectFromDatabase(true);
}
<commit_msg>[fixed] stability issue<commit_after>/*
 * GarageInstallationImplementation.cpp
 *
 *  Created on: Dec 6, 2010
 *      Author: crush
 */

#include "server/zone/objects/installation/garage/GarageInstallation.h"
#include "server/zone/objects/area/ActiveArea.h"
#include "server/zone/ZoneServer.h"
#include "server/zone/Zone.h"

void GarageInstallationImplementation::createChildObjects() {
	float positionX = coordinates.getPositionX();
	float positionY = coordinates.getPositionY();
	float positionZ = coordinates.getPositionZ();

	uint32 garageAreaTemplateCRC = String("object/garage_area.iff").hashCode();
	ManagedReference<SceneObject*> obj = server->getZoneServer()->createObject(garageAreaTemplateCRC, 1);

	if (obj == NULL)
		return;

	ActiveArea* activeArea = cast<ActiveArea*>( obj.get());

	activeArea->setRadius(64);
	activeArea->initializePosition(getPositionX(), getPositionZ(), getPositionY());
	//activeArea->insertToZone(getZone());
	getZone()->transferObject(activeArea, -1, true);

	garageArea = activeArea;

	TangibleObjectImplementation::createChildObjects();
}

void GarageInstallationImplementation::notifyRemoveFromZone() {
	InstallationObjectImplementation::notifyRemoveFromZone();

	Reference<ActiveArea* > garageArea = this->garageArea;

	if (garageArea != NULL) {
		EXECUTE_TASK_1(garagaArea, {
				Locker locker(garageArea_p);

				garageArea_p->destroyObjectFromWorld(false);
		});
	}
}

void GarageInstallationImplementation::destroyObjectFromDatabase(bool destroyContainedObjects) {
	InstallationObjectImplementation::destroyObjectFromDatabase(destroyContainedObjects);

	if (!destroyContainedObjects)
		return;

	if (garageArea != NULL)
		garageArea->destroyObjectFromDatabase(true);
}
<|endoftext|>