<commit_before>//
//  yas_audio_route_node.cpp
//  Copyright (c) 2015 Yuki Yasoshima.
//

#include "yas_audio_route_node.h"
#include "yas_stl_utils.h"

using namespace yas;

#pragma mark - kernel

class audio_route_node::kernel : public audio_node::kernel
{
   public:
    ~kernel() = default;

    audio_route_set routes;
};

#pragma mark - impl

class audio_route_node::impl : public audio_node::impl
{
   public:
    class core
    {
       public:
        audio_route_set routes;

        void erase_route_if_either_matched(const audio_route &route)
        {
            erase_route_if([&route](const audio_route &route_of_set) {
                return route_of_set.source == route.source || route_of_set.destination == route.destination;
            });
        }

        void erase_route_if(std::function<bool(const audio_route &)> pred)
        {
            erase_if(routes, pred);
        }
    };

    impl() : audio_node::impl(), _core(std::make_unique<core>())
    {
    }

    ~impl() = default;

    virtual void reset() override
    {
        _core->routes.clear();
        super_class::reset();
    }

    virtual UInt32 input_bus_count() const override
    {
        return std::numeric_limits<UInt32>::max();
    }

    virtual UInt32 output_bus_count() const override
    {
        return std::numeric_limits<UInt32>::max();
    }

    virtual std::shared_ptr<audio_node::kernel> make_kernel() override
    {
        return std::shared_ptr<audio_node::kernel>(new audio_route_node::kernel());
    }

    virtual void prepare_kernel(const std::shared_ptr<audio_node::kernel> &kernel) override
    {
        super_class::prepare_kernel(kernel);

        if (audio_route_node::kernel *route_kernel = dynamic_cast<audio_route_node::kernel *>(kernel.get())) {
            route_kernel->routes = _core->routes;
        } else {
            throw std::runtime_error(std::string(__PRETTY_FUNCTION__) +
                                     " : failed dynamic cast to audio_route_node::kernel.");
        }
    }

    virtual void render(audio_pcm_buffer &dst_buffer, const UInt32 dst_bus_idx, const audio_time &when) override
    {
        super_class::render(dst_buffer, dst_bus_idx, when);

        if (auto kernel = kernel_cast<audio_route_node::kernel>()) {
            auto &routes = kernel->routes;
            auto output_connection = kernel->output_connection(dst_bus_idx);
            auto input_connections = kernel->input_connections();
            const UInt32 dst_ch_count = dst_buffer.format().channel_count();

            for (const auto &pair : input_connections) {
                if (const auto &input_connection = pair.second) {
                    if (auto node = input_connection.source_node()) {
                        const auto &src_format = input_connection.format();
                        const auto &src_bus_idx = pair.first;
                        const UInt32 src_ch_count = src_format.channel_count();
                        if (const auto result =
                                channel_map_from_routes(routes, src_bus_idx, src_ch_count, dst_bus_idx, dst_ch_count)) {
                            yas::audio_pcm_buffer src_buffer(src_format, dst_buffer, result.value());
                            node.render(src_buffer, src_bus_idx, when);
                        }
                    }
                }
            }
        }
    }

#pragma mark -

    const audio_route_set &routes() const
    {
        return _core->routes;
    }

    void add_route(const audio_route &route)
    {
        _core->erase_route_if_either_matched(route);
        _core->routes.insert(route);
        update_kernel();
    }

    void add_route(audio_route &&route)
    {
        _core->erase_route_if_either_matched(route);
        _core->routes.insert(std::move(route));
        update_kernel();
    }

    void remove_route(const audio_route &route)
    {
        _core->routes.erase(route);
        update_kernel();
    }

    void remove_route_for_source(const audio_route::point &src_pt)
    {
        _core->erase_route_if([&src_pt](const audio_route &route_of_set) { return route_of_set.source == src_pt; });
        update_kernel();
    }

    void remove_route_for_destination(const audio_route::point &dst_pt)
    {
        _core->erase_route_if(
            [&dst_pt](const audio_route &route_of_set) { return route_of_set.destination == dst_pt; });
        update_kernel();
    }

    void set_routes(const audio_route_set &routes)
    {
        _core->routes.clear();
        _core->routes = routes;
        update_kernel();
    }

    void set_routes(audio_route_set &&routes)
    {
        _core->routes.clear();
        _core->routes = std::move(routes);
        update_kernel();
    }

    void clear_routes()
    {
        _core->routes.clear();
        update_kernel();
    }

    std::unique_ptr<core> _core;

   private:
    using super_class = super_class::impl;
};

#pragma mark - main

audio_route_node::audio_route_node() : super_class(std::make_unique<impl>(), create_tag)
{
}

audio_route_node::audio_route_node(std::nullptr_t) : super_class(nullptr)
{
}

const audio_route_set &audio_route_node::routes() const
{
    return _impl_ptr()->routes();
}

void audio_route_node::add_route(const audio_route &route)
{
    _impl_ptr()->add_route(route);
}

void audio_route_node::add_route(audio_route &&route)
{
    _impl_ptr()->add_route(std::move(route));
}

void audio_route_node::remove_route(const audio_route &route)
{
    _impl_ptr()->remove_route(route);
}

void audio_route_node::remove_route_for_source(const audio_route::point &src_pt)
{
    _impl_ptr()->remove_route_for_source(src_pt);
}

void audio_route_node::remove_route_for_destination(const audio_route::point &dst_pt)
{
    _impl_ptr()->remove_route_for_destination(dst_pt);
}

void audio_route_node::set_routes(const audio_route_set &routes)
{
    _impl_ptr()->set_routes(routes);
}

void audio_route_node::set_routes(audio_route_set &&routes)
{
    _impl_ptr()->set_routes(std::move(routes));
}

void audio_route_node::clear_routes()
{
    _impl_ptr()->clear_routes();
}

#pragma mark - private

std::shared_ptr<audio_route_node::impl> audio_route_node::_impl_ptr() const
{
    return std::dynamic_pointer_cast<audio_route_node::impl>(_impl);
}
<commit_msg>kernel cast<commit_after>//
//  yas_audio_route_node.cpp
//  Copyright (c) 2015 Yuki Yasoshima.
//

#include "yas_audio_route_node.h"
#include "yas_stl_utils.h"

using namespace yas;

#pragma mark - kernel

class audio_route_node::kernel : public audio_node::kernel
{
   public:
    ~kernel() = default;

    audio_route_set routes;
};

#pragma mark - impl

class audio_route_node::impl : public audio_node::impl
{
   public:
    class core
    {
       public:
        audio_route_set routes;

        void erase_route_if_either_matched(const audio_route &route)
        {
            erase_route_if([&route](const audio_route &route_of_set) {
                return route_of_set.source == route.source || route_of_set.destination == route.destination;
            });
        }

        void erase_route_if(std::function<bool(const audio_route &)> pred)
        {
            erase_if(routes, pred);
        }
    };

    impl() : audio_node::impl(), _core(std::make_unique<core>())
    {
    }

    ~impl() = default;

    virtual void reset() override
    {
        _core->routes.clear();
        super_class::reset();
    }

    virtual UInt32 input_bus_count() const override
    {
        return std::numeric_limits<UInt32>::max();
    }

    virtual UInt32 output_bus_count() const override
    {
        return std::numeric_limits<UInt32>::max();
    }

    virtual std::shared_ptr<audio_node::kernel> make_kernel() override
    {
        return std::shared_ptr<audio_node::kernel>(new audio_route_node::kernel());
    }

    virtual void prepare_kernel(const std::shared_ptr<audio_node::kernel> &kernel) override
    {
        super_class::prepare_kernel(kernel);

        if (auto route_kernel = std::dynamic_pointer_cast<audio_route_node::kernel>(kernel)) {
            route_kernel->routes = _core->routes;
        } else {
            throw std::runtime_error(std::string(__PRETTY_FUNCTION__) +
                                     " : failed dynamic cast to audio_route_node::kernel.");
        }
    }

    virtual void render(audio_pcm_buffer &dst_buffer, const UInt32 dst_bus_idx, const audio_time &when) override
    {
        super_class::render(dst_buffer, dst_bus_idx, when);

        if (auto kernel = kernel_cast<audio_route_node::kernel>()) {
            auto &routes = kernel->routes;
            auto output_connection = kernel->output_connection(dst_bus_idx);
            auto input_connections = kernel->input_connections();
            const UInt32 dst_ch_count = dst_buffer.format().channel_count();

            for (const auto &pair : input_connections) {
                if (const auto &input_connection = pair.second) {
                    if (auto node = input_connection.source_node()) {
                        const auto &src_format = input_connection.format();
                        const auto &src_bus_idx = pair.first;
                        const UInt32 src_ch_count = src_format.channel_count();
                        if (const auto result =
                                channel_map_from_routes(routes, src_bus_idx, src_ch_count, dst_bus_idx, dst_ch_count)) {
                            yas::audio_pcm_buffer src_buffer(src_format, dst_buffer, result.value());
                            node.render(src_buffer, src_bus_idx, when);
                        }
                    }
                }
            }
        }
    }

#pragma mark -

    const audio_route_set &routes() const
    {
        return _core->routes;
    }

    void add_route(const audio_route &route)
    {
        _core->erase_route_if_either_matched(route);
        _core->routes.insert(route);
        update_kernel();
    }

    void add_route(audio_route &&route)
    {
        _core->erase_route_if_either_matched(route);
        _core->routes.insert(std::move(route));
        update_kernel();
    }

    void remove_route(const audio_route &route)
    {
        _core->routes.erase(route);
        update_kernel();
    }

    void remove_route_for_source(const audio_route::point &src_pt)
    {
        _core->erase_route_if([&src_pt](const audio_route &route_of_set) { return route_of_set.source == src_pt; });
        update_kernel();
    }

    void remove_route_for_destination(const audio_route::point &dst_pt)
    {
        _core->erase_route_if(
            [&dst_pt](const audio_route &route_of_set) { return route_of_set.destination == dst_pt; });
        update_kernel();
    }

    void set_routes(const audio_route_set &routes)
    {
        _core->routes.clear();
        _core->routes = routes;
        update_kernel();
    }

    void set_routes(audio_route_set &&routes)
    {
        _core->routes.clear();
        _core->routes = std::move(routes);
        update_kernel();
    }

    void clear_routes()
    {
        _core->routes.clear();
        update_kernel();
    }

    std::unique_ptr<core> _core;

   private:
    using super_class = super_class::impl;
};

#pragma mark - main

audio_route_node::audio_route_node() : super_class(std::make_unique<impl>(), create_tag)
{
}

audio_route_node::audio_route_node(std::nullptr_t) : super_class(nullptr)
{
}

const audio_route_set &audio_route_node::routes() const
{
    return _impl_ptr()->routes();
}

void audio_route_node::add_route(const audio_route &route)
{
    _impl_ptr()->add_route(route);
}

void audio_route_node::add_route(audio_route &&route)
{
    _impl_ptr()->add_route(std::move(route));
}

void audio_route_node::remove_route(const audio_route &route)
{
    _impl_ptr()->remove_route(route);
}

void audio_route_node::remove_route_for_source(const audio_route::point &src_pt)
{
    _impl_ptr()->remove_route_for_source(src_pt);
}

void audio_route_node::remove_route_for_destination(const audio_route::point &dst_pt)
{
    _impl_ptr()->remove_route_for_destination(dst_pt);
}

void audio_route_node::set_routes(const audio_route_set &routes)
{
    _impl_ptr()->set_routes(routes);
}

void audio_route_node::set_routes(audio_route_set &&routes)
{
    _impl_ptr()->set_routes(std::move(routes));
}

void audio_route_node::clear_routes()
{
    _impl_ptr()->clear_routes();
}

#pragma mark - private

std::shared_ptr<audio_route_node::impl> audio_route_node::_impl_ptr() const
{
    return std::dynamic_pointer_cast<audio_route_node::impl>(_impl);
}
<|endoftext|>


<commit_before>
#include "PolycodeView.h"
#include "PolyWinCore.h"
#include "PolyCoreServices.h"
#include "PolyCoreInput.h"
#include "PolyRenderer.h"

using namespace Polycode;

Win32Core *core = NULL;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	int nWidth, nHeight;

	if(!core)
		return DefWindowProc(hWnd, message, wParam, lParam);

	switch (message)
	{
	case WM_SIZE:
		nWidth = LOWORD(lParam);
		nHeight = HIWORD(lParam);
		if(core)
			core->getServices()->getRenderer()->Resize(nWidth, nHeight);
	break;

	case WM_MOUSEMOVE:
		if(core)
			core->handleMouseMove(lParam,wParam);
	break;

	case WM_MOUSEWHEEL:
		if(core)
			core->handleMouseWheel(lParam,wParam);
	break;

	case WM_LBUTTONDOWN:
		if(core)
			core->handleMouseDown(CoreInput::MOUSE_BUTTON1, lParam,wParam);
	break;
	case WM_LBUTTONUP:
		if(core)
			core->handleMouseUp(CoreInput::MOUSE_BUTTON1, lParam,wParam);
	break;

	case WM_RBUTTONDOWN:
		if(core)
			core->handleMouseDown(CoreInput::MOUSE_BUTTON2, lParam,wParam);
	break;
	case WM_RBUTTONUP:
		if(core)
			core->handleMouseUp(CoreInput::MOUSE_BUTTON2, lParam,wParam);
	break;

	case WM_MBUTTONDOWN:
		if(core)
			core->handleMouseDown(CoreInput::MOUSE_BUTTON3, lParam,wParam);
	break;
	case WM_MBUTTONUP:
		if(core)
			core->handleMouseUp(CoreInput::MOUSE_BUTTON3, lParam,wParam);
	break;
	case WM_KEYDOWN:
		if(core) {
				wchar_t unicodeChar = 0;
				MSG m;
				m.hwnd = hWnd;
				m.message = message;
				m.wParam = wParam;
				m.lParam = lParam;
				m.time = 0;
				if ( PeekMessage(&m, hWnd, 0, WM_USER, PM_NOREMOVE) && (m.message == WM_CHAR) ) {
					GetMessage(&m, hWnd, 0, WM_USER);
			    		unicodeChar = (wchar_t)m.wParam;
				}

			core->handleKeyDown(lParam,wParam, unicodeChar);
		}
	break;
	case WM_KEYUP:
		if(core)
			core->handleKeyUp(lParam,wParam);
	break;
	case WM_CLOSE:
		if(core)
			core->Shutdown();
	break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

PolycodeView::PolycodeView(HINSTANCE hInstance, int nCmdShow, LPCTSTR windowTitle) : PolycodeViewBase() {

WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= NULL;
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= L"POLYCODEAPPLICATION";
	wcex.hIconSm		= LoadIcon(hInstance, IDI_APPLICATION);

	RegisterClassEx(&wcex);

  hwnd = CreateWindowEx(WS_EX_APPWINDOW, L"POLYCODEAPPLICATION", windowTitle, WS_OVERLAPPED|WS_SYSMENU,
      0, 0, 640, 480, NULL, NULL, hInstance, NULL);

  windowData = (void*)&hwnd;

   ShowWindow(hwnd, nCmdShow);
   UpdateWindow(hwnd);

}

PolycodeView::~PolycodeView() {

}<commit_msg>On Windows WM_CLOSE, call DefWindowProc after shuttong down core<commit_after>
#include "PolycodeView.h"
#include "PolyWinCore.h"
#include "PolyCoreServices.h"
#include "PolyCoreInput.h"
#include "PolyRenderer.h"

using namespace Polycode;

Win32Core *core = NULL;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	int nWidth, nHeight;
	bool useDefault = false;

	if(!core)
		return DefWindowProc(hWnd, message, wParam, lParam);

	switch (message)
	{
	case WM_SIZE:
		nWidth = LOWORD(lParam);
		nHeight = HIWORD(lParam);
		if(core)
			core->getServices()->getRenderer()->Resize(nWidth, nHeight);
	break;

	case WM_MOUSEMOVE:
		if(core)
			core->handleMouseMove(lParam,wParam);
	break;

	case WM_MOUSEWHEEL:
		if(core)
			core->handleMouseWheel(lParam,wParam);
	break;

	case WM_LBUTTONDOWN:
		if(core)
			core->handleMouseDown(CoreInput::MOUSE_BUTTON1, lParam,wParam);
	break;
	case WM_LBUTTONUP:
		if(core)
			core->handleMouseUp(CoreInput::MOUSE_BUTTON1, lParam,wParam);
	break;

	case WM_RBUTTONDOWN:
		if(core)
			core->handleMouseDown(CoreInput::MOUSE_BUTTON2, lParam,wParam);
	break;
	case WM_RBUTTONUP:
		if(core)
			core->handleMouseUp(CoreInput::MOUSE_BUTTON2, lParam,wParam);
	break;

	case WM_MBUTTONDOWN:
		if(core)
			core->handleMouseDown(CoreInput::MOUSE_BUTTON3, lParam,wParam);
	break;
	case WM_MBUTTONUP:
		if(core)
			core->handleMouseUp(CoreInput::MOUSE_BUTTON3, lParam,wParam);
	break;
	case WM_KEYDOWN:
		if(core) {
				wchar_t unicodeChar = 0;
				MSG m;
				m.hwnd = hWnd;
				m.message = message;
				m.wParam = wParam;
				m.lParam = lParam;
				m.time = 0;
				if ( PeekMessage(&m, hWnd, 0, WM_USER, PM_NOREMOVE) && (m.message == WM_CHAR) ) {
					GetMessage(&m, hWnd, 0, WM_USER);
			    		unicodeChar = (wchar_t)m.wParam;
				}

			core->handleKeyDown(lParam,wParam, unicodeChar);
		}
	break;
	case WM_KEYUP:
		if(core)
			core->handleKeyUp(lParam,wParam);
	break;
	case WM_CLOSE:
		if(core)
			core->Shutdown();
		useDefault = true;
	break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		useDefault = true;
		break;
	}

	if (useDefault)
		return DefWindowProc(hWnd, message, wParam, lParam);
	else
		return 0;
}

PolycodeView::PolycodeView(HINSTANCE hInstance, int nCmdShow, LPCTSTR windowTitle) : PolycodeViewBase() {

WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= NULL;
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= L"POLYCODEAPPLICATION";
	wcex.hIconSm		= LoadIcon(hInstance, IDI_APPLICATION);

	RegisterClassEx(&wcex);

  hwnd = CreateWindowEx(WS_EX_APPWINDOW, L"POLYCODEAPPLICATION", windowTitle, WS_OVERLAPPED|WS_SYSMENU,
      0, 0, 640, 480, NULL, NULL, hInstance, NULL);

  windowData = (void*)&hwnd;

   ShowWindow(hwnd, nCmdShow);
   UpdateWindow(hwnd);

}

PolycodeView::~PolycodeView() {

}<|endoftext|>


<commit_before>/*
* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the AMT nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED
* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS"
* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR
* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS
* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR
* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT
* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT,
* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.

* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT
* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS
* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL,
* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES,
* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF
* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT
* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.
*/

#include "xml_printer.hpp"

using namespace std;

/* XmlPrinter main methods */
string XmlPrinter::printError(
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    const string& errorCode,
    const string& errorText
  )
{
  xmlpp::Document * mErrorXml = initXmlDoc(
    "Error",
    instanceId,
    bufferSize,
    nextSeq
  );

  xmlpp::Element * errors = mErrorXml->get_root_node()->add_child("Errors");

  xmlpp::Element * error = errors->add_child("Error");
  error->set_attribute("errorCode", errorCode);
  error->set_child_text(errorText);

  string toReturn = printNode(mErrorXml->get_root_node());

  delete mErrorXml;

  return appendXmlEncode(toReturn);
}

string XmlPrinter::printProbe(
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    vector<Device *>& deviceList
  )
{
  xmlpp::Document *mProbeXml = initXmlDoc(
    "Devices",
    instanceId,
    bufferSize,
    nextSeq
  );

  xmlpp::Element *devices = mProbeXml->get_root_node()->add_child("Devices");

  vector<Device *>::iterator dev;
  for (dev = deviceList.begin(); dev != deviceList.end(); dev++)
  {
    xmlpp::Element *device = devices->add_child("Device");
    printProbeHelper(device, *dev);
  }

  string toReturn = printNode(mProbeXml->get_root_node());

  delete mProbeXml;

  return appendXmlEncode(toReturn);
}

string XmlPrinter::printSample(
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    const Int64 firstSeq,
    vector<ComponentEventPtr>& results
  )
{
  xmlpp::Document * mSampleXml = initXmlDoc(
    "Streams",
    instanceId,
    bufferSize,
    nextSeq,
    firstSeq
  );

  xmlpp::Element *streams = mSampleXml->get_root_node()->add_child("Streams");
  std::map<string, xmlpp::Element *> elements;
  std::map<string, xmlpp::Element *> components;
  std::map<string, xmlpp::Element *> devices;

  // Sort the vector by category.
  std::sort(results.begin(), results.end());

  vector<ComponentEventPtr>::iterator result;
  for (result = results.begin(); result != results.end(); result++)
  {
    addElement(*result, streams, elements, components, devices);
  }

  string toReturn = printNode(mSampleXml->get_root_node());

  delete mSampleXml;

  return appendXmlEncode(toReturn);
}

/* XmlPrinter helper Methods */
xmlpp::Document * XmlPrinter::initXmlDoc(
    const string& xmlType,
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    const Int64 firstSeq
  )
{
  xmlpp::Document *doc = new xmlpp::Document;

  string rootName = "MTConnect" + xmlType;
  string xmlns = "urn:mtconnect.org:MTConnect" + xmlType + ":1.1";
  string xsi = "urn:mtconnect.org:MTConnect" + xmlType +
    ":1.1 http://www.mtconnect.org/schemas/MTConnect" + xmlType + "_1.1.xsd";

  // Root
  xmlpp::Element * root = doc->create_root_node(rootName);
  root->set_attribute("xmlns:m", xmlns);
  root->set_attribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
  root->set_attribute("xmlns", xmlns);
  root->set_attribute("xsi:schemaLocation", xsi);

  // Header
  xmlpp::Element * header = doc->get_root_node()->add_child("Header");
  header->set_attribute("creationTime", getCurrentTime(GMT));
  header->set_attribute("sender", "localhost");
  header->set_attribute("instanceId", intToString(instanceId));
  header->set_attribute("bufferSize", intToString(bufferSize));
  header->set_attribute("version", "1.1");

  if (xmlType == "Streams")
  {
    header->set_attribute("nextSequence", int64ToString(nextSeq));
    header->set_attribute("firstSequence", int64ToString(firstSeq));
    header->set_attribute("lastSequence", int64ToString(nextSeq - 1));
  }

  return doc;
}

string XmlPrinter::printNode(
    const xmlpp::Node *node,
    const unsigned int indentation
  )
{
  // Constant node data determined for each node
  const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
  const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node);

  xmlpp::Node::NodeList children = node->get_children();
  bool hasChildren = (children.size() > 0);

  string toReturn;

  // Ignore empty whitespace
  if (nodeText && nodeText->is_white_space())
  {
    return "";
  }

  Glib::ustring nodename = node->get_name();

  // Element node: i.e. "<element"
  if (!nodeText && !nodename.empty())
  {
    toReturn += printIndentation(indentation) + "<" + nodename;
  }

  if (nodeText)
  {
    string text = nodeText->get_content();
    replaceIllegalCharacters(text);
    toReturn += text;
  }
  else if (nodeElement)
  {
    // Print attributes for the element: i.e. attribute1="value1"
    const xmlpp::Element::AttributeList& attributes =
      nodeElement->get_attributes();

    xmlpp::Element::AttributeList::const_iterator attr;
    for (attr = attributes.begin(); attr != attributes.end(); attr++)
    {
      toReturn += " " + (*attr)->get_name() +
       "=\"" + (*attr)->get_value() + "\"";
    }

    toReturn += (hasChildren) ? ">" : " />";

    if (!nodeElement->has_child_text())
    {
      toReturn += "\n";
    }
  }

  // If node does NOT have content, then it may have children
  if (!dynamic_cast<const xmlpp::ContentNode*>(node))
  {
    xmlpp::Node::NodeList::iterator child;
    for (child = children.begin(); child != children.end(); child++)
    {
      toReturn += printNode(*child, indentation + 2);
    }
  }

  // Close off xml tag, i.e. </tag>
  if (!nodeText && !nodename.empty() && hasChildren)// || indentation == 0)
  {
    if (!nodeElement->has_child_text())
    {
      toReturn += printIndentation(indentation);
    }
    toReturn += "</" + nodename + ">\n";
  }

  return toReturn;
}

void XmlPrinter::printProbeHelper(
    xmlpp::Element * element,
    Component * component
  )
{
  addAttributes(element, component->getAttributes());

  std::map<string, string> desc = component->getDescription();

  if (desc.size() > 0)
  {
    xmlpp::Element * description = element->add_child("Description");
    addAttributes(description, &desc);
  }

  list<DataItem *> datum = component->getDataItems();
  if (datum.size() > 0)
  {
    xmlpp::Element * dataItems = element->add_child("DataItems");

    list<DataItem *>::iterator data;
    for (data = datum.begin(); data!= datum.end(); data++)
    {
      xmlpp::Element * dataItem = dataItems->add_child("DataItem");
      addAttributes(dataItem, (*data)->getAttributes());
      string source = (*data)->getSource();
      if (!source.empty())
      {
        xmlpp::Element * src = dataItem->add_child("Source");
        src->add_child_text(source);
      }

      if ((*data)->hasConstraints())
      {
        xmlpp::Element * constraints = dataItem->add_child("Constraints");
        string s = (*data)->getMaximum();
        if (!s.empty())
        {
          xmlpp::Element *v = constraints->add_child("Maximum");
          v->add_child_text(s);
        }
        s = (*data)->getMinimum();
        if (!s.empty())
        {
          xmlpp::Element *v = constraints->add_child("Minimum");
          v->add_child_text(s);
        }
        vector<string> values = (*data)->getConstrainedValues();
        vector<string>::iterator value;
        for (value = values.begin(); value != values.end(); value++)
        {
          xmlpp::Element *v = constraints->add_child("Value");
          v->add_child_text(*value);
        }
      }
    }
  }

  list<Component *> children = component->getChildren();

  if (children.size() > 0)
  {
    xmlpp::Element * components = element->add_child("Components");

    list<Component *>::iterator child;
    for (child = children.begin(); child != children.end(); child++)
    {
      xmlpp::Element * component = components->add_child((*child)->getClass());
      printProbeHelper(component, *child);
    }
  }
}

string XmlPrinter::appendXmlEncode(const string& xml)
{
  return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + xml;
}

string XmlPrinter::printIndentation(unsigned int indentation)
{
  string indents;
  for (unsigned int i = 0; i < indentation; i++)
  {
    indents += " ";
  }
  return indents;
}

void XmlPrinter::addAttributes(
    xmlpp::Element *element,
    std::map<string, string> *attributes
  )
{
  std::map<string, string>::iterator attr;
  for (attr= attributes->begin(); attr!=attributes->end(); attr++)
  {
    element->set_attribute(attr->first, attr->second);
  }
}

xmlpp::Element * XmlPrinter::getDeviceStream(
    xmlpp::Element *element,
    Device *device,
    std::map<string, xmlpp::Element *> &devices
  )
{
  xmlpp::Element *deviceStream = devices[device->getName()];
  if (deviceStream != NULL)
    return deviceStream;

  // No element for device found, create a new one
  deviceStream = element->add_child("DeviceStream");
  deviceStream->set_attribute("name", device->getName());
  deviceStream->set_attribute("uuid", device->getUuid());
  devices[device->getName()] = deviceStream;

  return deviceStream;
}

void XmlPrinter::addElement(ComponentEvent *result,
			    xmlpp::Element *streams,
			    std::map<string, xmlpp::Element *> &elements,
			    std::map<string, xmlpp::Element *> &components,
			    std::map<string, xmlpp::Element *> &devices)
{
  DataItem *dataItem = result->getDataItem();
  Component *component = dataItem->getComponent();
  const char *dataName;
  switch (dataItem->getCategory())
  {
  case DataItem::SAMPLE:
    dataName = "Samples";
    break;

  case DataItem::EVENT:
    dataName = "Events";
    break;

  case DataItem::CONDITION:
    dataName = "Condition";
    break;
  }

  string key = component->getId() + dataName;

  xmlpp::Element *element = elements[key];
  xmlpp::Element *child;

  if (element == NULL)
  {
    xmlpp::Element * componentStream = components[component->getId()];
    if (componentStream == NULL)
    {
      xmlpp::Element *deviceStream =
        getDeviceStream(streams, component->getDevice(), devices);

      componentStream = deviceStream->add_child("ComponentStream");
      components[component->getId()] = componentStream;

      componentStream->set_attribute("component", component->getClass());
      componentStream->set_attribute("name", component->getName());
      componentStream->set_attribute("componentId", component->getId());
    }

    elements[key] = element = componentStream->add_child(dataName);
  }

  if (dataItem->isCondition()) {
    child = element->add_child(result->getLevelString());
  } else {
    child = element->add_child(dataItem->getTypeString(false));
  }
  if (!result->getValue().empty())
    child->add_child_text(result->getValue());
  addAttributes(child, result->getAttributes());
}

<commit_msg>Removed warning.<commit_after>/*
* Copyright (c) 2008, AMT – The Association For Manufacturing Technology (“AMT”)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the AMT nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* DISCLAIMER OF WARRANTY. ALL MTCONNECT MATERIALS AND SPECIFICATIONS PROVIDED
* BY AMT, MTCONNECT OR ANY PARTICIPANT TO YOU OR ANY PARTY ARE PROVIDED "AS IS"
* AND WITHOUT ANY WARRANTY OF ANY KIND. AMT, MTCONNECT, AND EACH OF THEIR
* RESPECTIVE MEMBERS, OFFICERS, DIRECTORS, AFFILIATES, SPONSORS, AND AGENTS
* (COLLECTIVELY, THE "AMT PARTIES") AND PARTICIPANTS MAKE NO REPRESENTATION OR
* WARRANTY OF ANY KIND WHATSOEVER RELATING TO THESE MATERIALS, INCLUDING, WITHOUT
* LIMITATION, ANY EXPRESS OR IMPLIED WARRANTY OF NONINFRINGEMENT,
* MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.

* LIMITATION OF LIABILITY. IN NO EVENT SHALL AMT, MTCONNECT, ANY OTHER AMT
* PARTY, OR ANY PARTICIPANT BE LIABLE FOR THE COST OF PROCURING SUBSTITUTE GOODS
* OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA OR ANY INCIDENTAL,
* CONSEQUENTIAL, INDIRECT, SPECIAL OR PUNITIVE DAMAGES OR OTHER DIRECT DAMAGES,
* WHETHER UNDER CONTRACT, TORT, WARRANTY OR OTHERWISE, ARISING IN ANY WAY OUT OF
* THIS AGREEMENT, USE OR INABILITY TO USE MTCONNECT MATERIALS, WHETHER OR NOT
* SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.
*/

#include "xml_printer.hpp"

using namespace std;

/* XmlPrinter main methods */
string XmlPrinter::printError(
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    const string& errorCode,
    const string& errorText
  )
{
  xmlpp::Document * mErrorXml = initXmlDoc(
    "Error",
    instanceId,
    bufferSize,
    nextSeq
  );

  xmlpp::Element * errors = mErrorXml->get_root_node()->add_child("Errors");

  xmlpp::Element * error = errors->add_child("Error");
  error->set_attribute("errorCode", errorCode);
  error->set_child_text(errorText);

  string toReturn = printNode(mErrorXml->get_root_node());

  delete mErrorXml;

  return appendXmlEncode(toReturn);
}

string XmlPrinter::printProbe(
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    vector<Device *>& deviceList
  )
{
  xmlpp::Document *mProbeXml = initXmlDoc(
    "Devices",
    instanceId,
    bufferSize,
    nextSeq
  );

  xmlpp::Element *devices = mProbeXml->get_root_node()->add_child("Devices");

  vector<Device *>::iterator dev;
  for (dev = deviceList.begin(); dev != deviceList.end(); dev++)
  {
    xmlpp::Element *device = devices->add_child("Device");
    printProbeHelper(device, *dev);
  }

  string toReturn = printNode(mProbeXml->get_root_node());

  delete mProbeXml;

  return appendXmlEncode(toReturn);
}

string XmlPrinter::printSample(
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    const Int64 firstSeq,
    vector<ComponentEventPtr>& results
  )
{
  xmlpp::Document * mSampleXml = initXmlDoc(
    "Streams",
    instanceId,
    bufferSize,
    nextSeq,
    firstSeq
  );

  xmlpp::Element *streams = mSampleXml->get_root_node()->add_child("Streams");
  std::map<string, xmlpp::Element *> elements;
  std::map<string, xmlpp::Element *> components;
  std::map<string, xmlpp::Element *> devices;

  // Sort the vector by category.
  std::sort(results.begin(), results.end());

  vector<ComponentEventPtr>::iterator result;
  for (result = results.begin(); result != results.end(); result++)
  {
    addElement(*result, streams, elements, components, devices);
  }

  string toReturn = printNode(mSampleXml->get_root_node());

  delete mSampleXml;

  return appendXmlEncode(toReturn);
}

/* XmlPrinter helper Methods */
xmlpp::Document * XmlPrinter::initXmlDoc(
    const string& xmlType,
    const unsigned int instanceId,
    const unsigned int bufferSize,
    const Int64 nextSeq,
    const Int64 firstSeq
  )
{
  xmlpp::Document *doc = new xmlpp::Document;

  string rootName = "MTConnect" + xmlType;
  string xmlns = "urn:mtconnect.org:MTConnect" + xmlType + ":1.1";
  string xsi = "urn:mtconnect.org:MTConnect" + xmlType +
    ":1.1 http://www.mtconnect.org/schemas/MTConnect" + xmlType + "_1.1.xsd";

  // Root
  xmlpp::Element * root = doc->create_root_node(rootName);
  root->set_attribute("xmlns:m", xmlns);
  root->set_attribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
  root->set_attribute("xmlns", xmlns);
  root->set_attribute("xsi:schemaLocation", xsi);

  // Header
  xmlpp::Element * header = doc->get_root_node()->add_child("Header");
  header->set_attribute("creationTime", getCurrentTime(GMT));
  header->set_attribute("sender", "localhost");
  header->set_attribute("instanceId", intToString(instanceId));
  header->set_attribute("bufferSize", intToString(bufferSize));
  header->set_attribute("version", "1.1");

  if (xmlType == "Streams")
  {
    header->set_attribute("nextSequence", int64ToString(nextSeq));
    header->set_attribute("firstSequence", int64ToString(firstSeq));
    header->set_attribute("lastSequence", int64ToString(nextSeq - 1));
  }

  return doc;
}

string XmlPrinter::printNode(
    const xmlpp::Node *node,
    const unsigned int indentation
  )
{
  // Constant node data determined for each node
  const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
  const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node);

  xmlpp::Node::NodeList children = node->get_children();
  bool hasChildren = (children.size() > 0);

  string toReturn;

  // Ignore empty whitespace
  if (nodeText && nodeText->is_white_space())
  {
    return "";
  }

  Glib::ustring nodename = node->get_name();

  // Element node: i.e. "<element"
  if (!nodeText && !nodename.empty())
  {
    toReturn += printIndentation(indentation) + "<" + nodename;
  }

  if (nodeText)
  {
    string text = nodeText->get_content();
    replaceIllegalCharacters(text);
    toReturn += text;
  }
  else if (nodeElement)
  {
    // Print attributes for the element: i.e. attribute1="value1"
    const xmlpp::Element::AttributeList& attributes =
      nodeElement->get_attributes();

    xmlpp::Element::AttributeList::const_iterator attr;
    for (attr = attributes.begin(); attr != attributes.end(); attr++)
    {
      toReturn += " " + (*attr)->get_name() +
       "=\"" + (*attr)->get_value() + "\"";
    }

    toReturn += (hasChildren) ? ">" : " />";

    if (!nodeElement->has_child_text())
    {
      toReturn += "\n";
    }
  }

  // If node does NOT have content, then it may have children
  if (!dynamic_cast<const xmlpp::ContentNode*>(node))
  {
    xmlpp::Node::NodeList::iterator child;
    for (child = children.begin(); child != children.end(); child++)
    {
      toReturn += printNode(*child, indentation + 2);
    }
  }

  // Close off xml tag, i.e. </tag>
  if (!nodeText && !nodename.empty() && hasChildren)// || indentation == 0)
  {
    if (!nodeElement->has_child_text())
    {
      toReturn += printIndentation(indentation);
    }
    toReturn += "</" + nodename + ">\n";
  }

  return toReturn;
}

void XmlPrinter::printProbeHelper(
    xmlpp::Element * element,
    Component * component
  )
{
  addAttributes(element, component->getAttributes());

  std::map<string, string> desc = component->getDescription();

  if (desc.size() > 0)
  {
    xmlpp::Element * description = element->add_child("Description");
    addAttributes(description, &desc);
  }

  list<DataItem *> datum = component->getDataItems();
  if (datum.size() > 0)
  {
    xmlpp::Element * dataItems = element->add_child("DataItems");

    list<DataItem *>::iterator data;
    for (data = datum.begin(); data!= datum.end(); data++)
    {
      xmlpp::Element * dataItem = dataItems->add_child("DataItem");
      addAttributes(dataItem, (*data)->getAttributes());
      string source = (*data)->getSource();
      if (!source.empty())
      {
        xmlpp::Element * src = dataItem->add_child("Source");
        src->add_child_text(source);
      }

      if ((*data)->hasConstraints())
      {
        xmlpp::Element * constraints = dataItem->add_child("Constraints");
        string s = (*data)->getMaximum();
        if (!s.empty())
        {
          xmlpp::Element *v = constraints->add_child("Maximum");
          v->add_child_text(s);
        }
        s = (*data)->getMinimum();
        if (!s.empty())
        {
          xmlpp::Element *v = constraints->add_child("Minimum");
          v->add_child_text(s);
        }
        vector<string> values = (*data)->getConstrainedValues();
        vector<string>::iterator value;
        for (value = values.begin(); value != values.end(); value++)
        {
          xmlpp::Element *v = constraints->add_child("Value");
          v->add_child_text(*value);
        }
      }
    }
  }

  list<Component *> children = component->getChildren();

  if (children.size() > 0)
  {
    xmlpp::Element * components = element->add_child("Components");

    list<Component *>::iterator child;
    for (child = children.begin(); child != children.end(); child++)
    {
      xmlpp::Element * component = components->add_child((*child)->getClass());
      printProbeHelper(component, *child);
    }
  }
}

string XmlPrinter::appendXmlEncode(const string& xml)
{
  return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + xml;
}

string XmlPrinter::printIndentation(unsigned int indentation)
{
  string indents;
  for (unsigned int i = 0; i < indentation; i++)
  {
    indents += " ";
  }
  return indents;
}

void XmlPrinter::addAttributes(
    xmlpp::Element *element,
    std::map<string, string> *attributes
  )
{
  std::map<string, string>::iterator attr;
  for (attr= attributes->begin(); attr!=attributes->end(); attr++)
  {
    element->set_attribute(attr->first, attr->second);
  }
}

xmlpp::Element * XmlPrinter::getDeviceStream(
    xmlpp::Element *element,
    Device *device,
    std::map<string, xmlpp::Element *> &devices
  )
{
  xmlpp::Element *deviceStream = devices[device->getName()];
  if (deviceStream != NULL)
    return deviceStream;

  // No element for device found, create a new one
  deviceStream = element->add_child("DeviceStream");
  deviceStream->set_attribute("name", device->getName());
  deviceStream->set_attribute("uuid", device->getUuid());
  devices[device->getName()] = deviceStream;

  return deviceStream;
}

void XmlPrinter::addElement(ComponentEvent *result,
			    xmlpp::Element *streams,
			    std::map<string, xmlpp::Element *> &elements,
			    std::map<string, xmlpp::Element *> &components,
			    std::map<string, xmlpp::Element *> &devices)
{
  DataItem *dataItem = result->getDataItem();
  Component *component = dataItem->getComponent();
  const char *dataName = "";
  switch (dataItem->getCategory())
  {
  case DataItem::SAMPLE:
    dataName = "Samples";
    break;

  case DataItem::EVENT:
    dataName = "Events";
    break;

  case DataItem::CONDITION:
    dataName = "Condition";
    break;
  }

  string key = component->getId() + dataName;

  xmlpp::Element *element = elements[key];
  xmlpp::Element *child;

  if (element == NULL)
  {
    xmlpp::Element * componentStream = components[component->getId()];
    if (componentStream == NULL)
    {
      xmlpp::Element *deviceStream =
        getDeviceStream(streams, component->getDevice(), devices);

      componentStream = deviceStream->add_child("ComponentStream");
      components[component->getId()] = componentStream;

      componentStream->set_attribute("component", component->getClass());
      componentStream->set_attribute("name", component->getName());
      componentStream->set_attribute("componentId", component->getId());
    }

    elements[key] = element = componentStream->add_child(dataName);
  }

  if (dataItem->isCondition()) {
    child = element->add_child(result->getLevelString());
  } else {
    child = element->add_child(dataItem->getTypeString(false));
  }
  if (!result->getValue().empty())
    child->add_child_text(result->getValue());
  addAttributes(child, result->getAttributes());
}

<|endoftext|>


<commit_before>#include "nxtOSEKRobotGenerator.h"

#include <QTextStream>
#include <cmath>
#include <QtCore/QObject>
#include <QDir>

#include "../../../../qrkernel/exception/exception.h"
#include "../../../../qrkernel/settingsManager.h"

#include "elementGeneratorFactory.h"

using namespace qReal;
using namespace robots::generator;

NxtOSEKRobotGenerator::NxtOSEKRobotGenerator(
		Id const &diagram
		, qrRepo::RepoControlInterface &api
		, qReal::ErrorReporterInterface &errorReporter
		, QString const &destinationPath
		)
		: mDestinationPath(destinationPath)
		, mErrorReporter(errorReporter)
{
	mIsNeedToDeleteMApi = false;
	mApi = dynamic_cast<qrRepo::RepoApi *>(&api);  // TODO: remove unneeded dynamic_cast or provide strong argumentation why it is needed.
	mDiagram = diagram;
}

NxtOSEKRobotGenerator::NxtOSEKRobotGenerator(QString const &pathToRepo
		, qReal::ErrorReporterInterface &errorReporter
		, QString const &destinationPath
		)
		: mDestinationPath(SettingsManager::value("temp", "").toString())
		, mErrorReporter(errorReporter)
{
	Q_UNUSED(destinationPath)
	mIsNeedToDeleteMApi = true;
	mApi = new qrRepo::RepoApi(pathToRepo);
}

NxtOSEKRobotGenerator::~NxtOSEKRobotGenerator()
{
	if (mApi && mIsNeedToDeleteMApi)
		delete mApi;
}

void NxtOSEKRobotGenerator::addToGeneratedStringSetVariableInit()
{
	/*foreach (SmartLine curVariable, mVariables) {
		mGeneratedStringSet[mVariablePlaceInGenStrSet].append(
				SmartLine("int " + curVariable.text() + ";", curVariable.elementId()));
	}*/
}

QString NxtOSEKRobotGenerator::generateVariableString()
{
	QString res;
	foreach (SmartLine curVariable, mVariables) {
		if (!curVariable.text().contains(" ")) {
			res = res + "static int " + curVariable.text() + ";\n";
		}
	}
	return res;
}

QString NxtOSEKRobotGenerator::addTabAndEndOfLine(QList<SmartLine> const &lineList, QString resultCode)
{
	foreach (SmartLine const &curLine, lineList) {
		if ( (curLine.indentLevelChange() == SmartLine::decrease)
			|| (curLine.indentLevelChange() == SmartLine::increaseDecrease) )
		{
			mCurTabNumber--;
		}
		resultCode += '\t' + QString(mCurTabNumber, '\t') + curLine.text() + "\n";
		if ( (curLine.indentLevelChange() == SmartLine::increase)
			|| (curLine.indentLevelChange() == SmartLine::increaseDecrease) )
		{
			mCurTabNumber++;
		}
	}
	return resultCode;
}

void NxtOSEKRobotGenerator::generateMakeFile(bool toGenerateIsEmpty, QString projectName, QString projectDir)
{
	QFile templateMakeFile(":/nxtOSEK/templates/template.makefile");
	if (!templateMakeFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + templateMakeFile.fileName() + "\"");
		return;
	}

	QFile resultMakeFile(projectDir + "/makefile");
	if (!resultMakeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + resultMakeFile.fileName() + "\"");
		return;
	}

	QTextStream outMake(&resultMakeFile);
	if (mBalancerIsActivated)
		outMake << templateMakeFile.readAll().replace("@@PROJECT_NAME@@", projectName.toUtf8()).replace("@@BALANCER@@", "balancer_param.c \\").replace("@@BALANCER_LIB@@", "USER_LIB = nxtway_gs_balancer");
	else
		outMake << templateMakeFile.readAll().replace("@@PROJECT_NAME@@", projectName.toUtf8()).replace("@@BALANCER@@", "").replace("@@BALANCER_LIB@@", "");
	templateMakeFile.close();

	outMake.flush();
	resultMakeFile.close();

	if (toGenerateIsEmpty) {
		mErrorReporter.addError(QObject::tr("There is nothing to generate, diagram doesn't have Initial Node or Initial Block"));
	}

}

void NxtOSEKRobotGenerator::insertCode(
		QString resultCode,
		QString resultInitCode,
		QString resultTerminateCode,
		QString curInitialNodeNumber)
{
	if (mBalancerIsActivated) {
		mResultString.replace("@@BALANCER@@", "#include \"balancer.h\"");
	} else {
		mResultString.replace("@@BALANCER@@", "");
	}
	mResultString.replace("@@CODE@@", resultCode +"\n" + "@@CODE@@");
	mTaskTemplate.replace("@@NUMBER@@", curInitialNodeNumber);
	mResultOIL.replace("@@TASK@@", mTaskTemplate + "\n" + "@@TASK@@");
	mResultString.replace("@@VARIABLES@@", generateVariableString() + "\n" + "@@VARIABLES@@");
	mResultString.replace("@@INITHOOKS@@", resultInitCode);
	mResultString.replace("@@TERMINATEHOOKS@@", resultTerminateCode);
}

void NxtOSEKRobotGenerator::deleteResidualLabels(QString projectName)
{
	mResultOIL.replace("@@TASK@@", "");
	mResultString.replace("@@VARIABLES@@", "");
	mResultString.replace("@@CODE@@", "");
	mResultString.replace("@@PROJECT_NAME@@", projectName);
}

void NxtOSEKRobotGenerator::generateFilesForBalancer(QString projectDir)
{
	if (mBalancerIsActivated) {
		QFile::copy(":/nxtOSEK/templates/balancer/balancer_param.c", projectDir + "/" + "balancer_param.c");
		QFile::copy(":/nxtOSEK/templates/balancer/balancer.h", projectDir + "/" +"balancer.h");
		QFile::copy(":/nxtOSEK/templates/balancer/balancer_types.h", projectDir + "/" + "balancer_types.h");
		QFile::copy(":/nxtOSEK/templates/balancer/libnxtway_gs_balancer.a", projectDir + "/" + "libnxtway_gs_balancer.a");
		QFile::copy(":/nxtOSEK/templates/balancer/rt_SATURATE.h", projectDir + "/" + "rt_SATURATE.h");
		QFile::copy(":/nxtOSEK/templates/balancer/rtwtypes.h", projectDir + "/" + "rtwtypes.h");
	}
}

void NxtOSEKRobotGenerator::generate()
{
	if (mDiagram == Id()) {
		mErrorReporter.addCritical(QObject::tr("There is no opened diagram"));
		return;
	}

	IdList toGenerate = mApi->elementsByType("InitialNode");
	toGenerate << mApi->elementsByType("InitialBlock");

	int curInitialNodeNumber = 0;

	QString resultInitCode;
	QString resultTerminateCode;

	//QDir projectsDir; //TODO: use user path to projects
	QString projectName = "example" + QString::number(curInitialNodeNumber);
	QString projectDir = "nxt-tools/" + projectName;

	//Create project directory
	if (!QDir(projectDir).exists()) {
		if (!QDir("nxt-tools/").exists())
			QDir().mkdir("nxt-tools/");
		QDir().mkdir(projectDir);
	}

	// Template C file
	QFile templateCFile(":/nxtOSEK/templates/template.c");
	if (!templateCFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + templateCFile.fileName() + "\"");
		return;
	}

	QTextStream templateCStream(&templateCFile);
	mResultString = templateCStream.readAll();
	templateCFile.close();

	// Generate OIL file
	QFile resultOILFile(projectDir + "/" + projectName + ".oil");
	if (!resultOILFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + resultOILFile.fileName() + "\"");
		return;
	}

	// Template OIL file
	QFile templateOILFile(":/nxtOSEK/templates/template.oil");
	if (!templateOILFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + templateOILFile.fileName() + "\"");
		return;
	}

	mResultOIL = templateOILFile.readAll();
	templateOILFile.close();

	// Task template file
	QFile taskTemplateFile(":/nxtOSEK/templates/taskTemplate.oil");
	if (!taskTemplateFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + taskTemplateFile.fileName() + "\"");
		return;
	}

	QString resultTaskTemplate = taskTemplateFile.readAll();
	taskTemplateFile.close();

	foreach (Id const &curInitialNode, toGenerate) {// идем по отдельным цепочкам из элементов

		mTaskTemplate = resultTaskTemplate;
		if (!mApi->isGraphicalElement(curInitialNode)) {
			continue;
		}

		if (mApi->parent(curInitialNode) != mDiagram) {
			continue;
		}

		mGeneratedStringSet.clear();
		mGeneratedStringSet.append(QList<SmartLine>()); //first list for variable initialization
		mVariablePlaceInGenStrSet = 0;

		mElementToStringListNumbers.clear();
		mVariables.clear();

		AbstractElementGenerator* gen = ElementGeneratorFactory::generator(this, curInitialNode, *mApi);
		mPreviousElement = curInitialNode;

		mBalancerIsActivated = false;
		gen->generate(); //may throws a exception
		delete gen;
		addToGeneratedStringSetVariableInit();

		// Result code in .c file
		QString resultCode;
		mCurTabNumber = 0;
		foreach (QList<SmartLine> lineList, mGeneratedStringSet) {
			 resultCode = addTabAndEndOfLine(lineList, resultCode);
		}
		// Code init block in .c file
		resultInitCode = addTabAndEndOfLine(mInitCode, resultInitCode);
		// Code terminate block in .c file
		resultTerminateCode = addTabAndEndOfLine(mTerminateCode, resultTerminateCode);
		resultCode = "TASK(OSEK_Task_Number_" + QString::number(curInitialNodeNumber) +")\n{\n" + resultCode + "}";
		insertCode(resultCode, resultInitCode, resultTerminateCode, QString::number(curInitialNodeNumber));
		curInitialNodeNumber++;
	}
	deleteResidualLabels(projectName);

	QFile resultCFile(projectDir + "/" + projectName + ".c");
	if (!resultCFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + resultCFile.fileName() + "\"");
		return;
	}

	//Output in the .c and .oil file
	QTextStream outC(&resultCFile);
	outC << mResultString;
	outC.flush();
	resultCFile.close();

	QTextStream outOIL(&resultOILFile);
	outOIL << mResultOIL;
	outOIL.flush();
	resultOILFile.close();
	generateMakeFile(toGenerate.isEmpty(), projectName, projectDir);
}

QList<SmartLine> &NxtOSEKRobotGenerator::variables()
{
	return mVariables;
}

QList<SmartLine> &NxtOSEKRobotGenerator::initCode()
{
	return mInitCode;
}

qrRepo::RepoApi const * const NxtOSEKRobotGenerator::api() const
{
	return mApi;
}

QByteArray NxtOSEKRobotGenerator::portValue1() const
{
	return mPortValue1;
}

QByteArray NxtOSEKRobotGenerator::portValue2() const
{
	return mPortValue2;
}

QByteArray NxtOSEKRobotGenerator::portValue3() const
{
	return mPortValue3;
}

QByteArray NxtOSEKRobotGenerator::portValue4() const
{
	return mPortValue4;
}

ErrorReporterInterface &NxtOSEKRobotGenerator::errorReporter() const
{
	return mErrorReporter;
}

qReal::Id &NxtOSEKRobotGenerator::previousElement()
{
	return mPreviousElement;
}

QList<QList<SmartLine> > &NxtOSEKRobotGenerator::generatedStringSet()
{
	return mGeneratedStringSet;
}

QMap<QString, QStack<int> > &NxtOSEKRobotGenerator::elementToStringListNumbers()
{
	return mElementToStringListNumbers;
}

QStack<qReal::Id> &NxtOSEKRobotGenerator::previousLoopElements()
{
	return mPreviousLoopElements;
}
<commit_msg>fixed bug: does not generate the file for balancer<commit_after>#include "nxtOSEKRobotGenerator.h"

#include <QTextStream>
#include <cmath>
#include <QtCore/QObject>
#include <QDir>

#include "../../../../qrkernel/exception/exception.h"
#include "../../../../qrkernel/settingsManager.h"

#include "elementGeneratorFactory.h"

using namespace qReal;
using namespace robots::generator;

NxtOSEKRobotGenerator::NxtOSEKRobotGenerator(
		Id const &diagram
		, qrRepo::RepoControlInterface &api
		, qReal::ErrorReporterInterface &errorReporter
		, QString const &destinationPath
		)
		: mDestinationPath(destinationPath)
		, mErrorReporter(errorReporter)
{
	mIsNeedToDeleteMApi = false;
	mApi = dynamic_cast<qrRepo::RepoApi *>(&api);  // TODO: remove unneeded dynamic_cast or provide strong argumentation why it is needed.
	mDiagram = diagram;
}

NxtOSEKRobotGenerator::NxtOSEKRobotGenerator(QString const &pathToRepo
		, qReal::ErrorReporterInterface &errorReporter
		, QString const &destinationPath
		)
		: mDestinationPath(SettingsManager::value("temp", "").toString())
		, mErrorReporter(errorReporter)
{
	Q_UNUSED(destinationPath)
	mIsNeedToDeleteMApi = true;
	mApi = new qrRepo::RepoApi(pathToRepo);
}

NxtOSEKRobotGenerator::~NxtOSEKRobotGenerator()
{
	if (mApi && mIsNeedToDeleteMApi)
		delete mApi;
}

void NxtOSEKRobotGenerator::addToGeneratedStringSetVariableInit()
{
	/*foreach (SmartLine curVariable, mVariables) {
		mGeneratedStringSet[mVariablePlaceInGenStrSet].append(
				SmartLine("int " + curVariable.text() + ";", curVariable.elementId()));
	}*/
}

QString NxtOSEKRobotGenerator::generateVariableString()
{
	QString res;
	foreach (SmartLine curVariable, mVariables) {
		if (!curVariable.text().contains(" ")) {
			res = res + "static int " + curVariable.text() + ";\n";
		}
	}
	return res;
}

QString NxtOSEKRobotGenerator::addTabAndEndOfLine(QList<SmartLine> const &lineList, QString resultCode)
{
	foreach (SmartLine const &curLine, lineList) {
		if ( (curLine.indentLevelChange() == SmartLine::decrease)
			|| (curLine.indentLevelChange() == SmartLine::increaseDecrease) )
		{
			mCurTabNumber--;
		}
		resultCode += '\t' + QString(mCurTabNumber, '\t') + curLine.text() + "\n";
		if ( (curLine.indentLevelChange() == SmartLine::increase)
			|| (curLine.indentLevelChange() == SmartLine::increaseDecrease) )
		{
			mCurTabNumber++;
		}
	}
	return resultCode;
}

void NxtOSEKRobotGenerator::generateMakeFile(bool toGenerateIsEmpty, QString projectName, QString projectDir)
{
	QFile templateMakeFile(":/nxtOSEK/templates/template.makefile");
	if (!templateMakeFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + templateMakeFile.fileName() + "\"");
		return;
	}

	QFile resultMakeFile(projectDir + "/makefile");
	if (!resultMakeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + resultMakeFile.fileName() + "\"");
		return;
	}

	QTextStream outMake(&resultMakeFile);
	if (mBalancerIsActivated)
		outMake << templateMakeFile.readAll().replace("@@PROJECT_NAME@@", projectName.toUtf8()).replace("@@BALANCER@@", "balancer_param.c \\").replace("@@BALANCER_LIB@@", "USER_LIB = nxtway_gs_balancer");
	else
		outMake << templateMakeFile.readAll().replace("@@PROJECT_NAME@@", projectName.toUtf8()).replace("@@BALANCER@@", "").replace("@@BALANCER_LIB@@", "");
	templateMakeFile.close();

	outMake.flush();
	resultMakeFile.close();

	if (toGenerateIsEmpty) {
		mErrorReporter.addError(QObject::tr("There is nothing to generate, diagram doesn't have Initial Node or Initial Block"));
	}

}

void NxtOSEKRobotGenerator::insertCode(
		QString resultCode,
		QString resultInitCode,
		QString resultTerminateCode,
		QString curInitialNodeNumber)
{
	if (mBalancerIsActivated) {
		mResultString.replace("@@BALANCER@@", "#include \"balancer.h\"");
	} else {
		mResultString.replace("@@BALANCER@@", "");
	}
	mResultString.replace("@@CODE@@", resultCode +"\n" + "@@CODE@@");
	mTaskTemplate.replace("@@NUMBER@@", curInitialNodeNumber);
	mResultOIL.replace("@@TASK@@", mTaskTemplate + "\n" + "@@TASK@@");
	mResultString.replace("@@VARIABLES@@", generateVariableString() + "\n" + "@@VARIABLES@@");
	mResultString.replace("@@INITHOOKS@@", resultInitCode);
	mResultString.replace("@@TERMINATEHOOKS@@", resultTerminateCode);
}

void NxtOSEKRobotGenerator::deleteResidualLabels(QString projectName)
{
	mResultOIL.replace("@@TASK@@", "");
	mResultString.replace("@@VARIABLES@@", "");
	mResultString.replace("@@CODE@@", "");
	mResultString.replace("@@PROJECT_NAME@@", projectName);
}

void NxtOSEKRobotGenerator::generateFilesForBalancer(QString projectDir)
{
	if (mBalancerIsActivated) {
		QFile::copy(":/nxtOSEK/templates/balancer/balancer_param.c", projectDir + "/" + "balancer_param.c");
		QFile::copy(":/nxtOSEK/templates/balancer/balancer.h", projectDir + "/" +"balancer.h");
		QFile::copy(":/nxtOSEK/templates/balancer/balancer_types.h", projectDir + "/" + "balancer_types.h");
		QFile::copy(":/nxtOSEK/templates/balancer/libnxtway_gs_balancer.a", projectDir + "/" + "libnxtway_gs_balancer.a");
		QFile::copy(":/nxtOSEK/templates/balancer/rt_SATURATE.h", projectDir + "/" + "rt_SATURATE.h");
		QFile::copy(":/nxtOSEK/templates/balancer/rtwtypes.h", projectDir + "/" + "rtwtypes.h");
	}
}

void NxtOSEKRobotGenerator::generate()
{
	if (mDiagram == Id()) {
		mErrorReporter.addCritical(QObject::tr("There is no opened diagram"));
		return;
	}

	IdList toGenerate = mApi->elementsByType("InitialNode");
	toGenerate << mApi->elementsByType("InitialBlock");

	int curInitialNodeNumber = 0;

	QString resultInitCode;
	QString resultTerminateCode;

	//QDir projectsDir; //TODO: use user path to projects
	QString projectName = "example" + QString::number(curInitialNodeNumber);
	QString projectDir = "nxt-tools/" + projectName;

	//Create project directory
	if (!QDir(projectDir).exists()) {
		if (!QDir("nxt-tools/").exists())
			QDir().mkdir("nxt-tools/");
		QDir().mkdir(projectDir);
	}

	// Template C file
	QFile templateCFile(":/nxtOSEK/templates/template.c");
	if (!templateCFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + templateCFile.fileName() + "\"");
		return;
	}

	QTextStream templateCStream(&templateCFile);
	mResultString = templateCStream.readAll();
	templateCFile.close();

	// Generate OIL file
	QFile resultOILFile(projectDir + "/" + projectName + ".oil");
	if (!resultOILFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + resultOILFile.fileName() + "\"");
		return;
	}

	// Template OIL file
	QFile templateOILFile(":/nxtOSEK/templates/template.oil");
	if (!templateOILFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + templateOILFile.fileName() + "\"");
		return;
	}

	mResultOIL = templateOILFile.readAll();
	templateOILFile.close();

	// Task template file
	QFile taskTemplateFile(":/nxtOSEK/templates/taskTemplate.oil");
	if (!taskTemplateFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + taskTemplateFile.fileName() + "\"");
		return;
	}

	QString resultTaskTemplate = taskTemplateFile.readAll();
	taskTemplateFile.close();

	foreach (Id const &curInitialNode, toGenerate) {// идем по отдельным цепочкам из элементов

		mTaskTemplate = resultTaskTemplate;
		if (!mApi->isGraphicalElement(curInitialNode)) {
			continue;
		}

		if (mApi->parent(curInitialNode) != mDiagram) {
			continue;
		}

		mGeneratedStringSet.clear();
		mGeneratedStringSet.append(QList<SmartLine>()); //first list for variable initialization
		mVariablePlaceInGenStrSet = 0;

		mElementToStringListNumbers.clear();
		mVariables.clear();

		AbstractElementGenerator* gen = ElementGeneratorFactory::generator(this, curInitialNode, *mApi);
		mPreviousElement = curInitialNode;

		mBalancerIsActivated = false;
		gen->generate(); //may throws a exception
		delete gen;
		addToGeneratedStringSetVariableInit();

		// Result code in .c file
		QString resultCode;
		mCurTabNumber = 0;
		foreach (QList<SmartLine> lineList, mGeneratedStringSet) {
			 resultCode = addTabAndEndOfLine(lineList, resultCode);
		}
		// Code init block in .c file
		resultInitCode = addTabAndEndOfLine(mInitCode, resultInitCode);
		// Code terminate block in .c file
		resultTerminateCode = addTabAndEndOfLine(mTerminateCode, resultTerminateCode);
		resultCode = "TASK(OSEK_Task_Number_" + QString::number(curInitialNodeNumber) +")\n{\n" + resultCode + "}";
		insertCode(resultCode, resultInitCode, resultTerminateCode, QString::number(curInitialNodeNumber));
		curInitialNodeNumber++;
	}
	deleteResidualLabels(projectName);

	QFile resultCFile(projectDir + "/" + projectName + ".c");
	if (!resultCFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
		mErrorReporter.addError("cannot open \"" + resultCFile.fileName() + "\"");
		return;
	}

	//Output in the .c and .oil file
	QTextStream outC(&resultCFile);
	outC << mResultString;
	outC.flush();
	resultCFile.close();

	QTextStream outOIL(&resultOILFile);
	outOIL << mResultOIL;
	outOIL.flush();
	resultOILFile.close();
	generateFilesForBalancer(projectDir);
	generateMakeFile(toGenerate.isEmpty(), projectName, projectDir);
}

QList<SmartLine> &NxtOSEKRobotGenerator::variables()
{
	return mVariables;
}

QList<SmartLine> &NxtOSEKRobotGenerator::initCode()
{
	return mInitCode;
}

qrRepo::RepoApi const * const NxtOSEKRobotGenerator::api() const
{
	return mApi;
}

QByteArray NxtOSEKRobotGenerator::portValue1() const
{
	return mPortValue1;
}

QByteArray NxtOSEKRobotGenerator::portValue2() const
{
	return mPortValue2;
}

QByteArray NxtOSEKRobotGenerator::portValue3() const
{
	return mPortValue3;
}

QByteArray NxtOSEKRobotGenerator::portValue4() const
{
	return mPortValue4;
}

ErrorReporterInterface &NxtOSEKRobotGenerator::errorReporter() const
{
	return mErrorReporter;
}

qReal::Id &NxtOSEKRobotGenerator::previousElement()
{
	return mPreviousElement;
}

QList<QList<SmartLine> > &NxtOSEKRobotGenerator::generatedStringSet()
{
	return mGeneratedStringSet;
}

QMap<QString, QStack<int> > &NxtOSEKRobotGenerator::elementToStringListNumbers()
{
	return mElementToStringListNumbers;
}

QStack<qReal::Id> &NxtOSEKRobotGenerator::previousLoopElements()
{
	return mPreviousLoopElements;
}
<|endoftext|>


<commit_before><commit_msg>committed a remake of the WAV loader by Andreas H�fler<commit_after><|endoftext|>


<commit_before>#ifndef BLUETOE_SERVICES_GATT_HPP
#define BLUETOE_SERVICES_GATT_HPP

#include <bluetoe/service.hpp>
#include <bluetoe/characteristic.hpp>
#include <bluetoe/attribute_handle.hpp>

namespace bluetoe {

    namespace gatt {
        /**
         * @brief The assigned 16 bit UUID for the Generic Attribute Profile service
         */
        using service_uuid = service_uuid16< 0x1801 >;

        /**
         * @brief The assigned 16 bit UUID for Service Changed characteristic
         */
        using service_changed_uuid = characteristic_uuid16< 0x2A05 >;

        /**
         * @brief Service Changed characteristic
         */
        using service_changed_characteristic = characteristic<
            service_changed_uuid,
            indicate,
            no_read_access,
            fixed_uint32_value< 0xFFFF0001 >
        >;

        /**
         * @brief Generic Attribute Profile service with a single Service Changed characteristic
         *
         * As the handle of the Service Changed Value Attribute handle should be stable, equal
         * over all future versions of your server, this service should always be the first
         * service in the server. If that is not possible, use service_with_fixed_handles<> and
         * assign the attribute handles manually.
         */
        using service = ::bluetoe::service<
            service_uuid,
            service_changed_characteristic
        >;

        /**
         * @brief Generic Attribute Profile service with a single Service Changed characteristic
         *
         * This version allows manually allocating the attribute handles.
         */
        template <
            std::uint16_t ServiceHandle,
            std::uint16_t ServiceChangedCharDeclarationHandle = ServiceHandle + 1,
            std::uint16_t ServiceChangedCharValueHandle       = ServiceHandle + 2,
            std::uint16_t ServiceChangedCahrCCCDHandle        = ServiceHandle + 3 >
        using service_with_fixed_handles = ::bluetoe::service<
            attribute_handle< ServiceHandle >,
            service_uuid,
            characteristic<
                attribute_handles<
                    ServiceChangedCharDeclarationHandle,
                    ServiceChangedCharValueHandle,
                    ServiceChangedCahrCCCDHandle >,
                service_changed_uuid,
                indicate,
                no_read_access,
                fixed_uint32_value< 0xFFFF0001 >
            >
        >;
    }
}

#endif

<commit_msg>service changed characterstic must be readable<commit_after>#ifndef BLUETOE_SERVICES_GATT_HPP
#define BLUETOE_SERVICES_GATT_HPP

#include <bluetoe/service.hpp>
#include <bluetoe/characteristic.hpp>
#include <bluetoe/attribute_handle.hpp>

namespace bluetoe {

    namespace gatt {
        /**
         * @brief The assigned 16 bit UUID for the Generic Attribute Profile service
         */
        using service_uuid = service_uuid16< 0x1801 >;

        /**
         * @brief The assigned 16 bit UUID for Service Changed characteristic
         */
        using service_changed_uuid = characteristic_uuid16< 0x2A05 >;

        /**
         * @brief Service Changed characteristic
         */
        using service_changed_characteristic = characteristic<
            service_changed_uuid,
            indicate,
            fixed_uint32_value< 0xFFFF0001 >
        >;

        /**
         * @brief Generic Attribute Profile service with a single Service Changed characteristic
         *
         * As the handle of the Service Changed Value Attribute handle should be stable, equal
         * over all future versions of your server, this service should always be the first
         * service in the server. If that is not possible, use service_with_fixed_handles<> and
         * assign the attribute handles manually.
         */
        using service = ::bluetoe::service<
            service_uuid,
            service_changed_characteristic
        >;

        /**
         * @brief Generic Attribute Profile service with a single Service Changed characteristic
         *
         * This version allows manually allocating the attribute handles.
         */
        template <
            std::uint16_t ServiceHandle,
            std::uint16_t ServiceChangedCharDeclarationHandle = ServiceHandle + 1,
            std::uint16_t ServiceChangedCharValueHandle       = ServiceHandle + 2,
            std::uint16_t ServiceChangedCahrCCCDHandle        = ServiceHandle + 3 >
        using service_with_fixed_handles = ::bluetoe::service<
            attribute_handle< ServiceHandle >,
            service_uuid,
            characteristic<
                attribute_handles<
                    ServiceChangedCharDeclarationHandle,
                    ServiceChangedCharValueHandle,
                    ServiceChangedCahrCCCDHandle >,
                service_changed_uuid,
                indicate,
                fixed_uint32_value< 0xFFFF0001 >
            >
        >;
    }
}

#endif

<|endoftext|>


<commit_before>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// 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 "iceoryx_posh/roudi/memory/posix_shm_memory_provider.hpp"

#include "iceoryx_posh/internal/log/posh_logging.hpp"
#include "iceoryx_utils/internal/posix_wrapper/system_configuration.hpp"

#include "iceoryx_utils/platform/signal.hpp"
#include "iceoryx_utils/platform/unistd.hpp"

namespace iox
{
namespace roudi
{
namespace
{
void sigbusHandler(int32_t) noexcept
{
    char msg[] =
        "\033[0;1;97;41mFatal error:\033[m the available memory is insufficient. Cannot allocate mempools in shared "
        "memory. Please make sure that enough memory is available. For this, consider also the memory which is "
        "required for the [/iceoryx_mgmt] segment. Please refer to share/doc/iceoryx/FAQ.md in your release delivery.";
    size_t len = strlen(msg);
    size_t count [[gnu::unused]] = write(STDERR_FILENO, msg, len);
    _exit(EXIT_FAILURE);
}
} // namespace

PosixShmMemoryProvider::PosixShmMemoryProvider(const ShmNameString& shmName,
                                               const posix::AccessMode accessMode,
                                               const posix::OwnerShip ownership) noexcept
    : m_shmName(shmName)
    , m_accessMode(accessMode)
    , m_ownership(ownership)
{
}

PosixShmMemoryProvider::~PosixShmMemoryProvider() noexcept
{
    destroy();
}

cxx::expected<void*, MemoryProviderError> PosixShmMemoryProvider::createMemory(const uint64_t size,
                                                                               const uint64_t alignment) noexcept
{
    auto pageSize = posix::pageSize();
    if (!pageSize.has_value())
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::PAGE_SIZE_CHECK_ERROR);
    }

    if (alignment > posix::pageSize().value())
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::MEMORY_ALIGNMENT_EXCEEDS_PAGE_SIZE);
    }

    /// @todo the SIGBUS handler could maybe be moved to the RouDiMemoryManager

    // register signal handler for SIGBUS
    struct sigaction oldAct;
    struct sigaction newAct;
    sigemptyset(&newAct.sa_mask);
    newAct.sa_handler = sigbusHandler;
    newAct.sa_flags = 0;
    if (cxx::makeSmartC(sigaction, cxx::ReturnMode::PRE_DEFINED_SUCCESS_CODE, {0}, {}, SIGBUS, &newAct, &oldAct)
            .hasErrors())
    {
        LogFatal() << "Could not set signal handler for SIGBUS!";
        errorHandler(Error::kROUDI_MEMORY__COULD_NOT_REGISTER_SIGBUS, nullptr, ErrorLevel::FATAL);
    }

    // create and map a shared memory region
    m_shmObject = posix::SharedMemoryObject::create(m_shmName.c_str(), size, m_accessMode, m_ownership, nullptr);

    // unregister signal handler
    if (cxx::makeSmartC(sigaction, cxx::ReturnMode::PRE_DEFINED_SUCCESS_CODE, {0}, {}, SIGBUS, &oldAct, nullptr)
            .hasErrors())
    {
        LogFatal() << "Could not reset signal handler for SIGBUS!";
        errorHandler(Error::kROUDI_MEMORY__COULD_NOT_UNREGISTER_SIGBUS, nullptr, ErrorLevel::FATAL);
    }

    if (!m_shmObject.has_value())
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::MEMORY_CREATION_FAILED);
    }

    auto baseAddress = m_shmObject->getBaseAddress();
    if (baseAddress == nullptr)
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::MEMORY_CREATION_FAILED);
    }

    m_shmObject->finalizeAllocation();

    return cxx::success<void*>(baseAddress);
}

cxx::expected<MemoryProviderError> PosixShmMemoryProvider::destroyMemory() noexcept
{
    m_shmObject.reset();
    return cxx::success<void>();
}

} // namespace roudi
} // namespace iox
<commit_msg>iox-#91 Remove outdated todo<commit_after>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// 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 "iceoryx_posh/roudi/memory/posix_shm_memory_provider.hpp"

#include "iceoryx_posh/internal/log/posh_logging.hpp"
#include "iceoryx_utils/internal/posix_wrapper/system_configuration.hpp"

#include "iceoryx_utils/platform/signal.hpp"
#include "iceoryx_utils/platform/unistd.hpp"

namespace iox
{
namespace roudi
{
namespace
{
void sigbusHandler(int32_t) noexcept
{
    char msg[] =
        "\033[0;1;97;41mFatal error:\033[m the available memory is insufficient. Cannot allocate mempools in shared "
        "memory. Please make sure that enough memory is available. For this, consider also the memory which is "
        "required for the [/iceoryx_mgmt] segment. Please refer to share/doc/iceoryx/FAQ.md in your release delivery.";
    size_t len = strlen(msg);
    size_t count [[gnu::unused]] = write(STDERR_FILENO, msg, len);
    _exit(EXIT_FAILURE);
}
} // namespace

PosixShmMemoryProvider::PosixShmMemoryProvider(const ShmNameString& shmName,
                                               const posix::AccessMode accessMode,
                                               const posix::OwnerShip ownership) noexcept
    : m_shmName(shmName)
    , m_accessMode(accessMode)
    , m_ownership(ownership)
{
}

PosixShmMemoryProvider::~PosixShmMemoryProvider() noexcept
{
    destroy();
}

cxx::expected<void*, MemoryProviderError> PosixShmMemoryProvider::createMemory(const uint64_t size,
                                                                               const uint64_t alignment) noexcept
{
    auto pageSize = posix::pageSize();
    if (!pageSize.has_value())
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::PAGE_SIZE_CHECK_ERROR);
    }

    if (alignment > posix::pageSize().value())
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::MEMORY_ALIGNMENT_EXCEEDS_PAGE_SIZE);
    }

    // register signal handler for SIGBUS
    struct sigaction oldAct;
    struct sigaction newAct;
    sigemptyset(&newAct.sa_mask);
    newAct.sa_handler = sigbusHandler;
    newAct.sa_flags = 0;
    if (cxx::makeSmartC(sigaction, cxx::ReturnMode::PRE_DEFINED_SUCCESS_CODE, {0}, {}, SIGBUS, &newAct, &oldAct)
            .hasErrors())
    {
        LogFatal() << "Could not set signal handler for SIGBUS!";
        errorHandler(Error::kROUDI_MEMORY__COULD_NOT_REGISTER_SIGBUS, nullptr, ErrorLevel::FATAL);
    }

    // create and map a shared memory region
    m_shmObject = posix::SharedMemoryObject::create(m_shmName.c_str(), size, m_accessMode, m_ownership, nullptr);

    // unregister signal handler
    if (cxx::makeSmartC(sigaction, cxx::ReturnMode::PRE_DEFINED_SUCCESS_CODE, {0}, {}, SIGBUS, &oldAct, nullptr)
            .hasErrors())
    {
        LogFatal() << "Could not reset signal handler for SIGBUS!";
        errorHandler(Error::kROUDI_MEMORY__COULD_NOT_UNREGISTER_SIGBUS, nullptr, ErrorLevel::FATAL);
    }

    if (!m_shmObject.has_value())
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::MEMORY_CREATION_FAILED);
    }

    auto baseAddress = m_shmObject->getBaseAddress();
    if (baseAddress == nullptr)
    {
        return cxx::error<MemoryProviderError>(MemoryProviderError::MEMORY_CREATION_FAILED);
    }

    m_shmObject->finalizeAllocation();

    return cxx::success<void*>(baseAddress);
}

cxx::expected<MemoryProviderError> PosixShmMemoryProvider::destroyMemory() noexcept
{
    m_shmObject.reset();
    return cxx::success<void>();
}

} // namespace roudi
} // namespace iox
<|endoftext|>


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

#include "airbourne_board.h"
#include "rosflight.h"
#include "mavlink.h"

extern "C" {
/* The prototype shows it is a naked function - in effect this is just an
assembly function. */
void HardFault_Handler( void ) __attribute__( ( naked ) );
void reset(bool);

/* The fault handler implementation calls a function called
prvGetRegistersFromStack(). */
void HardFault_Handler(void)
{
    __asm volatile
    (
        " tst lr, #4                                                \n"
        " ite eq                                                    \n"
        " mrseq r0, msp                                             \n"
        " mrsne r0, psp                                             \n"
        " ldr r1, [r0, #24]                                         \n"
        " ldr r2, handler2_address_const                            \n"
        " bx r2                                                     \n"
        " handler2_address_const: .word prvGetRegistersFromStack    \n"
    );
}

void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress )
{
  /* These are volatile to try and prevent the compiler/linker optimising them
  away as the variables never actually get used.  If the debugger won't show the
  values of the variables, make them global my moving their declaration outside
  of this function. */
  volatile uint32_t r0;
  volatile uint32_t r1;
  volatile uint32_t r2;
  volatile uint32_t r3;
  volatile uint32_t r12;
  volatile uint32_t lr; /* Link register. */
  volatile uint32_t pc; /* Program counter. */
  volatile uint32_t psr;/* Program status register. */

  r0 = pulFaultStackAddress[ 0 ];
  r1 = pulFaultStackAddress[ 1 ];
  r2 = pulFaultStackAddress[ 2 ];
  r3 = pulFaultStackAddress[ 3 ];

  r12 = pulFaultStackAddress[ 4 ];
  lr = pulFaultStackAddress[ 5 ];
  pc = pulFaultStackAddress[ 6 ];
  psr = pulFaultStackAddress[ 7 ];

  // avoid compiler warnings about unused variables
  (void) r0;
  (void) r1;
  (void) r2;
  (void) r3;
  (void) r12;
  (void) lr;
  (void) pc;
  (void) psr;

  /* When the following line is hit, the variables contain the register values. */
  //reset(false);
  NVIC_SystemReset();
}

void NMI_Handler()
{
  while(1) {}
}

void MemManage_Handler()
{
  while(1) {}
}

void BusFault_Handler()
{
  while(1) {}
}

void UsageFault_Handler()
{
  while(1) {}
}

void WWDG_IRQHandler()
{
  while(1) {}
}
}
//Currently soft resets are not supported
void reset(bool hard_reset)
{
  rosflight_firmware::AirbourneBoard board;
  rosflight_firmware::Mavlink mavlink(board);
  rosflight_firmware::ROSflight firmware(board, mavlink);
  board.init_board();

  firmware.init();
  while (true)
  {
    firmware.run();
    if(board.clock_micros()/5e6>1e6)
    {
        void(*crashPtr)()=nullptr;
        crashPtr();
    }

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

#include "airbourne_board.h"
#include "rosflight.h"
#include "mavlink.h"

extern "C" {
/* The prototype shows it is a naked function - in effect this is just an
assembly function. */
void HardFault_Handler( void ) __attribute__( ( naked ) );
void reset(bool);

/* The fault handler implementation calls a function called
prvGetRegistersFromStack(). */
void HardFault_Handler(void)
{
    __asm volatile
    (
        " tst lr, #4                                                \n"
        " ite eq                                                    \n"
        " mrseq r0, msp                                             \n"
        " mrsne r0, psp                                             \n"
        " ldr r1, [r0, #24]                                         \n"
        " ldr r2, handler2_address_const                            \n"
        " bx r2                                                     \n"
        " handler2_address_const: .word prvGetRegistersFromStack    \n"
    );
}

void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress )
{
  /* These are volatile to try and prevent the compiler/linker optimising them
  away as the variables never actually get used.  If the debugger won't show the
  values of the variables, make them global my moving their declaration outside
  of this function. */
  volatile uint32_t r0;
  volatile uint32_t r1;
  volatile uint32_t r2;
  volatile uint32_t r3;
  volatile uint32_t r12;
  volatile uint32_t lr; /* Link register. */
  volatile uint32_t pc; /* Program counter. */
  volatile uint32_t psr;/* Program status register. */

  r0 = pulFaultStackAddress[ 0 ];
  r1 = pulFaultStackAddress[ 1 ];
  r2 = pulFaultStackAddress[ 2 ];
  r3 = pulFaultStackAddress[ 3 ];

  r12 = pulFaultStackAddress[ 4 ];
  lr = pulFaultStackAddress[ 5 ];
  pc = pulFaultStackAddress[ 6 ];
  psr = pulFaultStackAddress[ 7 ];

  // avoid compiler warnings about unused variables
  (void) r0;
  (void) r1;
  (void) r2;
  (void) r3;
  (void) r12;
  (void) lr;
  (void) pc;
  (void) psr;

  /* When the following line is hit, the variables contain the register values. */
  //reset(false);
  NVIC_SystemReset();
}

void NMI_Handler()
{
  while(1) {}
}

void MemManage_Handler()
{
  while(1) {}
}

void BusFault_Handler()
{
  while(1) {}
}

void UsageFault_Handler()
{
  while(1) {}
}

void WWDG_IRQHandler()
{
  while(1) {}
}
}
//Currently soft resets are not supported
void reset()
{
  rosflight_firmware::AirbourneBoard board;
  rosflight_firmware::Mavlink mavlink(board);
  rosflight_firmware::ROSflight firmware(board, mavlink);
  board.init_board();

  firmware.init();
  while (true)
  {
    firmware.run();
    if(board.clock_micros()/5e6>1e6)
    {
        void(*crashPtr)()=nullptr;
        crashPtr();
    }

  }
}
int main(void)
{
  reset();
  return 0;
}
<|endoftext|>


<commit_before>
/* =============================================================================
 *
 * Title:         Query devices for OpenGL/OpenCL interoperability
 * Author:        Felix Niederwanger
 * =============================================================================
 */

#include <iostream>
#include <vector>
#include <string>
#include <exception>

#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif

#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GL/glx.h>
#include <CL/cl_gl.h>

using namespace std;

static cl_context createOpenGlContext() {
	/* ==== Set up OpenGL. This is needed otherwise the current OpenGL device is not found by OpenGL ==== */
	int argc = 0;
	glutInit(&argc, NULL);
	glutCreateWindow("");

	GLenum res = glewInit();
    if (res != GLEW_OK)
    {
        string error = "Glew error";
        char* glewError = (char*)glewGetErrorString(res);
        error = error + string( glewError );
        throw error;
    }

	/* ==== Setting up OpenCL and query OpenGL shared devices==== */
	const int max_devices = 100;
	cl_int state;
	cl_platform_id platform[max_devices];
	cl_context context;
	cl_device_id devices[max_devices];

	//Get platform
	cl_uint numberOfPlatforms = 0;
	if(clGetPlatformIDs(100, platform, &numberOfPlatforms) != CL_SUCCESS)
		throw "Platform not found";
	if(numberOfPlatforms <= 0)
		throw "No platforms found";

	//Parameters needed to bind OpenGL's context to OpenCL's.
	cl_context_properties properties[] = {	CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
						CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
						CL_CONTEXT_PLATFORM, (cl_context_properties) platform[0],
						0};

	//Find openGL devices.
	typedef CL_API_ENTRY cl_int (CL_API_CALL *CLpointer)(const cl_context_properties *properties, cl_gl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret);
	CL_API_ENTRY cl_int (CL_API_CALL *myCLGetGLContextInfoKHR)(const cl_context_properties *properties, cl_gl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) = (CLpointer)clGetExtensionFunctionAddressForPlatform(platform[0], "clGetGLContextInfoKHR");

	size_t size;
	state = myCLGetGLContextInfoKHR(properties, CL_DEVICES_FOR_GL_CONTEXT_KHR, max_devices*sizeof(cl_device_id), devices, &size);

	if(state != CL_SUCCESS)
		throw "Devices resolution failed (clGetGLContextInfoKHR)";

	const int numberSharedDevices = (int)(size/sizeof(cl_device_id));
	if(numberSharedDevices <= 0) throw "No devices found";

	context = clCreateContext(properties, 1, &devices[0], NULL, NULL, &state);
	if(state != CL_SUCCESS)
		throw "Creating context failed";

	return context;
}

int main(int argc, char** argv) {
    cout << "OpenCL/OpenGL interoperability | Query devices" << endl;

	try {
		cl_context context = createOpenGlContext();
		if(context == NULL) {
			cerr << "Context initialisation failed" << endl;
			return EXIT_FAILURE;
		} else {
			cout << "  OpenGL/OpenCL shared context created successfully" << endl;
		}
	} catch (const char *msg) {
		cerr << "Creating OpenGL/OpenCL shared context failed: " << msg << endl;
		return EXIT_FAILURE;
	} catch (string &msg) {
		cerr << "Creating OpenGL/OpenCL shared context failed: " << msg << endl;
		return EXIT_FAILURE;
	}

    return EXIT_SUCCESS;
}
<commit_msg>Small update<commit_after>
/* =============================================================================
 *
 * Title:         Query devices for OpenGL/OpenCL interoperability
 * Author:        Felix Niederwanger
 * =============================================================================
 */

#include <iostream>
#include <vector>
#include <string>
#include <exception>

#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif

#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <GL/glx.h>
#include <CL/cl_gl.h>

using namespace std;

static cl_context createOpenGlContext(bool initGlut = false) {
	/* ==== Set up OpenGL. This is needed otherwise the current OpenGL device is not found by OpenGL ==== */
	if(initGlut) {
		int argc = 0;
		glutInit(&argc, NULL);
		glutCreateWindow("");

		GLenum res = glewInit();
		if (res != GLEW_OK)
		{
			string error = "Glew error";
			char* glewError = (char*)glewGetErrorString(res);
			error = error + string( glewError );
			throw error;
		}
    }

	/* ==== Setting up OpenCL and query OpenGL shared devices==== */
	const int max_devices = 100;
	cl_int state;
	cl_platform_id platform[max_devices];
	cl_context context;
	cl_device_id devices[max_devices];

	//Get platform
	cl_uint numberOfPlatforms = 0;
	if(clGetPlatformIDs(100, platform, &numberOfPlatforms) != CL_SUCCESS)
		throw "Platform not found";
	if(numberOfPlatforms <= 0)
		throw "No platforms found";

	//Parameters needed to bind OpenGL's context to OpenCL's.
	cl_context_properties properties[] = {	CL_GL_CONTEXT_KHR, (cl_context_properties) glXGetCurrentContext(),
						CL_GLX_DISPLAY_KHR, (cl_context_properties) glXGetCurrentDisplay(),
						CL_CONTEXT_PLATFORM, (cl_context_properties) platform[0],
						0};

	//Find openGL devices.
	typedef CL_API_ENTRY cl_int (CL_API_CALL *CLpointer)(const cl_context_properties *properties, cl_gl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret);
	CL_API_ENTRY cl_int (CL_API_CALL *myCLGetGLContextInfoKHR)(const cl_context_properties *properties, cl_gl_context_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) = (CLpointer)clGetExtensionFunctionAddressForPlatform(platform[0], "clGetGLContextInfoKHR");

	size_t size;
	state = myCLGetGLContextInfoKHR(properties, CL_DEVICES_FOR_GL_CONTEXT_KHR, max_devices*sizeof(cl_device_id), devices, &size);

	if(state != CL_SUCCESS)
		throw "Devices resolution failed (clGetGLContextInfoKHR)";

	const int numberSharedDevices = (int)(size/sizeof(cl_device_id));
	if(numberSharedDevices <= 0) throw "No devices found";

	context = clCreateContext(properties, 1, &devices[0], NULL, NULL, &state);
	if(state != CL_SUCCESS)
		throw "Creating context failed";

	return context;
}

int main(int argc, char** argv) {
    cout << "OpenCL/OpenGL interoperability | Query devices" << endl;

	// Manually init glut
	glutInit(&argc, argv);
	glutCreateWindow("");

	GLenum res = glewInit();
	if (res != GLEW_OK)
	{
		cerr << "Glew initialisation failed: " << glewGetErrorString(res) << endl;
		return EXIT_FAILURE;
	}

	try {
		cl_context context = createOpenGlContext();
		if(context == NULL) {
			cerr << "Context initialisation failed" << endl;
			return EXIT_FAILURE;
		} else {
			cout << "  OpenGL/OpenCL shared context created successfully" << endl;
		}
	} catch (const char *msg) {
		cerr << "Creating OpenGL/OpenCL shared context failed: " << msg << endl;
		return EXIT_FAILURE;
	} catch (string &msg) {
		cerr << "Creating OpenGL/OpenCL shared context failed: " << msg << endl;
		return EXIT_FAILURE;
	}

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>coverity#1242815 Result is not floating-point<commit_after><|endoftext|>


<commit_before><commit_msg>sw: fix regex search/replace of $ in selection<commit_after><|endoftext|>


<commit_before><commit_msg>Less confusing variable name.<commit_after><|endoftext|>