<commit_before>/*
 * OXT - OS eXtensions for boosT
 * Provides important functionality necessary for writing robust server software.
 *
 * Copyright (c) 2010 Phusion
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifndef _OXT_THREAD_HPP_
#define _OXT_THREAD_HPP_

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "system_calls.hpp"
#include "backtrace.hpp"
#ifdef OXT_BACKTRACE_IS_ENABLED
	#include <sstream>
#endif
#include <string>
#include <list>
#include <unistd.h>
#include <limits.h>  // for PTHREAD_STACK_MIN

namespace oxt {

extern boost::mutex _next_thread_number_mutex;
extern unsigned int _next_thread_number;

/**
 * Enhanced thread class with support for:
 * - user-defined stack size.
 * - system call interruption.
 * - backtraces.
 */
class thread: public boost::thread {
private:
	struct thread_data {
		std::string name;
		#ifdef OXT_BACKTRACE_IS_ENABLED
			thread_registration *registration;
			boost::mutex registration_lock;
			bool done;
		#endif
	};

	typedef boost::shared_ptr<thread_data> thread_data_ptr;

	thread_data_ptr data;

	void initialize_data(const std::string &thread_name) {
		data = thread_data_ptr(new thread_data());
		if (thread_name.empty()) {
			boost::mutex::scoped_lock l(_next_thread_number_mutex);
			std::stringstream str;

			str << "Thread #" << _next_thread_number;
			_next_thread_number++;
			data->name = str.str();
		} else {
			data->name = thread_name;
		}
		#ifdef OXT_BACKTRACE_IS_ENABLED
			data->registration = NULL;
			data->done = false;
		#endif
	}

	static void thread_main(boost::function<void ()> func, thread_data_ptr data) {
		#ifdef OXT_BACKTRACE_IS_ENABLED
			initialize_backtrace_support_for_this_thread i(data->name);
			data->registration = i.registration;
		#endif

		#ifdef OXT_BACKTRACE_IS_ENABLED
			// Put finalization code in a struct destructor,
			// for exception safety.
			struct finalization_routines {
				thread_data_ptr &data;

				finalization_routines(thread_data_ptr &data_)
					: data(data_) {}

				~finalization_routines() {
					boost::mutex::scoped_lock l(data->registration_lock);
					data->registration = NULL;
					data->done = true;
				}
			};
			finalization_routines f(data);
		#endif

		func();
	}

public:
	/**
	 * Create a new thread.
	 *
	 * @param func A function object which will be called as the thread's
	 *     main function. This object must be copyable. <tt>func</tt> is
	 *     copied into storage managed internally by the thread library,
	 *     and that copy is invoked on a newly-created thread of execution.
	 * @param name A name for this thread. If an empty string is given, then
	 *     a name will be automatically chosen.
	 * @param stack_size The stack size, in bytes, that the thread should
	 *     have. If 0 is specified, the operating system's default stack
	 *     size is used. If non-zero is specified, and the size is smaller
	 *     than the operating system's minimum stack size, then the operating
	 *     system's minimum stack size will be used.
	 * @pre func must be copyable.
	 * @throws boost::thread_resource_error Something went wrong during
	 *     creation of the thread.
	 */
	explicit thread(boost::function<void ()> func, const std::string &name = "", unsigned int stack_size = 0) {
		initialize_data(name);

		set_thread_main_function(boost::bind(thread_main, func, data));

		unsigned long min_stack_size;
		bool stack_min_size_defined;
		bool round_stack_size;

		#ifdef PTHREAD_STACK_MIN
			// PTHREAD_STACK_MIN may not be a constant macro so we need
			// to evaluate it dynamically.
			min_stack_size = PTHREAD_STACK_MIN;
			stack_min_size_defined = true;
		#else
			// Assume minimum stack size is 128 KB.
			min_stack_size = 128 * 1024;
			stack_min_size_defined = false;
		#endif
		if (stack_size != 0 && stack_size < min_stack_size) {
			stack_size = min_stack_size;
			round_stack_size = !stack_min_size_defined;
		} else {
			round_stack_size = true;
		}

		if (round_stack_size) {
			// Round stack size up to page boundary.
			long page_size;
			#if defined(_SC_PAGESIZE)
				page_size = sysconf(_SC_PAGESIZE);
			#elif defined(_SC_PAGE_SIZE)
				page_size = sysconf(_SC_PAGE_SIZE);
			#elif defined(PAGESIZE)
				page_size = sysconf(PAGESIZE);
			#elif defined(PAGE_SIZE)
				page_size = sysconf(PAGE_SIZE);
			#else
				page_size = getpagesize();
			#endif
			if (stack_size % page_size != 0) {
				stack_size = stack_size - (stack_size % page_size) + page_size;
			}
		}

		start_thread(stack_size);
	}

	/**
	 * Return this thread's name. The name was set during construction.
	 */
	std::string name() const throw() {
		return data->name;
	}

	/**
	 * Return the current backtrace of the thread of execution, as a string.
	 */
	std::string backtrace() const throw() {
		#ifdef OXT_BACKTRACE_IS_ENABLED
			boost::mutex::scoped_lock l(data->registration_lock);
			if (data->registration == NULL) {
				if (data->done) {
					return "     (no backtrace: thread has quit)";
				} else {
					return "     (no backtrace: thread hasn't been started yet)";
				}
			} else {
				spin_lock::scoped_lock l2(*data->registration->backtrace_lock);
				return _format_backtrace(data->registration->backtrace);
			}
		#else
			return "    (backtrace support disabled during compile time)";
		#endif
	}

	/**
	 * Return the backtraces of all oxt::thread threads, as well as that of the
	 * main thread, in a nicely formatted string.
	 */
	static std::string all_backtraces() throw() {
		#ifdef OXT_BACKTRACE_IS_ENABLED
			boost::mutex::scoped_lock l(_thread_registration_mutex);
			list<thread_registration *>::const_iterator it;
			std::stringstream result;

			for (it = _registered_threads.begin(); it != _registered_threads.end(); it++) {
				thread_registration *r = *it;
				result << "Thread '" << r->name << "':" << endl;

				spin_lock::scoped_lock l(*r->backtrace_lock);
				result << _format_backtrace(r->backtrace) << endl;
			}
			return result.str();
		#else
			return "(backtrace support disabled during compile time)";
		#endif
	}

	/**
	 * Interrupt the thread. This method behaves just like
	 * boost::thread::interrupt(), but will also respect the interruption
	 * points defined in oxt::syscalls.
	 *
	 * Note that an interruption request may get lost, depending on the
	 * current execution point of the thread. Thus, one should call this
	 * method in a loop, until a certain goal condition has been fulfilled.
	 * interrupt_and_join() is a convenience method that implements this
	 * pattern.
	 */
	void interrupt() {
		int ret;

		boost::thread::interrupt();
		do {
			ret = pthread_kill(native_handle(),
				INTERRUPTION_SIGNAL);
		} while (ret == EINTR);
	}

	/**
	 * Keep interrupting the thread until it's done, then join it.
	 *
	 * @throws boost::thread_interrupted The calling thread has been
	 *    interrupted before we could join this thread.
	 */
	void interrupt_and_join() {
		bool done = false;
		while (!done) {
			interrupt();
			done = timed_join(boost::posix_time::millisec(10));
		}
	}

	/**
	 * Keep interrupting the thread until it's done, then join it.
	 * This method will keep trying for at most timeout milliseconds.
	 *
	 * @param timeout The maximum number of milliseconds that this method
	 *                should keep trying.
	 * @return True if the thread was successfully joined, false if the
	 *         timeout has been reached.
	 * @throws boost::thread_interrupted The calling thread has been
	 *    interrupted before we could join this thread.
	 */
	bool interrupt_and_join(unsigned int timeout) {
		bool joined = false, timed_out = false;
		boost::posix_time::ptime deadline =
			boost::posix_time::microsec_clock::local_time() +
			boost::posix_time::millisec(timeout);
		while (!joined && !timed_out) {
			interrupt();
			joined = timed_join(boost::posix_time::millisec(10));
			timed_out = !joined && boost::posix_time::microsec_clock::local_time() > deadline;
		}
		return joined;
	}

	/**
	 * Interrupt and join multiple threads in a way that's more efficient than calling
	 * interrupt_and_join() on each thread individually. It iterates over all threads,
	 * interrupts each one without joining it, then waits until at least one thread
	 * is joinable. This is repeated until all threads are joined.
	 *
	 * @param threads An array of threads to join.
	 * @param size The number of elements in threads.
	 * @throws boost::thread_interrupted The calling thread has been
	 *    interrupted before all threads have been joined. Some threads
	 *    may have been successfully joined while others haven't.
	 */
	static void interrupt_and_join_multiple(oxt::thread **threads, unsigned int size) {
		std::list<oxt::thread *> remaining_threads;
		std::list<oxt::thread *>::iterator it, current;
		oxt::thread *thread;
		unsigned int i;

		for (i = 0; i < size; i++) {
			remaining_threads.push_back(threads[i]);
		}

		while (!remaining_threads.empty()) {
			for (it = remaining_threads.begin(); it != remaining_threads.end(); it++) {
				thread = *it;
				thread->interrupt();
			}
			for (it = remaining_threads.begin(); it != remaining_threads.end(); it++) {
				thread = *it;
				if (thread->timed_join(boost::posix_time::millisec(0))) {
					current = it;
					it--;
					remaining_threads.erase(current);
				}
			}
			if (!remaining_threads.empty()) {
				syscalls::usleep(10000);
			}
		}
	}
};

/**
 * Like boost::lock_guard, but is interruptable.
 */
template<typename TimedLockable>
class interruptable_lock_guard {
private:
	TimedLockable &mutex;
public:
	interruptable_lock_guard(TimedLockable &m): mutex(m) {
		bool locked = false;

		while (!locked) {
			locked = m.timed_lock(boost::posix_time::milliseconds(10));
			if (!locked) {
				boost::this_thread::interruption_point();
			}
		}
	}

	~interruptable_lock_guard() {
		mutex.unlock();
	}
};

} // namespace oxt

#endif /* _OXT_THREAD_HPP_ */

<commit_msg>Increase interruptable_lock_guard busy loop sleep time to 20 msec.<commit_after>/*
 * OXT - OS eXtensions for boosT
 * Provides important functionality necessary for writing robust server software.
 *
 * Copyright (c) 2010 Phusion
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifndef _OXT_THREAD_HPP_
#define _OXT_THREAD_HPP_

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "system_calls.hpp"
#include "backtrace.hpp"
#ifdef OXT_BACKTRACE_IS_ENABLED
	#include <sstream>
#endif
#include <string>
#include <list>
#include <unistd.h>
#include <limits.h>  // for PTHREAD_STACK_MIN

namespace oxt {

extern boost::mutex _next_thread_number_mutex;
extern unsigned int _next_thread_number;

/**
 * Enhanced thread class with support for:
 * - user-defined stack size.
 * - system call interruption.
 * - backtraces.
 */
class thread: public boost::thread {
private:
	struct thread_data {
		std::string name;
		#ifdef OXT_BACKTRACE_IS_ENABLED
			thread_registration *registration;
			boost::mutex registration_lock;
			bool done;
		#endif
	};

	typedef boost::shared_ptr<thread_data> thread_data_ptr;

	thread_data_ptr data;

	void initialize_data(const std::string &thread_name) {
		data = thread_data_ptr(new thread_data());
		if (thread_name.empty()) {
			boost::mutex::scoped_lock l(_next_thread_number_mutex);
			std::stringstream str;

			str << "Thread #" << _next_thread_number;
			_next_thread_number++;
			data->name = str.str();
		} else {
			data->name = thread_name;
		}
		#ifdef OXT_BACKTRACE_IS_ENABLED
			data->registration = NULL;
			data->done = false;
		#endif
	}

	static void thread_main(boost::function<void ()> func, thread_data_ptr data) {
		#ifdef OXT_BACKTRACE_IS_ENABLED
			initialize_backtrace_support_for_this_thread i(data->name);
			data->registration = i.registration;
		#endif

		#ifdef OXT_BACKTRACE_IS_ENABLED
			// Put finalization code in a struct destructor,
			// for exception safety.
			struct finalization_routines {
				thread_data_ptr &data;

				finalization_routines(thread_data_ptr &data_)
					: data(data_) {}

				~finalization_routines() {
					boost::mutex::scoped_lock l(data->registration_lock);
					data->registration = NULL;
					data->done = true;
				}
			};
			finalization_routines f(data);
		#endif

		func();
	}

public:
	/**
	 * Create a new thread.
	 *
	 * @param func A function object which will be called as the thread's
	 *     main function. This object must be copyable. <tt>func</tt> is
	 *     copied into storage managed internally by the thread library,
	 *     and that copy is invoked on a newly-created thread of execution.
	 * @param name A name for this thread. If an empty string is given, then
	 *     a name will be automatically chosen.
	 * @param stack_size The stack size, in bytes, that the thread should
	 *     have. If 0 is specified, the operating system's default stack
	 *     size is used. If non-zero is specified, and the size is smaller
	 *     than the operating system's minimum stack size, then the operating
	 *     system's minimum stack size will be used.
	 * @pre func must be copyable.
	 * @throws boost::thread_resource_error Something went wrong during
	 *     creation of the thread.
	 */
	explicit thread(boost::function<void ()> func, const std::string &name = "", unsigned int stack_size = 0) {
		initialize_data(name);

		set_thread_main_function(boost::bind(thread_main, func, data));

		unsigned long min_stack_size;
		bool stack_min_size_defined;
		bool round_stack_size;

		#ifdef PTHREAD_STACK_MIN
			// PTHREAD_STACK_MIN may not be a constant macro so we need
			// to evaluate it dynamically.
			min_stack_size = PTHREAD_STACK_MIN;
			stack_min_size_defined = true;
		#else
			// Assume minimum stack size is 128 KB.
			min_stack_size = 128 * 1024;
			stack_min_size_defined = false;
		#endif
		if (stack_size != 0 && stack_size < min_stack_size) {
			stack_size = min_stack_size;
			round_stack_size = !stack_min_size_defined;
		} else {
			round_stack_size = true;
		}

		if (round_stack_size) {
			// Round stack size up to page boundary.
			long page_size;
			#if defined(_SC_PAGESIZE)
				page_size = sysconf(_SC_PAGESIZE);
			#elif defined(_SC_PAGE_SIZE)
				page_size = sysconf(_SC_PAGE_SIZE);
			#elif defined(PAGESIZE)
				page_size = sysconf(PAGESIZE);
			#elif defined(PAGE_SIZE)
				page_size = sysconf(PAGE_SIZE);
			#else
				page_size = getpagesize();
			#endif
			if (stack_size % page_size != 0) {
				stack_size = stack_size - (stack_size % page_size) + page_size;
			}
		}

		start_thread(stack_size);
	}

	/**
	 * Return this thread's name. The name was set during construction.
	 */
	std::string name() const throw() {
		return data->name;
	}

	/**
	 * Return the current backtrace of the thread of execution, as a string.
	 */
	std::string backtrace() const throw() {
		#ifdef OXT_BACKTRACE_IS_ENABLED
			boost::mutex::scoped_lock l(data->registration_lock);
			if (data->registration == NULL) {
				if (data->done) {
					return "     (no backtrace: thread has quit)";
				} else {
					return "     (no backtrace: thread hasn't been started yet)";
				}
			} else {
				spin_lock::scoped_lock l2(*data->registration->backtrace_lock);
				return _format_backtrace(data->registration->backtrace);
			}
		#else
			return "    (backtrace support disabled during compile time)";
		#endif
	}

	/**
	 * Return the backtraces of all oxt::thread threads, as well as that of the
	 * main thread, in a nicely formatted string.
	 */
	static std::string all_backtraces() throw() {
		#ifdef OXT_BACKTRACE_IS_ENABLED
			boost::mutex::scoped_lock l(_thread_registration_mutex);
			list<thread_registration *>::const_iterator it;
			std::stringstream result;

			for (it = _registered_threads.begin(); it != _registered_threads.end(); it++) {
				thread_registration *r = *it;
				result << "Thread '" << r->name << "':" << endl;

				spin_lock::scoped_lock l(*r->backtrace_lock);
				result << _format_backtrace(r->backtrace) << endl;
			}
			return result.str();
		#else
			return "(backtrace support disabled during compile time)";
		#endif
	}

	/**
	 * Interrupt the thread. This method behaves just like
	 * boost::thread::interrupt(), but will also respect the interruption
	 * points defined in oxt::syscalls.
	 *
	 * Note that an interruption request may get lost, depending on the
	 * current execution point of the thread. Thus, one should call this
	 * method in a loop, until a certain goal condition has been fulfilled.
	 * interrupt_and_join() is a convenience method that implements this
	 * pattern.
	 */
	void interrupt() {
		int ret;

		boost::thread::interrupt();
		do {
			ret = pthread_kill(native_handle(),
				INTERRUPTION_SIGNAL);
		} while (ret == EINTR);
	}

	/**
	 * Keep interrupting the thread until it's done, then join it.
	 *
	 * @throws boost::thread_interrupted The calling thread has been
	 *    interrupted before we could join this thread.
	 */
	void interrupt_and_join() {
		bool done = false;
		while (!done) {
			interrupt();
			done = timed_join(boost::posix_time::millisec(10));
		}
	}

	/**
	 * Keep interrupting the thread until it's done, then join it.
	 * This method will keep trying for at most timeout milliseconds.
	 *
	 * @param timeout The maximum number of milliseconds that this method
	 *                should keep trying.
	 * @return True if the thread was successfully joined, false if the
	 *         timeout has been reached.
	 * @throws boost::thread_interrupted The calling thread has been
	 *    interrupted before we could join this thread.
	 */
	bool interrupt_and_join(unsigned int timeout) {
		bool joined = false, timed_out = false;
		boost::posix_time::ptime deadline =
			boost::posix_time::microsec_clock::local_time() +
			boost::posix_time::millisec(timeout);
		while (!joined && !timed_out) {
			interrupt();
			joined = timed_join(boost::posix_time::millisec(10));
			timed_out = !joined && boost::posix_time::microsec_clock::local_time() > deadline;
		}
		return joined;
	}

	/**
	 * Interrupt and join multiple threads in a way that's more efficient than calling
	 * interrupt_and_join() on each thread individually. It iterates over all threads,
	 * interrupts each one without joining it, then waits until at least one thread
	 * is joinable. This is repeated until all threads are joined.
	 *
	 * @param threads An array of threads to join.
	 * @param size The number of elements in threads.
	 * @throws boost::thread_interrupted The calling thread has been
	 *    interrupted before all threads have been joined. Some threads
	 *    may have been successfully joined while others haven't.
	 */
	static void interrupt_and_join_multiple(oxt::thread **threads, unsigned int size) {
		std::list<oxt::thread *> remaining_threads;
		std::list<oxt::thread *>::iterator it, current;
		oxt::thread *thread;
		unsigned int i;

		for (i = 0; i < size; i++) {
			remaining_threads.push_back(threads[i]);
		}

		while (!remaining_threads.empty()) {
			for (it = remaining_threads.begin(); it != remaining_threads.end(); it++) {
				thread = *it;
				thread->interrupt();
			}
			for (it = remaining_threads.begin(); it != remaining_threads.end(); it++) {
				thread = *it;
				if (thread->timed_join(boost::posix_time::millisec(0))) {
					current = it;
					it--;
					remaining_threads.erase(current);
				}
			}
			if (!remaining_threads.empty()) {
				syscalls::usleep(10000);
			}
		}
	}
};

/**
 * Like boost::lock_guard, but is interruptable.
 */
template<typename TimedLockable>
class interruptable_lock_guard {
private:
	TimedLockable &mutex;
public:
	interruptable_lock_guard(TimedLockable &m): mutex(m) {
		bool locked = false;

		while (!locked) {
			locked = m.timed_lock(boost::posix_time::milliseconds(20));
			if (!locked) {
				boost::this_thread::interruption_point();
			}
		}
	}

	~interruptable_lock_guard() {
		mutex.unlock();
	}
};

} // namespace oxt

#endif /* _OXT_THREAD_HPP_ */

<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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 <memory>
#include <string>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferInputPoseBehavior.h"
#include "SurgSim/Devices/MultiAxis/MultiAxisDevice.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Input/InputComponent.h"
#include "SurgSim/Input/InputManager.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgSceneryRepresentation.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Physics/PhysicsManager.h"
#include "Examples/ExampleStapling/AddStapleBehavior.h"

/// Load scenery object from file
/// \param name Name of this scenery representation.
/// \param fileName Name of the file from which the scenery representation is loaded.
/// \return A SceneElement containing the scenery representation.
std::shared_ptr<SurgSim::Framework::SceneElement> createSceneryObject(const std::string& name,
																	  const std::string& fileName)
{
	std::shared_ptr<SurgSim::Graphics::SceneryRepresentation> sceneryRepresentation =
		std::make_shared<SurgSim::Graphics::OsgSceneryRepresentation>(name + "SceneryRepresentation");
	sceneryRepresentation->setFileName(fileName);

	auto sceneElement = std::make_shared<SurgSim::Blocks::BasicSceneElement>(name + "SceneElement");
	sceneElement->addComponent(sceneryRepresentation);

	return sceneElement;
}

std::shared_ptr<SurgSim::Graphics::ViewElement> createView()
{
	auto view = std::make_shared<SurgSim::Graphics::OsgViewElement>("StaplingDemoView");

	view->enableManipulator(true);
	view->setManipulatorParameters(SurgSim::Math::Vector3d(0.0, 0.5, 0.5), SurgSim::Math::Vector3d::Zero());

	return view;
}

int main(int argc, char* argv[])
{
	auto behaviorManager = std::make_shared<SurgSim::Framework::BehaviorManager>();
	auto graphicsManager = std::make_shared<SurgSim::Graphics::OsgManager>();
	auto inputManager    = std::make_shared<SurgSim::Input::InputManager>();
	auto physicsManager  = std::make_shared<SurgSim::Physics::PhysicsManager>();

	auto runtime = std::make_shared<SurgSim::Framework::Runtime>("config.txt");
	runtime->addManager(behaviorManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(inputManager);
	runtime->addManager(physicsManager);

	auto toolDevice = std::make_shared<SurgSim::Device::MultiAxisDevice>("MultiAxisDevice");
	SURGSIM_ASSERT(toolDevice->initialize() == true) <<
		"Could not initialize device " << toolDevice->getName() << " for the tool.\n";
	inputManager->addDevice(toolDevice);

	std::shared_ptr<SurgSim::Framework::SceneElement> staplerSceneElement =
		createSceneryObject("stapler", "Geometry/stapler.obj");

	// In order to connect the stapler scenery representation to an input device, after create a SceneElement for it,
	// we need to retrieve the stapler scenery representation from the SceneElement.
	std::shared_ptr<SurgSim::Framework::Component> staplerComponent =
		staplerSceneElement->getComponent("staplerSceneryRepresentation");
	auto staplerSceneryRepresentation = std::static_pointer_cast<SurgSim::Framework::Representation>(staplerComponent);

	auto inputComponent = std::make_shared<SurgSim::Input::InputComponent>("input");
	inputComponent->setDeviceName("MultiAxisDevice");

	auto transferInputPose = std::make_shared<SurgSim::Blocks::TransferInputPoseBehavior>("Input to graphicalStapler");
	transferInputPose->setPoseSender(inputComponent);
	transferInputPose->setPoseReceiver(staplerSceneryRepresentation);

	auto addStapleBehavior = std::make_shared<AddStapleFromInputBehavior>("Staple");
	addStapleBehavior->setInputComponent(inputComponent);

	staplerSceneElement->addComponent(inputComponent);
	staplerSceneElement->addComponent(transferInputPose);
	staplerSceneElement->addComponent(addStapleBehavior);

	std::shared_ptr<SurgSim::Framework::Scene> scene = runtime->getScene();
	scene->addSceneElement(createSceneryObject("arm", "Geometry/forearm.osgb"));
	scene->addSceneElement(createView());
	scene->addSceneElement(staplerSceneElement);

	runtime->execute();

	return 0;
}
<commit_msg>Include all stapler parts into stapling demo.<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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 <memory>
#include <string>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferInputPoseBehavior.h"
#include "SurgSim/Devices/MultiAxis/MultiAxisDevice.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Framework/TransferPropertiesBehavior.h"
#include "SurgSim/Input/InputComponent.h"
#include "SurgSim/Input/InputManager.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgSceneryRepresentation.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Physics/PhysicsManager.h"
#include "Examples/ExampleStapling/AddStapleBehavior.h"

using SurgSim::Blocks::BasicSceneElement;
using SurgSim::Blocks::TransferInputPoseBehavior;
using SurgSim::Framework::BehaviorManager;
using SurgSim::Framework::Runtime;
using SurgSim::Framework::Scene;
using SurgSim::Framework::SceneElement;
using SurgSim::Framework::TransferPropertiesBehavior;
using SurgSim::Graphics::SceneryRepresentation;
using SurgSim::Graphics::ViewElement;
using SurgSim::Graphics::OsgManager;
using SurgSim::Graphics::OsgViewElement;
using SurgSim::Graphics::OsgSceneryRepresentation;
using SurgSim::Input::DeviceInterface;
using SurgSim::Input::InputComponent;
using SurgSim::Input::InputManager;
using SurgSim::Math::Vector3d;
using SurgSim::Physics::PhysicsManager;

/// Load scenery object from file
/// \param name Name of this scenery representation.
/// \param fileName Name of the file from which the scenery representation is loaded.
/// \return A SceneElement containing the scenery representation.
std::shared_ptr<SceneElement> createSceneryObject(const std::string& name, const std::string& fileName)
{
	std::shared_ptr<SceneryRepresentation> sceneryRepresentation =
		std::make_shared<OsgSceneryRepresentation>(name + "SceneryRepresentation");
	sceneryRepresentation->setFileName(fileName);

	std::shared_ptr<SceneElement> sceneElement = std::make_shared<BasicSceneElement>(name + "SceneElement");
	sceneElement->addComponent(sceneryRepresentation);

	return sceneElement;
}

std::shared_ptr<SceneElement> createStapler(const std::string& staplerName, const std::string& deviceName)
{
	std::shared_ptr<SceneryRepresentation> staplerHandle =
		std::make_shared<OsgSceneryRepresentation>(staplerName + "Handle");
	std::shared_ptr<SceneryRepresentation> staplerIndicator =
		std::make_shared<OsgSceneryRepresentation>(staplerName + "Indicator");
	std::shared_ptr<SceneryRepresentation> staplerMarkings=
		std::make_shared<OsgSceneryRepresentation>(staplerName + "Markings");
	std::shared_ptr<SceneryRepresentation> staplerTrigger =
		std::make_shared<OsgSceneryRepresentation>(staplerName + "Trigger");

	staplerHandle->setFileName("Geometry/stapler_handle.obj");
	staplerIndicator->setFileName("Geometry/stapler_indicator.obj");
	staplerMarkings->setFileName("Geometry/stapler_markings.obj");
	staplerTrigger->setFileName("Geometry/stapler_trigger.obj");

	std::shared_ptr<TransferPropertiesBehavior> glue = std::make_shared<TransferPropertiesBehavior>("StaplerGlue");
	glue->connect(staplerHandle, "pose", staplerIndicator, "pose");
	glue->connect(staplerHandle, "pose", staplerMarkings, "pose");
	glue->connect(staplerHandle, "pose", staplerTrigger, "pose");

	std::shared_ptr<InputComponent> inputComponent = std::make_shared<InputComponent>("input");
	inputComponent->setDeviceName(deviceName);

	std::shared_ptr<TransferInputPoseBehavior> transferInputPose =
		std::make_shared<TransferInputPoseBehavior>("Input to graphicalStapler");
	transferInputPose->setPoseSender(inputComponent);
	transferInputPose->setPoseReceiver(staplerHandle);

	std::shared_ptr<AddStapleFromInputBehavior> addStapleBehavior =
		std::make_shared<AddStapleFromInputBehavior>("Staple");
	addStapleBehavior->setInputComponent(inputComponent);

	std::shared_ptr<SceneElement> sceneElement = std::make_shared<BasicSceneElement>(staplerName + "SceneElement");
	sceneElement->addComponent(staplerHandle);
	sceneElement->addComponent(staplerIndicator);
	sceneElement->addComponent(staplerMarkings);
	sceneElement->addComponent(staplerTrigger);
	sceneElement->addComponent(glue);
	sceneElement->addComponent(inputComponent);
	sceneElement->addComponent(transferInputPose);
	sceneElement->addComponent(addStapleBehavior);

	return sceneElement;
}

std::shared_ptr<ViewElement> createView()
{
	std::shared_ptr<OsgViewElement> view = std::make_shared<OsgViewElement>("StaplingDemoView");

	view->enableManipulator(true);
	view->setManipulatorParameters(Vector3d(0.0, 0.5, 0.5), Vector3d::Zero());

	return view;
}

int main(int argc, char* argv[])
{
	const std::string deviceName = "MultiAxisDevice";

	std::shared_ptr<BehaviorManager> behaviorManager = std::make_shared<BehaviorManager>();
	std::shared_ptr<OsgManager> graphicsManager = std::make_shared<OsgManager>();
	std::shared_ptr<InputManager> inputManager = std::make_shared<InputManager>();
	std::shared_ptr<PhysicsManager> physicsManager = std::make_shared<PhysicsManager>();

	std::shared_ptr<Runtime> runtime = std::make_shared<Runtime>("config.txt");
	runtime->addManager(behaviorManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(inputManager);
	runtime->addManager(physicsManager);

	std::shared_ptr<DeviceInterface> toolDevice = std::make_shared<SurgSim::Device::MultiAxisDevice>(deviceName);
	SURGSIM_ASSERT(toolDevice->initialize() == true) <<
		"Could not initialize device " << toolDevice->getName() << " for the tool.\n";
	inputManager->addDevice(toolDevice);

	std::shared_ptr<Scene> scene = runtime->getScene();
	scene->addSceneElement(createSceneryObject("arm", "Geometry/forearm.osgb"));
	scene->addSceneElement(createView());
	scene->addSceneElement(createStapler("stapler", deviceName));

	runtime->execute();

	return 0;
}
<|endoftext|>


<commit_before>#include <ruby.h>
#if defined(HAVE_RUBY_ENCODING_H)
#include <ruby/encoding.h>
#endif

#include "unf/normalizer.hh"

extern "C" {
  VALUE unf_allocate(VALUE klass);
  VALUE unf_initialize(VALUE self);
  VALUE unf_delete(UNF::Normalizer* ptr);
  VALUE unf_normalize(VALUE self, VALUE source, VALUE normalization_form);

  ID FORM_NFD;
  ID FORM_NFC;
  ID FORM_NFKD;
  ID FORM_NFKC;

  void Init_unf_ext() {
    VALUE mdl = rb_define_module("UNF");

    VALUE cls = rb_define_class_under(mdl, "Normalizer", rb_cObject);
    rb_define_alloc_func(cls, unf_allocate);
    rb_define_method(cls, "initialize", (VALUE (*)(...))unf_initialize, 0);
    rb_define_method(cls, "normalize", (VALUE (*)(...))unf_normalize, 2);

    FORM_NFD = rb_intern("nfd");
    FORM_NFC = rb_intern("nfc");
    FORM_NFKD= rb_intern("nfkd");
    FORM_NFKC= rb_intern("nfkc");
  }

  VALUE unf_allocate(VALUE klass) {
    UNF::Normalizer* ptr;
    VALUE obj = Data_Make_Struct(klass, UNF::Normalizer, NULL, unf_delete, ptr);
    new ((void*)ptr) UNF::Normalizer;
    return obj;
  }

  VALUE unf_initialize(VALUE self) {
    return self;
  }

  VALUE unf_delete(UNF::Normalizer* ptr) {
    ptr->~Normalizer();
    ruby_xfree(ptr);
  }

  VALUE unf_normalize(VALUE self, VALUE source, VALUE normalization_form) {
    UNF::Normalizer* ptr;
    Data_Get_Struct(self, UNF::Normalizer, ptr);

    const char* src = StringValueCStr(source);
    const char* rlt;
    ID form_id = SYM2ID(normalization_form);

    if(form_id == FORM_NFD)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFD);
    else if(form_id == FORM_NFC)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFC);
    else if(form_id == FORM_NFKD)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFKD);
    else if(form_id == FORM_NFKC)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFKC);
    else
      rb_raise(rb_eArgError, "Specified Normalization-Form is unknown. Please select one from among :nfc, :nfd, :nfkc, :nfkd.");

#if defined(HAVE_RUBY_ENCODING_H)
    return rb_enc_str_new(rlt, strlen(rlt), rb_utf8_encoding());
#else
    return rb_str_new2(rlt);
#endif
  }
}
<commit_msg>Include ruby.h after unf/normalizer.hh so fix build with 1.8 on win32.<commit_after>#include "unf/normalizer.hh"

#include <ruby.h>
#if defined(HAVE_RUBY_ENCODING_H)
#include <ruby/encoding.h>
#endif

extern "C" {
  VALUE unf_allocate(VALUE klass);
  VALUE unf_initialize(VALUE self);
  VALUE unf_delete(UNF::Normalizer* ptr);
  VALUE unf_normalize(VALUE self, VALUE source, VALUE normalization_form);

  ID FORM_NFD;
  ID FORM_NFC;
  ID FORM_NFKD;
  ID FORM_NFKC;

  void Init_unf_ext() {
    VALUE mdl = rb_define_module("UNF");

    VALUE cls = rb_define_class_under(mdl, "Normalizer", rb_cObject);
    rb_define_alloc_func(cls, unf_allocate);
    rb_define_method(cls, "initialize", (VALUE (*)(...))unf_initialize, 0);
    rb_define_method(cls, "normalize", (VALUE (*)(...))unf_normalize, 2);

    FORM_NFD = rb_intern("nfd");
    FORM_NFC = rb_intern("nfc");
    FORM_NFKD= rb_intern("nfkd");
    FORM_NFKC= rb_intern("nfkc");
  }

  VALUE unf_allocate(VALUE klass) {
    UNF::Normalizer* ptr;
    VALUE obj = Data_Make_Struct(klass, UNF::Normalizer, NULL, unf_delete, ptr);
    new ((void*)ptr) UNF::Normalizer;
    return obj;
  }

  VALUE unf_initialize(VALUE self) {
    return self;
  }

  VALUE unf_delete(UNF::Normalizer* ptr) {
    ptr->~Normalizer();
    ruby_xfree(ptr);
  }

  VALUE unf_normalize(VALUE self, VALUE source, VALUE normalization_form) {
    UNF::Normalizer* ptr;
    Data_Get_Struct(self, UNF::Normalizer, ptr);

    const char* src = StringValueCStr(source);
    const char* rlt;
    ID form_id = SYM2ID(normalization_form);

    if(form_id == FORM_NFD)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFD);
    else if(form_id == FORM_NFC)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFC);
    else if(form_id == FORM_NFKD)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFKD);
    else if(form_id == FORM_NFKC)
      rlt = ptr->normalize(src, UNF::Normalizer::FORM_NFKC);
    else
      rb_raise(rb_eArgError, "Specified Normalization-Form is unknown. Please select one from among :nfc, :nfd, :nfkc, :nfkd.");

#if defined(HAVE_RUBY_ENCODING_H)
    return rb_enc_str_new(rlt, strlen(rlt), rb_utf8_encoding());
#else
    return rb_str_new2(rlt);
#endif
  }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: serviceinfohelper.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-19 16:19:05 $
 *
 *  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: 2002 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_SERVICEINFOHELPER_HXX_
#define CONFIGMGR_SERVICEINFOHELPER_HXX_

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

namespace configmgr
{
// -----------------------------------------------------------------------------
    namespace uno   = ::com::sun::star::uno;
    namespace lang  = ::com::sun::star::lang;
    using ::rtl::OUString;
// -----------------------------------------------------------------------------

    typedef sal_Char const * AsciiServiceName;
// -----------------------------------------------------------------------------

    /// POD struct describing the registration information of a service implementation
    struct ServiceRegistrationInfo
    {
        /// The implementation name of this service implementation
        AsciiServiceName implementationName;
        /// The services for which this service implementation is registered
        AsciiServiceName const * registeredServiceNames;
    };
// -----------------------------------------------------------------------------

    /// POD struct describing the implementation information of a service implementation
    struct ServiceImplementationInfo
    {
        /// The implementation name of this service implementation
        AsciiServiceName implementationName;
        /// The services for which this service implementation is registered
        AsciiServiceName const * registeredServiceNames;
        /// Additional services implemented by this service implementation, for which it is not registered
        AsciiServiceName const * additionalServiceNames;
    };
// -----------------------------------------------------------------------------

    // ServiceImplementationInfo has a compatible initial sequence with struct ServiceRegistrationInfo

    inline
    ServiceRegistrationInfo const *
        getRegistrationInfo(ServiceImplementationInfo const * _info)
    {
        return reinterpret_cast<ServiceRegistrationInfo const *>(_info);
    }
// -----------------------------------------------------------------------------

    /// POD struct describing the registration information of a singleton
    struct SingletonRegistrationInfo
    {
        /// The name of this singleton
        AsciiServiceName singletonName;
        /// The implementation, which owns this singleton
        AsciiServiceName implementationName;
        /// The service, which should be instatiated for this singleton
        AsciiServiceName instantiatedServiceName;
        /// A name for a pseudo-implementation, which is mapped to this singleton
        ServiceRegistrationInfo const * mappedImplementation;
    };
// -----------------------------------------------------------------------------

    class ServiceRegistrationHelper
    {
        ServiceRegistrationInfo const*const m_info;

    public:
        ServiceRegistrationHelper(ServiceRegistrationInfo const* _info)
        : m_info(_info)
        {}

        ServiceRegistrationHelper(ServiceImplementationInfo const* _info)
        : m_info(getRegistrationInfo(_info))
        {}

        sal_Int32 countServices() const;

        OUString getImplementationName( ) const
            throw(uno::RuntimeException);

        uno::Sequence< OUString > getRegisteredServiceNames( ) const
            throw(uno::RuntimeException);
    };
// -----------------------------------------------------------------------------

    class ServiceInfoHelper
    {
        ServiceImplementationInfo const*const m_info;

    public:
        ServiceInfoHelper(ServiceImplementationInfo const* _info)
        : m_info(_info)
        {}

        sal_Int32 countServices() const;

        OUString getImplementationName( ) const
            throw(uno::RuntimeException);

        sal_Bool supportsService( OUString const & ServiceName ) const
            throw(uno::RuntimeException);

        uno::Sequence< OUString > getSupportedServiceNames( ) const
            throw(uno::RuntimeException);
    };
// -----------------------------------------------------------------------------

} // namespace configmgr

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.3.194); FILE MERGED 2005/09/05 17:04:35 rt 1.3.194.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: serviceinfohelper.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 03:55:54 $
 *
 *  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 CONFIGMGR_SERVICEINFOHELPER_HXX_
#define CONFIGMGR_SERVICEINFOHELPER_HXX_

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

namespace configmgr
{
// -----------------------------------------------------------------------------
    namespace uno   = ::com::sun::star::uno;
    namespace lang  = ::com::sun::star::lang;
    using ::rtl::OUString;
// -----------------------------------------------------------------------------

    typedef sal_Char const * AsciiServiceName;
// -----------------------------------------------------------------------------

    /// POD struct describing the registration information of a service implementation
    struct ServiceRegistrationInfo
    {
        /// The implementation name of this service implementation
        AsciiServiceName implementationName;
        /// The services for which this service implementation is registered
        AsciiServiceName const * registeredServiceNames;
    };
// -----------------------------------------------------------------------------

    /// POD struct describing the implementation information of a service implementation
    struct ServiceImplementationInfo
    {
        /// The implementation name of this service implementation
        AsciiServiceName implementationName;
        /// The services for which this service implementation is registered
        AsciiServiceName const * registeredServiceNames;
        /// Additional services implemented by this service implementation, for which it is not registered
        AsciiServiceName const * additionalServiceNames;
    };
// -----------------------------------------------------------------------------

    // ServiceImplementationInfo has a compatible initial sequence with struct ServiceRegistrationInfo

    inline
    ServiceRegistrationInfo const *
        getRegistrationInfo(ServiceImplementationInfo const * _info)
    {
        return reinterpret_cast<ServiceRegistrationInfo const *>(_info);
    }
// -----------------------------------------------------------------------------

    /// POD struct describing the registration information of a singleton
    struct SingletonRegistrationInfo
    {
        /// The name of this singleton
        AsciiServiceName singletonName;
        /// The implementation, which owns this singleton
        AsciiServiceName implementationName;
        /// The service, which should be instatiated for this singleton
        AsciiServiceName instantiatedServiceName;
        /// A name for a pseudo-implementation, which is mapped to this singleton
        ServiceRegistrationInfo const * mappedImplementation;
    };
// -----------------------------------------------------------------------------

    class ServiceRegistrationHelper
    {
        ServiceRegistrationInfo const*const m_info;

    public:
        ServiceRegistrationHelper(ServiceRegistrationInfo const* _info)
        : m_info(_info)
        {}

        ServiceRegistrationHelper(ServiceImplementationInfo const* _info)
        : m_info(getRegistrationInfo(_info))
        {}

        sal_Int32 countServices() const;

        OUString getImplementationName( ) const
            throw(uno::RuntimeException);

        uno::Sequence< OUString > getRegisteredServiceNames( ) const
            throw(uno::RuntimeException);
    };
// -----------------------------------------------------------------------------

    class ServiceInfoHelper
    {
        ServiceImplementationInfo const*const m_info;

    public:
        ServiceInfoHelper(ServiceImplementationInfo const* _info)
        : m_info(_info)
        {}

        sal_Int32 countServices() const;

        OUString getImplementationName( ) const
            throw(uno::RuntimeException);

        sal_Bool supportsService( OUString const & ServiceName ) const
            throw(uno::RuntimeException);

        uno::Sequence< OUString > getSupportedServiceNames( ) const
            throw(uno::RuntimeException);
    };
// -----------------------------------------------------------------------------

} // namespace configmgr

#endif

<|endoftext|>


<commit_before>#include <jni.h>
#include "demopkg_Process.h"

JNIEXPORT void JNICALL Java_demopkg_Process_nativeLongOperation
  (JNIEnv *env, jobject owner, jobject param1)
{
	jclass cls = env->GetObjectClass(param1);
	jmethodID mid = env->GetMethodID(cls, "OnPercent", "(I)V");
    if (mid == NULL) {
		printf("1. not found method..\n");
        return;
    } else printf("1. found method!\n");
	//env->CallVoidMethod(owner, mid);//error
	for (int i=1; i<=100; i++)
		env->CallVoidMethod(param1, mid, i);//ok
	mid = env->GetMethodID(cls, "OnPercentEx", "(Ldemopkg/CmplxStruct;)V");
    if (mid == NULL) {
		printf("2. not found method..\n");
        return;
    } else printf("2. found method!\n");
	jclass clazz = env->FindClass("demopkg/CmplxStruct");
	jobject obj = env->AllocObject(clazz);
	if (obj == NULL) {
		printf("2. can't alloc..\n");
        return;
    } else printf("2. alloc ok!\n");
	env->CallVoidMethod(param1, mid, obj);
}<commit_msg>set integer to field of callback param<commit_after>#include <jni.h>
#include "demopkg_Process.h"

JNIEXPORT void JNICALL Java_demopkg_Process_nativeLongOperation
  (JNIEnv *env, jobject owner, jobject param1)
{
	jclass cls = env->GetObjectClass(param1);
	jmethodID mid = env->GetMethodID(cls, "OnPercent", "(I)V");
    if (mid == NULL) {
		printf("1. not found method..\n");
        return;
    } else printf("1. found method!\n");
	//env->CallVoidMethod(owner, mid);//error
	for (int i=1; i<=10; i++)
		env->CallVoidMethod(param1, mid, i);//ok
	mid = env->GetMethodID(cls, "OnPercentEx", "(Ldemopkg/CmplxStruct;)V");
    if (mid == NULL) {
		printf("2. not found method..\n");
        return;
    } else printf("2. found method!\n");
	jclass clazz = env->FindClass("demopkg/CmplxStruct");
	jobject obj = env->AllocObject(clazz);
	if (obj == NULL) {
		printf("2. can't alloc..\n");
        return;
    } else printf("2. alloc ok!\n");
	jfieldID fld = env->GetFieldID(clazz, "fieldI","I");
	env->SetIntField(obj, fld, 3);
	env->CallVoidMethod(param1, mid, obj);
}<|endoftext|>


<commit_before>/*
 * vector-benches.cpp
 *
 * Benchmarks relating to SSE and AVX instructions.
 */

#if !UARCH_BENCH_PORTABLE

#include <immintrin.h>

#include "benchmark.hpp"
#include "opt-control.hpp"

extern "C" {

bench2_f bypass_vmovdqa_latency;
bench2_f bypass_vmovdqu_latency;
bench2_f bypass_vmovups_latency;
bench2_f bypass_vmovupd_latency;

bench2_f bypass_movd_latency;
bench2_f bypass_movq_latency;

bench2_f vector_load_load_lat_movdqu_0_xmm;
bench2_f vector_load_load_lat_vmovdqu_0_xmm;
bench2_f vector_load_load_lat_lddqu_0_xmm;
bench2_f vector_load_load_lat_vlddqu_0_xmm;
bench2_f vector_load_load_lat_vmovdqu_0_ymm;
bench2_f vector_load_load_lat_vmovdqu32_0_zmm;

bench2_f vector_load_load_lat_movdqu_63_xmm;
bench2_f vector_load_load_lat_vmovdqu_63_xmm;
bench2_f vector_load_load_lat_lddqu_63_xmm;
bench2_f vector_load_load_lat_vlddqu_63_xmm;
bench2_f vector_load_load_lat_vmovdqu_63_ymm;
bench2_f vector_load_load_lat_vmovdqu32_63_zmm;

bench2_f p01_fusion_p1;
bench2_f p01_fusion_p0;

}

/**
 * Specialization of modify for double to use the xmm
 * register type (x86 specific).
 */
HEDLEY_ALWAYS_INLINE
static void modify(__m256i& x) {
    __asm__ volatile (" " :"+x"(x)::);
}

HEDLEY_NEVER_INLINE
long intrinsic_bench(uint64_t iters, void*) {

    __m256i total = _mm256_setzero_si256(), addend = _mm256_set1_epi32(1);

    do {
        for (int i = 0; i < 4; i++) {
            total = _mm256_add_epi32(total, addend);
            modify(total);
        }
    } while (--iters);

    return _mm256_extract_epi32(total, 0);
}

template <typename TIMER>
void register_vector(GroupList& list) {
    {
        std::shared_ptr<BenchmarkGroup> group = std::make_shared<BenchmarkGroup>("vector/bypass", "Vector unit bypass latency");
        list.push_back(group);

        auto maker = DeltaMaker<TIMER>(group.get(), 100000);

        maker.template make<bypass_vmovdqa_latency>("movdqa", "movdqa [mem] -> paddb latency", 1);
        maker.template make<bypass_vmovdqu_latency>("movdqu", "movdqu [mem] -> paddb latency", 1);
        maker.template make<bypass_vmovups_latency>("movups", "movups [mem] -> paddb latency", 1);
        maker.template make<bypass_vmovupd_latency>("movupd", "movupd [mem] -> paddb latency", 1);

        maker.template make<bypass_movd_latency>("movd",   "movq rax,xmm0 -> xmm0,rax lat", 1);
        maker.template make<bypass_movq_latency>("movq",   "movq rax,xmm0 -> xmm0,rax lat", 1);

    }

    {
        std::shared_ptr<BenchmarkGroup> group = std::make_shared<BenchmarkGroup>("vector/load-load", "Vector load-load latency");
        list.push_back(group);

        auto maker = DeltaMaker<TIMER>(group.get(), 100000).setFeatures({AVX2});
        auto m512  = maker.setFeatures({AVX512F});

        maker.template make< vector_load_load_lat_movdqu_0_xmm  >(  "movdqu-aligned"    ,    "aligned  movdqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_0_xmm  >( "vmovdqu-aligned"    ,    "aligned vmovdqu xmm load lat", 1);
        maker.template make<  vector_load_load_lat_lddqu_0_xmm  >(   "lddqu-aligned"    ,    "aligned   lddqu xmm load lat", 1);
        maker.template make< vector_load_load_lat_vlddqu_0_xmm  >(  "vlddqu-aligned"    ,    "aligned  vlddqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_0_ymm  >( "vmovdqu-aligned-ymm",    "aligned vmovdqu ymm load lat", 1);
        m512 .template make<vector_load_load_lat_vmovdqu32_0_zmm>( "vmovdqu-aligned-zmm",    "aligned vmovdqu zmm load lat", 1);

        maker.template make< vector_load_load_lat_movdqu_63_xmm   >( "movdqu-misaligned"    , "misaligned  movdqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_63_xmm   >("vmovdqu-misaligned"    , "misaligned vmovdqu xmm load lat", 1);
        maker.template make<  vector_load_load_lat_lddqu_63_xmm   >(  "lddqu-misaligned"    , "misaligned   lddqu xmm load lat", 1);
        maker.template make< vector_load_load_lat_vlddqu_63_xmm   >( "vlddqu-misaligned"    , "misaligned  vlddqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_63_ymm   >("vmovdqu-misaligned-ymm", "misaligned vmovdqu ymm load lat", 1);
        m512 .template make<vector_load_load_lat_vmovdqu32_63_zmm>("vmovdqu-misaligned-zmm", "misaligned vmovdqu zmm load lat", 1);
    }

    {
        std::shared_ptr<BenchmarkGroup> group = std::make_shared<BenchmarkGroup>("vector/misc", "Miscellaneous vector benches");
        list.push_back(group);

        auto m512  = DeltaMaker<TIMER>(group.get(), 1000).setFeatures({AVX512F});

        m512.template make<p01_fusion_p1>("p01-fusion-p1", "check that scalar ops go to p1", 100);
        m512.template make<p01_fusion_p0>("p01-fusion-p0", "check that scalar ops go to p0", 100);

        auto maker = DeltaMaker<TIMER>(group.get()).setFeatures({AVX2});

        maker.template make<intrinsic_bench>("intrinsic", "demo how to write intrinsic bench", 4);
        maker.useLoopDelta().template make<intrinsic_bench>("intrinsic-loop-delta", "demo with loop delta", 4);
    }

}

#define REGISTER_ALL(CLOCK) template void register_vector<CLOCK>(GroupList& list);

ALL_TIMERS_X(REGISTER_ALL)

#endif // #if !UARCH_BENCH_PORTABLE

<commit_msg>make bench AVX2 specific<commit_after>/*
 * vector-benches.cpp
 *
 * Benchmarks relating to SSE and AVX instructions.
 */

#if !UARCH_BENCH_PORTABLE

#ifdef __AVX2__
#include <immintrin.h>
#endif

#include "benchmark.hpp"
#include "opt-control.hpp"

extern "C" {

bench2_f bypass_vmovdqa_latency;
bench2_f bypass_vmovdqu_latency;
bench2_f bypass_vmovups_latency;
bench2_f bypass_vmovupd_latency;

bench2_f bypass_movd_latency;
bench2_f bypass_movq_latency;

bench2_f vector_load_load_lat_movdqu_0_xmm;
bench2_f vector_load_load_lat_vmovdqu_0_xmm;
bench2_f vector_load_load_lat_lddqu_0_xmm;
bench2_f vector_load_load_lat_vlddqu_0_xmm;
bench2_f vector_load_load_lat_vmovdqu_0_ymm;
bench2_f vector_load_load_lat_vmovdqu32_0_zmm;

bench2_f vector_load_load_lat_movdqu_63_xmm;
bench2_f vector_load_load_lat_vmovdqu_63_xmm;
bench2_f vector_load_load_lat_lddqu_63_xmm;
bench2_f vector_load_load_lat_vlddqu_63_xmm;
bench2_f vector_load_load_lat_vmovdqu_63_ymm;
bench2_f vector_load_load_lat_vmovdqu32_63_zmm;

bench2_f p01_fusion_p1;
bench2_f p01_fusion_p0;

}

#ifdef __AVX2__

/**
 * Specialization of modify for double to use the xmm
 * register type (x86 specific).
 */
HEDLEY_ALWAYS_INLINE
static void modify(__m256i& x) {
    __asm__ volatile (" " :"+x"(x)::);
}

HEDLEY_NEVER_INLINE
long intrinsic_bench(uint64_t iters, void*) {

    __m256i total = _mm256_setzero_si256(), addend = _mm256_set1_epi32(1);

    do {
        for (int i = 0; i < 4; i++) {
            total = _mm256_add_epi32(total, addend);
            modify(total);
        }
    } while (--iters);

    return _mm256_extract_epi32(total, 0);
}

#endif

template <typename TIMER>
void register_vector(GroupList& list) {
    {
        std::shared_ptr<BenchmarkGroup> group = std::make_shared<BenchmarkGroup>("vector/bypass", "Vector unit bypass latency");
        list.push_back(group);

        auto maker = DeltaMaker<TIMER>(group.get(), 100000);

        maker.template make<bypass_vmovdqa_latency>("movdqa", "movdqa [mem] -> paddb latency", 1);
        maker.template make<bypass_vmovdqu_latency>("movdqu", "movdqu [mem] -> paddb latency", 1);
        maker.template make<bypass_vmovups_latency>("movups", "movups [mem] -> paddb latency", 1);
        maker.template make<bypass_vmovupd_latency>("movupd", "movupd [mem] -> paddb latency", 1);

        maker.template make<bypass_movd_latency>("movd",   "movq rax,xmm0 -> xmm0,rax lat", 1);
        maker.template make<bypass_movq_latency>("movq",   "movq rax,xmm0 -> xmm0,rax lat", 1);

    }

    {
        std::shared_ptr<BenchmarkGroup> group = std::make_shared<BenchmarkGroup>("vector/load-load", "Vector load-load latency");
        list.push_back(group);

        auto maker = DeltaMaker<TIMER>(group.get(), 100000).setFeatures({AVX2});
        auto m512  = maker.setFeatures({AVX512F});

        maker.template make< vector_load_load_lat_movdqu_0_xmm  >(  "movdqu-aligned"    ,    "aligned  movdqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_0_xmm  >( "vmovdqu-aligned"    ,    "aligned vmovdqu xmm load lat", 1);
        maker.template make<  vector_load_load_lat_lddqu_0_xmm  >(   "lddqu-aligned"    ,    "aligned   lddqu xmm load lat", 1);
        maker.template make< vector_load_load_lat_vlddqu_0_xmm  >(  "vlddqu-aligned"    ,    "aligned  vlddqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_0_ymm  >( "vmovdqu-aligned-ymm",    "aligned vmovdqu ymm load lat", 1);
        m512 .template make<vector_load_load_lat_vmovdqu32_0_zmm>( "vmovdqu-aligned-zmm",    "aligned vmovdqu zmm load lat", 1);

        maker.template make< vector_load_load_lat_movdqu_63_xmm   >( "movdqu-misaligned"    , "misaligned  movdqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_63_xmm   >("vmovdqu-misaligned"    , "misaligned vmovdqu xmm load lat", 1);
        maker.template make<  vector_load_load_lat_lddqu_63_xmm   >(  "lddqu-misaligned"    , "misaligned   lddqu xmm load lat", 1);
        maker.template make< vector_load_load_lat_vlddqu_63_xmm   >( "vlddqu-misaligned"    , "misaligned  vlddqu xmm load lat", 1);
        maker.template make<vector_load_load_lat_vmovdqu_63_ymm   >("vmovdqu-misaligned-ymm", "misaligned vmovdqu ymm load lat", 1);
        m512 .template make<vector_load_load_lat_vmovdqu32_63_zmm>("vmovdqu-misaligned-zmm", "misaligned vmovdqu zmm load lat", 1);
    }

    {
        std::shared_ptr<BenchmarkGroup> group = std::make_shared<BenchmarkGroup>("vector/misc", "Miscellaneous vector benches");
        list.push_back(group);

        auto m512  = DeltaMaker<TIMER>(group.get(), 1000).setFeatures({AVX512F});

        m512.template make<p01_fusion_p1>("p01-fusion-p1", "check that scalar ops go to p1", 100);
        m512.template make<p01_fusion_p0>("p01-fusion-p0", "check that scalar ops go to p0", 100);

#ifdef __AVX2__
        auto maker = DeltaMaker<TIMER>(group.get()).setFeatures({AVX2});

        maker.template make<intrinsic_bench>("intrinsic", "demo how to write intrinsic bench", 4);
        maker.useLoopDelta().template make<intrinsic_bench>("intrinsic-loop-delta", "demo with loop delta", 4);
#endif
    }

}

#define REGISTER_ALL(CLOCK) template void register_vector<CLOCK>(GroupList& list);

ALL_TIMERS_X(REGISTER_ALL)

#endif // #if !UARCH_BENCH_PORTABLE

<|endoftext|>


<commit_before>#include "Defuzzification.h"
#include "FuzzyLogic.h"
#include "InputFuzzySetTrapezoidal.h"
#include "InputFuzzySetTriangular.h"
#include "LibInfoFuzzyEngine.h"
#include "OutputFuzzySetTrapezoidal.h"
#include "OutputFuzzySetTriangular.h"

#include <UnitTest++/UnitTest++.h>

#include <iostream>

const double EPS{0.01};

SUITE(FuzzyEngine)
{
   TEST(mbs_InputFuzzySetTriangular)
   {
      std::cout << "--- mbs_InputFuzzySetTriangular" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 10, 20);

      ifz.setInput(-10.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(0.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(2.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(7.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(25.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetLeftTriangular)
   {
      std::cout << "--- mbs_InputFuzzySetLeftTriangular" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 5, 15);

      ifz.setInput(5.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetRightTriangular)
   {
      std::cout << "--- mbs_InputFuzzySetRightTriangular" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 15, 15);

      ifz.setInput(0.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetTrapezoidal)
   {
      std::cout << "--- mbs_InputFuzzySetTrapezoidal" << std::endl;
      InputFuzzySetTrapezoidal ifz("Test", 5, 10, 20, 40);

      ifz.setInput(-10.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(0.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(2.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(7.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(30.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(40.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(50.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetLeftTrapezoidal)
   {
      std::cout << "--- mbs_InputFuzzySetLeftTrapezoidal" << std::endl;
      InputFuzzySetTrapezoidal ifz("Test", 0, 0, 20, 40);

      ifz.setInput(0.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(30.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(40.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(50.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetRightTrapezoidal)
   {
      std::cout << "--- mbs_InputFuzzySetRightTrapezoidal" << std::endl;
      InputFuzzySetTrapezoidal ifz("Test", 5, 10, 20, 20);

      ifz.setInput(-10.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(0.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(2.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(7.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(30.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(defuz_OutputFuzzySetTriangular)
   {
      std::cout << "--- defuz_OutputFuzzySetTriangular" << std::endl;
      OutputFuzzySetTriangular ofz("Test", 5, 10, 20);

      ofz.setMbs(0.5);
      CHECK_CLOSE(7.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(15.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((7.5 + 15.0) / 2.0, ofz.meanOfMaximum(), EPS);
      ofz.clearMbs();

      ofz.setMbs(0.1);
      CHECK_CLOSE(5.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(19.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((5.5 + 19.0) / 2.0, ofz.meanOfMaximum(), EPS);
      std::cout << std::endl;
   }

   TEST(defuz_OutputFuzzySetTrapezoidal)
   {
      std::cout << "--- defuz_OutputFuzzySetTrapezoidal" << std::endl;
      OutputFuzzySetTrapezoidal ofz("Test", 0, 5, 10, 20);

      ofz.setMbs(0.5);
      CHECK_CLOSE(2.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(15.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((2.5 + 15.0) / 2.0, ofz.meanOfMaximum(), EPS);
      ofz.clearMbs();

      ofz.setMbs(0.1);
      CHECK_CLOSE(0.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(19.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((0.5 + 19.0) / 2.0, ofz.meanOfMaximum(), EPS);
      std::cout << std::endl;
   }

   TEST(defuz_OutputFuzzySetLeftTrapezoidal)
   {
      std::cout << "--- defuz_OutputFuzzySetLeftTrapezoidal" << std::endl;
      OutputFuzzySetTrapezoidal ofz("Test", 0, 0, 10, 20);

      ofz.setMbs(0.5);
      CHECK_CLOSE(0.0, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(15.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((0.0 + 15.0) / 2.0, ofz.meanOfMaximum(), EPS);
      ofz.clearMbs();

      ofz.setMbs(0.1);
      CHECK_CLOSE(0.0, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(19.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((0.0 + 19.0) / 2.0, ofz.meanOfMaximum(), EPS);
      std::cout << std::endl;
   }

   TEST(defuz_outputsFuzzySets)
   {
      std::cout << "-- defuz output Fuzzy Sets" << std::endl;
      OutputFuzzySetTrapezoidal ofz1("Test", 0, 1, 4, 5);
      OutputFuzzySetTrapezoidal ofz2("Test", 3, 4, 6, 7);
      OutputFuzzySetTrapezoidal ofz3("Test", 5, 6, 7, 8);
      std::vector<OutputFuzzySet *> all{&ofz1, &ofz2, &ofz3};

      ofz1.setMbs(0.3);
      ofz2.setMbs(0.5);
      ofz3.setMbs(1.0);
      CHECK_CLOSE(6.0, defuzFirstOfMaxima(all), EPS);
      CHECK_CLOSE(6.5, defuzMeanOfMaximum(all), EPS);
      CHECK_CLOSE(7.0, defuzLastOfMaxima(all), EPS);
      CHECK_CLOSE(5.416, defuzWeightedAverage(all), EPS);
      std::cout << std::endl;
   }

   TEST(FuzzyLogic_or)
   {
      std::cout << "-- Fuzzy logic OR" << std::endl;
      InputFuzzySetTriangular ifz1("Test", 5, 10, 15);
      InputFuzzySetTriangular ifz2("Test", 10, 15, 20);
      OutputFuzzySetTriangular ofz("Test", 0, 5, 10);

      ifz1.setInput(12.5);
      ifz2.setInput(12.5);
      ofz = ifz1 or ifz2;
      CHECK_CLOSE(0.5, ofz.getMbs(), EPS);
      auto mom = ofz.meanOfMaximum();
      std::cout << std::endl;
   }

   TEST(FuzzyLogic_and)
   {
      std::cout << "-- Fuzzy logic AND" << std::endl;
      InputFuzzySetTriangular ifz1("Test", 5, 10, 15);
      InputFuzzySetTriangular ifz2("Test", 10, 15, 20);
      OutputFuzzySetTriangular ofz("Test", 0, 5, 10);

      ifz1.setInput(10);
      ifz2.setInput(10);
      ofz = ifz1 and ifz2;
      CHECK_CLOSE(0.0, ofz.getMbs(), EPS);
      std::cout << std::endl;
   }

   TEST(FuzzyLogic_not)
   {
      std::cout << "-- Fuzzy logic NOT" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 10, 15);
      OutputFuzzySetTriangular ofz("Test", 0, 5, 10);

      ifz.setInput(13.75);
      ofz = not ifz;
      CHECK_CLOSE(0.75, ofz.getMbs(), EPS);

      ifz.setInput(20);
      ofz = not ifz;
      CHECK_CLOSE(1.0, ofz.getMbs(), EPS);
      std::cout << std::endl;
   }
}

int main()
{
   std::cout << "Tests: " << fuzzy::libName << " v" << fuzzy::libVersion
             << std::endl
             << std::endl;

   auto result = UnitTest::RunAllTests();
   std::cout << std::endl;
   return result;
}
<commit_msg>Solved warning<commit_after>#include "Defuzzification.h"
#include "FuzzyLogic.h"
#include "InputFuzzySetTrapezoidal.h"
#include "InputFuzzySetTriangular.h"
#include "LibInfoFuzzyEngine.h"
#include "OutputFuzzySetTrapezoidal.h"
#include "OutputFuzzySetTriangular.h"

#include <UnitTest++/UnitTest++.h>

#include <iostream>

const double EPS{0.01};

SUITE(FuzzyEngine)
{
   TEST(mbs_InputFuzzySetTriangular)
   {
      std::cout << "--- mbs_InputFuzzySetTriangular" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 10, 20);

      ifz.setInput(-10.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(0.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(2.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(7.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(25.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetLeftTriangular)
   {
      std::cout << "--- mbs_InputFuzzySetLeftTriangular" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 5, 15);

      ifz.setInput(5.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetRightTriangular)
   {
      std::cout << "--- mbs_InputFuzzySetRightTriangular" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 15, 15);

      ifz.setInput(0.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetTrapezoidal)
   {
      std::cout << "--- mbs_InputFuzzySetTrapezoidal" << std::endl;
      InputFuzzySetTrapezoidal ifz("Test", 5, 10, 20, 40);

      ifz.setInput(-10.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(0.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(2.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(7.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(30.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(40.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(50.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetLeftTrapezoidal)
   {
      std::cout << "--- mbs_InputFuzzySetLeftTrapezoidal" << std::endl;
      InputFuzzySetTrapezoidal ifz("Test", 0, 0, 20, 40);

      ifz.setInput(0.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(30.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(40.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(50.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(mbs_InputFuzzySetRightTrapezoidal)
   {
      std::cout << "--- mbs_InputFuzzySetRightTrapezoidal" << std::endl;
      InputFuzzySetTrapezoidal ifz("Test", 5, 10, 20, 20);

      ifz.setInput(-10.0);
      auto mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(0.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(2.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(5.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.0, mbs, EPS);

      ifz.setInput(7.5);
      mbs = ifz.getMbs();
      CHECK_CLOSE(0.5, mbs, EPS);

      ifz.setInput(10.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(15.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(20.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);

      ifz.setInput(30.0);
      mbs = ifz.getMbs();
      CHECK_CLOSE(1.0, mbs, EPS);
      std::cout << std::endl;
   }

   TEST(defuz_OutputFuzzySetTriangular)
   {
      std::cout << "--- defuz_OutputFuzzySetTriangular" << std::endl;
      OutputFuzzySetTriangular ofz("Test", 5, 10, 20);

      ofz.setMbs(0.5);
      CHECK_CLOSE(7.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(15.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((7.5 + 15.0) / 2.0, ofz.meanOfMaximum(), EPS);
      ofz.clearMbs();

      ofz.setMbs(0.1);
      CHECK_CLOSE(5.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(19.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((5.5 + 19.0) / 2.0, ofz.meanOfMaximum(), EPS);
      std::cout << std::endl;
   }

   TEST(defuz_OutputFuzzySetTrapezoidal)
   {
      std::cout << "--- defuz_OutputFuzzySetTrapezoidal" << std::endl;
      OutputFuzzySetTrapezoidal ofz("Test", 0, 5, 10, 20);

      ofz.setMbs(0.5);
      CHECK_CLOSE(2.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(15.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((2.5 + 15.0) / 2.0, ofz.meanOfMaximum(), EPS);
      ofz.clearMbs();

      ofz.setMbs(0.1);
      CHECK_CLOSE(0.5, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(19.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((0.5 + 19.0) / 2.0, ofz.meanOfMaximum(), EPS);
      std::cout << std::endl;
   }

   TEST(defuz_OutputFuzzySetLeftTrapezoidal)
   {
      std::cout << "--- defuz_OutputFuzzySetLeftTrapezoidal" << std::endl;
      OutputFuzzySetTrapezoidal ofz("Test", 0, 0, 10, 20);

      ofz.setMbs(0.5);
      CHECK_CLOSE(0.0, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(15.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((0.0 + 15.0) / 2.0, ofz.meanOfMaximum(), EPS);
      ofz.clearMbs();

      ofz.setMbs(0.1);
      CHECK_CLOSE(0.0, ofz.firstOfMaxima(), EPS);
      CHECK_CLOSE(19.0, ofz.lastOfMaxima(), EPS);
      CHECK_CLOSE((0.0 + 19.0) / 2.0, ofz.meanOfMaximum(), EPS);
      std::cout << std::endl;
   }

   TEST(defuz_outputsFuzzySets)
   {
      std::cout << "-- defuz output Fuzzy Sets" << std::endl;
      OutputFuzzySetTrapezoidal ofz1("Test", 0, 1, 4, 5);
      OutputFuzzySetTrapezoidal ofz2("Test", 3, 4, 6, 7);
      OutputFuzzySetTrapezoidal ofz3("Test", 5, 6, 7, 8);
      std::vector<OutputFuzzySet *> all{&ofz1, &ofz2, &ofz3};

      ofz1.setMbs(0.3);
      ofz2.setMbs(0.5);
      ofz3.setMbs(1.0);
      CHECK_CLOSE(6.0, defuzFirstOfMaxima(all), EPS);
      CHECK_CLOSE(6.5, defuzMeanOfMaximum(all), EPS);
      CHECK_CLOSE(7.0, defuzLastOfMaxima(all), EPS);
      CHECK_CLOSE(5.416, defuzWeightedAverage(all), EPS);
      std::cout << std::endl;
   }

   TEST(FuzzyLogic_or)
   {
      std::cout << "-- Fuzzy logic OR" << std::endl;
      InputFuzzySetTriangular ifz1("Test", 5, 10, 15);
      InputFuzzySetTriangular ifz2("Test", 10, 15, 20);
      OutputFuzzySetTriangular ofz("Test", 0, 5, 10);

      ifz1.setInput(12.5);
      ifz2.setInput(12.5);
      ofz = ifz1 or ifz2;
      CHECK_CLOSE(0.5, ofz.getMbs(), EPS);
      std::cout << std::endl;
   }

   TEST(FuzzyLogic_and)
   {
      std::cout << "-- Fuzzy logic AND" << std::endl;
      InputFuzzySetTriangular ifz1("Test", 5, 10, 15);
      InputFuzzySetTriangular ifz2("Test", 10, 15, 20);
      OutputFuzzySetTriangular ofz("Test", 0, 5, 10);

      ifz1.setInput(10);
      ifz2.setInput(10);
      ofz = ifz1 and ifz2;
      CHECK_CLOSE(0.0, ofz.getMbs(), EPS);
      std::cout << std::endl;
   }

   TEST(FuzzyLogic_not)
   {
      std::cout << "-- Fuzzy logic NOT" << std::endl;
      InputFuzzySetTriangular ifz("Test", 5, 10, 15);
      OutputFuzzySetTriangular ofz("Test", 0, 5, 10);

      ifz.setInput(13.75);
      ofz = not ifz;
      CHECK_CLOSE(0.75, ofz.getMbs(), EPS);

      ifz.setInput(20);
      ofz = not ifz;
      CHECK_CLOSE(1.0, ofz.getMbs(), EPS);
      std::cout << std::endl;
   }
}

int main()
{
   std::cout << "Tests: " << fuzzy::libName << " v" << fuzzy::libVersion
             << std::endl
             << std::endl;

   auto result = UnitTest::RunAllTests();
   std::cout << std::endl;
   return result;
}
<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <boost/asio.hpp>

#include <bh.h>
#include <bh_serialize.h>
#include "comm.h"

using boost::asio::ip::tcp;
using namespace std;
using namespace bohrium;

namespace bohrium {
namespace proxy {

boost::asio::io_service io_service;
tcp::socket socket(io_service);

static void init_client_socket(tcp::socket &socket, const std::string &address, int port)
{
    for(unsigned int i = 0; i < 1000000; ++i)
    {
        try
        {
            tcp::resolver resolver(io_service);
            tcp::resolver::query query(address, to_string(port));
            tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
            boost::asio::connect(socket, endpoint_iterator);
            break;
        }
        catch(...)
        {
            cout << "retry"  << endl;

        }

    }
}

static void init_server_socket(tcp::socket &socket, int port)
{
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port));
    acceptor.accept(socket);
}

CommFrontend::CommFrontend(const char* component_name, const std::string &address, int port)
{
    init_client_socket(socket, address, port);

    //Serialize message body
    vector<char> buf_body;
    serialize::Init body(component_name);
    body.serialize(buf_body);

    //Serialize message head
    vector<char> buf_head;
    serialize::Header head(serialize::TYPE_INIT, buf_body.size());
    head.serialize(buf_head);

    //Send serialized message
    cout << "server send INIT message " << endl;
    boost::asio::write(socket, boost::asio::buffer(buf_head));
    boost::asio::write(socket, boost::asio::buffer(buf_body));
}

void CommFrontend::shutdown()
{
    //Serialize message head
    vector<char> buf_head;
    serialize::Header head(serialize::TYPE_SHUTDOWN, 0);
    head.serialize(buf_head);

    //Send serialized message
    cout << "server send SHUTDOWN message " << endl;
    boost::asio::write(socket, boost::asio::buffer(buf_head));
    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    socket.close();

}

void CommFrontend::execute(bh_ir &bhir)
{
    //Serialize the BhIR
    vector<char> buf_body;
    vector<bh_base*> data_send;
    vector<bh_base*> data_recv;
    exec_serializer.serialize(bhir, buf_body, data_send, data_recv);

    //Serialize message head
    vector<char> buf_head;
    serialize::Header head(serialize::TYPE_EXEC, buf_body.size());
    head.serialize(buf_head);

    //Send serialized message
    cout << "server send EXEC message " << endl;
    boost::asio::write(socket, boost::asio::buffer(buf_head));
    boost::asio::write(socket, boost::asio::buffer(buf_body));

    //Send array data
    cout << "EXEC send new base data: ";
    for(size_t i=0; i< data_send.size(); ++i)
    {
        bh_base *base = data_send[i];
        assert(base->data != NULL);
        printf("%p ", base);
        send_array_data(base);
    }
    cout << endl;

    //Cleanup discard base array etc.
    exec_serializer.cleanup(bhir);

    //Receive sync'ed array data
    cout << "EXEC recv sync'ed base data: [";
    for(size_t i=0; i< data_recv.size(); ++i)
    {
        bh_base *base = data_recv[i];
        bh_data_malloc(base);
        printf("%p ", base);
        recv_array_data(base);
    }
    cout << "]" << endl;
}

void CommFrontend::send_array_data(const bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::write(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

void CommFrontend::recv_array_data(bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::read(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

CommBackend::CommBackend(const std::string &address, int port) {
    init_server_socket(socket, port);
}

serialize::Header CommBackend::next_message_head()
{
    //Let's read the head of the message
    vector<char> buf_head(serialize::HeaderSize);
    boost::asio::read(socket, boost::asio::buffer(buf_head));
    serialize::Header head(buf_head);

    cout << "client read head with body size of " << head.body_size << endl;
    return head;
}

void CommBackend::next_message_body(std::vector<char> &buffer)
{
    boost::asio::read(socket, boost::asio::buffer(buffer));
}

void CommBackend::shutdown()
{
    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    socket.close();
}

void CommBackend::send_array_data(const bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::write(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

void CommBackend::recv_array_data(bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::read(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

}}
<commit_msg>proxy: replaced boost::asio::connect() with a more legacy compatible implementation<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium 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 more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <boost/asio.hpp>

#include <bh.h>
#include <bh_serialize.h>
#include "comm.h"

using boost::asio::ip::tcp;
using namespace std;
using namespace bohrium;

namespace bohrium {
namespace proxy {

boost::asio::io_service io_service;
tcp::socket socket(io_service);

static void init_client_socket(tcp::socket &socket, const std::string &address, int port)
{
    for(unsigned int i = 0; i < 1000000; ++i)
    {
        try
        {
            // Get a list of endpoints corresponding to the server name.
            tcp::resolver resolver(io_service);
            tcp::resolver::query query(address, to_string(port));
            tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
            tcp::resolver::iterator end;

            // Try each endpoint until we successfully establish a connection.
            boost::system::error_code error = boost::asio::error::host_not_found;
            while (error && endpoint_iterator != end)
            {
                socket.close();
                socket.connect(*endpoint_iterator++, error);
            }
            if (error)
                throw boost::system::system_error(error);

            return;
        }
        catch(...)
        {
            cout << "retry"  << endl;

        }

    }
}

static void init_server_socket(tcp::socket &socket, int port)
{
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port));
    acceptor.accept(socket);
}

CommFrontend::CommFrontend(const char* component_name, const std::string &address, int port)
{
    init_client_socket(socket, address, port);

    //Serialize message body
    vector<char> buf_body;
    serialize::Init body(component_name);
    body.serialize(buf_body);

    //Serialize message head
    vector<char> buf_head;
    serialize::Header head(serialize::TYPE_INIT, buf_body.size());
    head.serialize(buf_head);

    //Send serialized message
    cout << "server send INIT message " << endl;
    boost::asio::write(socket, boost::asio::buffer(buf_head));
    boost::asio::write(socket, boost::asio::buffer(buf_body));
}

void CommFrontend::shutdown()
{
    //Serialize message head
    vector<char> buf_head;
    serialize::Header head(serialize::TYPE_SHUTDOWN, 0);
    head.serialize(buf_head);

    //Send serialized message
    cout << "server send SHUTDOWN message " << endl;
    boost::asio::write(socket, boost::asio::buffer(buf_head));
    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    socket.close();

}

void CommFrontend::execute(bh_ir &bhir)
{
    //Serialize the BhIR
    vector<char> buf_body;
    vector<bh_base*> data_send;
    vector<bh_base*> data_recv;
    exec_serializer.serialize(bhir, buf_body, data_send, data_recv);

    //Serialize message head
    vector<char> buf_head;
    serialize::Header head(serialize::TYPE_EXEC, buf_body.size());
    head.serialize(buf_head);

    //Send serialized message
    cout << "server send EXEC message " << endl;
    boost::asio::write(socket, boost::asio::buffer(buf_head));
    boost::asio::write(socket, boost::asio::buffer(buf_body));

    //Send array data
    cout << "EXEC send new base data: ";
    for(size_t i=0; i< data_send.size(); ++i)
    {
        bh_base *base = data_send[i];
        assert(base->data != NULL);
        printf("%p ", base);
        send_array_data(base);
    }
    cout << endl;

    //Cleanup discard base array etc.
    exec_serializer.cleanup(bhir);

    //Receive sync'ed array data
    cout << "EXEC recv sync'ed base data: [";
    for(size_t i=0; i< data_recv.size(); ++i)
    {
        bh_base *base = data_recv[i];
        bh_data_malloc(base);
        printf("%p ", base);
        recv_array_data(base);
    }
    cout << "]" << endl;
}

void CommFrontend::send_array_data(const bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::write(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

void CommFrontend::recv_array_data(bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::read(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

CommBackend::CommBackend(const std::string &address, int port) {
    init_server_socket(socket, port);
}

serialize::Header CommBackend::next_message_head()
{
    //Let's read the head of the message
    vector<char> buf_head(serialize::HeaderSize);
    boost::asio::read(socket, boost::asio::buffer(buf_head));
    serialize::Header head(buf_head);

    cout << "client read head with body size of " << head.body_size << endl;
    return head;
}

void CommBackend::next_message_body(std::vector<char> &buffer)
{
    boost::asio::read(socket, boost::asio::buffer(buffer));
}

void CommBackend::shutdown()
{
    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    socket.close();
}

void CommBackend::send_array_data(const bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::write(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

void CommBackend::recv_array_data(bh_base *base)
{
    assert(base->data != NULL);
    boost::asio::read(socket, boost::asio::buffer(base->data, bh_base_size(base)));
}

}}
<|endoftext|>