<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef SYMBOL_TABLE_H
#define SYMBOL_TABLE_H

#include <memory>
#include <string>
#include <unordered_map>

#include "Variable.hpp"
#include "Function.hpp"
#include "Struct.hpp"

namespace eddic {

typedef std::unordered_map<std::string, std::shared_ptr<Function>> FunctionMap;
typedef std::unordered_map<std::string, std::shared_ptr<Struct>> StructMap;

/*!
 * \class SymbolTable
 * \brief The global symbol table.
 *
 * This class is responsible for managing all the functions and the structs declarations of the current program.
 * It's also responsible of managing the reference count for the functions.
 */
class SymbolTable {
    private:
        FunctionMap functions;
        StructMap structs;

        void addPrintFunction(const std::string& function, BaseType parameterType);
        void defineStandardFunctions();

    public:
        SymbolTable();
        SymbolTable(const SymbolTable& rhs) = delete;

        /*!
         * Reset the symbol table.
         */
        void reset();

        /*!
         * Add the given function to the symbol table.
         * \param function The function to add to the symbol table.
         */
        void addFunction(std::shared_ptr<Function> function);

        /*!
         * Returns the function with the given name.
         * \param function The function to search for.
         * \return A pointer to the function with the given name.
         */
        std::shared_ptr<Function> getFunction(const std::string& function);

        /*!
         * Indicates if a function with the given name exists.
         * \param function The function to search for.
         * \return true if a function with the given name exists, otherwise false.
         */
        bool exists(const std::string& function);

        /*!
         * Add the given structure to the symbol table.
         * \param struct_ The structure to add to the symbol table.
         */
        void add_struct(std::shared_ptr<Struct> struct_);

        /*!
         * Returns the structure with the given name.
         * \param struct_ The structure to search for.
         * \return A pointer to the structure with the given name.
         */
        std::shared_ptr<Struct> get_struct(const std::string& struct_

        /*!
         * Indicates if a structure with the given name exists.
         * \param struct_ The structure to search for.
         * \return true if a structure with the given name exists, otherwise false.
         */
        bool struct_exists(const std::string& struct_);

        int member_offset(std::shared_ptr<Struct> struct_, const std::string& member);
        int member_offset_reverse(std::shared_ptr<Struct> struct_, const std::string& member);
        int size_of_struct(const std::string& struct_);

        /*!
         * Returns an iterator to the first function.
         * \return An iterator to the first function.
         */
        FunctionMap::const_iterator begin();

        /*!
         * Returns an iterator past the last function.
         * \return An iterator past the last function.
         */
        FunctionMap::const_iterator end();

        /*!
         * Add a reference to the function with the given name.
         * \param function The function to add a reference to.
         */
        void addReference(const std::string& function);

        /*!
         * Get the reference counter of the given function.
         * \param function The function to add a reference to.
         * \return The reference counter of the given function.
         */
        int referenceCount(const std::string& function);
};

/*!
 * The global symbol table.
 */
extern SymbolTable symbols;

} //end of eddic

#endif
<commit_msg>Fix typo<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef SYMBOL_TABLE_H
#define SYMBOL_TABLE_H

#include <memory>
#include <string>
#include <unordered_map>

#include "Variable.hpp"
#include "Function.hpp"
#include "Struct.hpp"

namespace eddic {

typedef std::unordered_map<std::string, std::shared_ptr<Function>> FunctionMap;
typedef std::unordered_map<std::string, std::shared_ptr<Struct>> StructMap;

/*!
 * \class SymbolTable
 * \brief The global symbol table.
 *
 * This class is responsible for managing all the functions and the structs declarations of the current program.
 * It's also responsible of managing the reference count for the functions.
 */
class SymbolTable {
    private:
        FunctionMap functions;
        StructMap structs;

        void addPrintFunction(const std::string& function, BaseType parameterType);
        void defineStandardFunctions();

    public:
        SymbolTable();
        SymbolTable(const SymbolTable& rhs) = delete;

        /*!
         * Reset the symbol table.
         */
        void reset();

        /*!
         * Add the given function to the symbol table.
         * \param function The function to add to the symbol table.
         */
        void addFunction(std::shared_ptr<Function> function);

        /*!
         * Returns the function with the given name.
         * \param function The function to search for.
         * \return A pointer to the function with the given name.
         */
        std::shared_ptr<Function> getFunction(const std::string& function);

        /*!
         * Indicates if a function with the given name exists.
         * \param function The function to search for.
         * \return true if a function with the given name exists, otherwise false.
         */
        bool exists(const std::string& function);

        /*!
         * Add the given structure to the symbol table.
         * \param struct_ The structure to add to the symbol table.
         */
        void add_struct(std::shared_ptr<Struct> struct_);

        /*!
         * Returns the structure with the given name.
         * \param struct_ The structure to search for.
         * \return A pointer to the structure with the given name.
         */
        std::shared_ptr<Struct> get_struct(const std::string& struct_);

        /*!
         * Indicates if a structure with the given name exists.
         * \param struct_ The structure to search for.
         * \return true if a structure with the given name exists, otherwise false.
         */
        bool struct_exists(const std::string& struct_);

        int member_offset(std::shared_ptr<Struct> struct_, const std::string& member);
        int member_offset_reverse(std::shared_ptr<Struct> struct_, const std::string& member);
        int size_of_struct(const std::string& struct_);

        /*!
         * Returns an iterator to the first function.
         * \return An iterator to the first function.
         */
        FunctionMap::const_iterator begin();

        /*!
         * Returns an iterator past the last function.
         * \return An iterator past the last function.
         */
        FunctionMap::const_iterator end();

        /*!
         * Add a reference to the function with the given name.
         * \param function The function to add a reference to.
         */
        void addReference(const std::string& function);

        /*!
         * Get the reference counter of the given function.
         * \param function The function to add a reference to.
         * \return The reference counter of the given function.
         */
        int referenceCount(const std::string& function);
};

/*!
 * The global symbol table.
 */
extern SymbolTable symbols;

} //end of eddic

#endif
<|endoftext|>


<commit_before>#pragma once

#include <algorithm>
#include <iterator>

namespace aid {

    // worst case: n^2
    // average case: n^2
    // best case: n^2
    // space complexity: 1
    template<typename It>
    void bubble_sort(It first, It last) {
        for (auto it = std::prev(last); it != first; --it)
            for (auto it2 = first; it2 != it; ++it2)
                if (*it2 > *std::next(it2))
                    std::iter_swap(it2, std::next(it2));
    }

}
<commit_msg>Added insertion sort<commit_after>#pragma once

#include <algorithm>
#include <iterator>

namespace aid {

    // worst case: n^2
    // average case: n^2
    // best case: n^2
    // space complexity: 1
    template<typename It>
    void bubble_sort(It first, It last) {
        for (auto it = std::prev(last); it != first; --it)
            for (auto it2 = first; it2 != it; ++it2)
                if (*it2 > *std::next(it2))
                    std::iter_swap(it2, std::next(it2));
    }

    // worst case: n^2
    // average case: n^2
    // best case: n
    // space complexity: 1
    template<typename It>
    void insertion_sort(It first, It last) {
        for (auto it = std::next(first); it != last; ++it)
            for (auto it2 = it; it2 != first && *std::prev(it2) > *it2; --it2)
                std::iter_swap(std::prev(it2), it2);
    }

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2010-2012 frankee zhou (frankee.zhou at gmail dot com)
 *
 * Distributed under 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 <cetty/shuttle/ShuttleBackend.h>

#include <cetty/handler/codec/LengthFieldBasedFrameDecoder.h>
#include <cetty/handler/codec/LengthFieldPrepender.h>
#include <cetty/service/builder/ClientBuilder.h>
#include <cetty/protobuf/service/ProtobufUtil.h>
#include <cetty/protobuf/service/ProtobufServicePtr.h>
#include <cetty/shuttle/protobuf/ProtobufProxyCodec.h>
#include <cetty/shuttle/protobuf/ProtobufProxyMessage.h>

namespace cetty {
namespace shuttle {

using namespace cetty::handler::codec;
using namespace cetty::service::builder;
using namespace cetty::protobuf::service;
using namespace cetty::shuttle::protobuf;

cetty::channel::ChannelPtr ShuttleBackend::emptyChannel_;
std::map<ThreadId, ShuttleBackendPtr> ShuttleBackend::backends_;

bool ShuttleBackend::initializeChannel(ChannelPipeline& pipeline) {
    pipeline.addLast<LengthFieldBasedFrameDecoder::Handler>(
        "frameDecoder",
        LengthFieldBasedFrameDecoder::HandlerPtr(new LengthFieldBasedFrameDecoder(
                    16 * 1024 * 1024,
                    0,
                    4,
                    0,
                    4,
                    4,
                    ProtobufUtil::adler32Checksum)));

    pipeline.addLast<LengthFieldPrepender::Handler>(
        "frameEncoder",
        LengthFieldPrepender::HandlerPtr(new LengthFieldPrepender(
                4,
                4,
                ProtobufUtil::adler32Checksum)));

    pipeline.addLast<ProtobufProxyCodec::Handler>(
        "protobufCodec",
        ProtobufProxyCodec::HandlerPtr(new ProtobufProxyCodec));

    return true;
}

void ShuttleBackend::configure(const std::map<std::string, Backend*>& config, const EventLoopPoolPtr& pool) {
    EventLoopPool::Iterator itr = pool->begin();

    for (; itr != pool->end(); ++itr) {
        ShuttleBackendPtr backend = ShuttleBackendPtr(new ShuttleBackend(*itr));
        backend->configure(config);
        backends_.insert(std::make_pair((*itr)->threadId(), backend));
    }
}

void ShuttleBackend::configure(const std::map<std::string, Backend*>& config) {
    std::map<std::string, Backend*>::const_iterator itr;

    for (itr = config.begin(); itr != config.end(); ++itr) {
        channels_.insert(std::make_pair(itr->first,
                                        builder_.build(itr->second->servers)));
    }
}

const ChannelPtr& ShuttleBackend::getChannel(const std::string& method) {
    std::map<ThreadId, ShuttleBackendPtr>::const_iterator itr =
        backends_.find(CurrentThread::id());

    if (itr != backends_.end()) {
        return itr->second->channel(method);
    }
    else {
        return emptyChannel_;
    }
}

const ChannelPtr& ShuttleBackend::channel(const std::string& method) const {
    std::map<std::string, ChannelPtr>::const_iterator itr =
        channels_.find(method);

    if (itr != channels_.end()) {
        return itr->second;
    }

    return emptyChannel_;
}

ShuttleBackend::ShuttleBackend(const EventLoopPtr& loop)
    : builder_(loop) {
    init();
}

void ShuttleBackend::init() {
    builder_.setClientInitializer(
        boost::bind(&ShuttleBackend::initializeChannel, this, _1));
}

}
}
<commit_msg>添加debug日志<commit_after>/*
 * Copyright (c) 2010-2012 frankee zhou (frankee.zhou at gmail dot com)
 *
 * Distributed under 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 <cetty/shuttle/ShuttleBackend.h>

#include <cetty/handler/codec/LengthFieldBasedFrameDecoder.h>
#include <cetty/handler/codec/LengthFieldPrepender.h>
#include <cetty/service/builder/ClientBuilder.h>
#include <cetty/protobuf/service/ProtobufUtil.h>
#include <cetty/protobuf/service/ProtobufServicePtr.h>
#include <cetty/shuttle/protobuf/ProtobufProxyCodec.h>
#include <cetty/shuttle/protobuf/ProtobufProxyMessage.h>

namespace cetty {
namespace shuttle {

using namespace cetty::handler::codec;
using namespace cetty::service::builder;
using namespace cetty::protobuf::service;
using namespace cetty::shuttle::protobuf;

cetty::channel::ChannelPtr ShuttleBackend::emptyChannel_;
std::map<ThreadId, ShuttleBackendPtr> ShuttleBackend::backends_;

bool ShuttleBackend::initializeChannel(ChannelPipeline& pipeline) {
    pipeline.addLast<LengthFieldBasedFrameDecoder::Handler>(
        "frameDecoder",
        LengthFieldBasedFrameDecoder::HandlerPtr(new LengthFieldBasedFrameDecoder(
                    16 * 1024 * 1024,
                    0,
                    4,
                    0,
                    4,
                    4,
                    ProtobufUtil::adler32Checksum)));

    pipeline.addLast<LengthFieldPrepender::Handler>(
        "frameEncoder",
        LengthFieldPrepender::HandlerPtr(new LengthFieldPrepender(
                4,
                4,
                ProtobufUtil::adler32Checksum)));

    pipeline.addLast<ProtobufProxyCodec::Handler>(
        "protobufCodec",
        ProtobufProxyCodec::HandlerPtr(new ProtobufProxyCodec));

    return true;
}

void ShuttleBackend::configure(const std::map<std::string, Backend*>& config,
                               const EventLoopPoolPtr& pool) {
    EventLoopPool::Iterator itr = pool->begin();

    for (; itr != pool->end(); ++itr) {
        ShuttleBackendPtr backend = ShuttleBackendPtr(new ShuttleBackend(*itr));
        backend->configure(config);
        ThreadId id = (*itr)->threadId();
        backends_.insert(std::make_pair(id, backend));
        LOG_DEBUG << "config backend for " << id;
    }
}

void ShuttleBackend::configure(const std::map<std::string, Backend*>& config) {
    std::map<std::string, Backend*>::const_iterator itr;

    for (itr = config.begin(); itr != config.end(); ++itr) {
        channels_.insert(std::make_pair(itr->first,
                                        builder_.build(itr->second->servers)));
        LOG_DEBUG << "config the channel in backend for " << itr->first;
    }
}

const ChannelPtr& ShuttleBackend::getChannel(const std::string& method) {
    ThreadId id = CurrentThread::id();
    std::map<ThreadId, ShuttleBackendPtr>::const_iterator itr =
        backends_.find(id);

    if (itr != backends_.end()) {
        return itr->second->channel(method);
    }
    else {
        LOG_WARN << "failed to found the channel for " << method
                 << " in " << id;
        return emptyChannel_;
    }
}

const ChannelPtr& ShuttleBackend::channel(const std::string& method) const {
    std::map<std::string, ChannelPtr>::const_iterator itr =
        channels_.find(method);

    if (itr != channels_.end()) {
        return itr->second;
    }
    else {
        LOG_WARN << "failed to found the channel for " << method;
        return emptyChannel_;
    }
}

ShuttleBackend::ShuttleBackend(const EventLoopPtr& loop)
    : builder_(loop) {
    init();
}

void ShuttleBackend::init() {
    builder_.setClientInitializer(
        boost::bind(&ShuttleBackend::initializeChannel, this, _1));
}

}
}
<|endoftext|>


<commit_before>/*
 * This file is part of `et engine`
 * Copyright 2009-2013 by Sergey Reznik
 * Please, do not modify content without approval.
 *
 */

#include <et/geometry/geometry.h>
#include <et/app/application.h>
#include <et/input/gestures.h>

using namespace et;

const float GesturesRecognizer::defaultClickTemporalThreshold = 0.25f;
const float GesturesRecognizer::defaultClickSpatialTreshold = 0.015f;
const float GesturesRecognizer::defaultHoldTemporalThreshold = 1.0f;

GesturesRecognizer::GesturesRecognizer(bool automaticMode) : InputHandler(automaticMode),
	_clickTemporalThreshold(defaultClickTemporalThreshold),
	_clickSpatialThreshold(defaultClickSpatialTreshold),
	_holdTemporalThreshold(defaultHoldTemporalThreshold)
{
}

void GesturesRecognizer::handlePointersMovement()
{
    if (_pointers.size() == 2)
    {
        vec2 currentPositions[2];
        vec2 previousPositions[2];

        size_t index = 0;
		for (auto& i : _pointers)
        {
            currentPositions[index] = i.second.current.normalizedPos;
            previousPositions[index] = i.second.previous.normalizedPos;
			i.second.moved = false;
			++index;
        }

		vec2 dir0 = currentPositions[0] - previousPositions[0];
		vec2 dir1 = currentPositions[1] - previousPositions[1];
		vec2 center = 0.5f * (previousPositions[0] + previousPositions[1]);

		RecognizedGesture gesture = _gesture;
		if (gesture == RecognizedGesture_NoGesture)
		{
			vec2 nDir0 = normalize(dir0);
			vec2 nDir1 = normalize(dir1);
			float direction = dot(nDir0, nDir1);
			if (direction < -0.5f)
			{
				bool catchZoom = (_recognizedGestures & RecognizedGesture_Zoom) == RecognizedGesture_Zoom;
				bool catchRotate = (_recognizedGestures & RecognizedGesture_Rotate) == RecognizedGesture_Rotate;

				if (catchZoom && catchRotate)
				{
					float aspect = std::abs(dot(nDir0, normalize(previousPositions[0] - center))) +
						std::abs(dot(nDir1, normalize(previousPositions[1] - center)));
					gesture = (aspect > SQRT_3) ? RecognizedGesture_Zoom : RecognizedGesture_Rotate;
				}
				else if (catchZoom)
				{
					gesture = RecognizedGesture_Zoom;
				}
				else if (catchRotate)
				{
					gesture = RecognizedGesture_Rotate;
				}
			}
			else if ((direction > 0.5f) && (_recognizedGestures & RecognizedGesture_Swipe))
			{
				gesture = RecognizedGesture_Swipe;
			}
		}

		switch (gesture)
		{
			case RecognizedGesture_Zoom:
			{
				float zoomValue = (currentPositions[0] - currentPositions[1]).length() /
					(previousPositions[0] - previousPositions[1]).length();

				zoomAroundPoint.invoke(zoomValue, center);
				zoom.invoke(zoomValue);
				break;
			}

			case RecognizedGesture_Rotate:
			{
				vec2 centerToCurrent0 = currentPositions[0] - center;
				vec2 centerToCurrent1 = currentPositions[1] - center;
				float angle0 = std::atan2(dir0.length(), centerToCurrent0.length());
				float angle1 = std::atan2(dir1.length(), centerToCurrent1.length());
				float angleValue = (outerProduct(centerToCurrent0, dir0) < 0.0f ? 0.5f : -0.5f) * (angle0 + angle1);
				rotate.invoke(angleValue);
				break;
			}

			case RecognizedGesture_Swipe:
			{
				swipe.invoke(0.5f * (dir0 + dir1), 2);
				break;
			}

			default:
				break;
		}

		if (_lockGestures)
			_gesture = gesture;

    }
}

void GesturesRecognizer::cancelWaitingForClicks()
{
	_shouldPerformClick = false;
	_shouldPerformDoubleClick = false;
	_singlePointer = PointerInputInfo();
	cancelUpdates();
}

void GesturesRecognizer::update(float t)
{
	if (t - _singlePointer.timestamp >= _clickTemporalThreshold)
	{
		click.invoke(_singlePointer);
		cancelWaitingForClicks();
	}
}

void GesturesRecognizer::onPointerPressed(et::PointerInputInfo pi)
{
	pointerPressed.invoke(pi);

	_pointers[pi.id] = PointersInputDelta(pi, pi);
	pressed.invoke(pi.normalizedPos, pi.type);

	if (_pointers.size() == 1)
	{
		if (_shouldPerformClick)
		{
			float dp = (pi.normalizedPos - _singlePointer.normalizedPos).dotSelf();
			if (dp <= sqr(_clickSpatialThreshold))
			{
				_shouldPerformClick = false;
				_shouldPerformDoubleClick = true;
			}
			else
			{
				click.invoke(_singlePointer);

				_singlePointer = pi;
				_shouldPerformClick = true;
				_shouldPerformDoubleClick = false;
			}
		}
		else
		{
			_shouldPerformClick = true;
			_singlePointer = pi;
		}

		_singlePointer.id = pi.id;
	}
	else
	{
		_singlePointer = PointerInputInfo();
		cancelWaitingForClicks();
	}
}

void GesturesRecognizer::onPointerMoved(et::PointerInputInfo pi)
{
	pointerMoved.invoke(pi);

	if ((pi.id == 0) || (_pointers.count(pi.id) == 0)) return;

	if (_pointers.size() == 1)
	{
		bool hasPressedPointer = (_singlePointer.id != 0);
		bool shouldPerformMovement = !hasPressedPointer;

		if (hasPressedPointer && (pi.id == _singlePointer.id))
		{
			float len = (pi.normalizedPos - _singlePointer.normalizedPos).dotSelf();
			shouldPerformMovement = (len >= sqr(_clickSpatialThreshold));
		}

		if (shouldPerformMovement)
		{
			if (hasPressedPointer)
			{
				cancelWaitingForClicks();
				clickCancelled.invoke();
			}

			_pointers[pi.id].moved = true;
			_pointers[pi.id].previous = _pointers[pi.id].current;
			_pointers[pi.id].current = pi;

			const PointerInputInfo& pPrev = _pointers[pi.id].previous;
			const PointerInputInfo& pCurr = _pointers[pi.id].current;

			vec2 offset = pCurr.normalizedPos - pPrev.normalizedPos;
			vec2 speed = offset / etMax(0.01f, pCurr.timestamp - pPrev.timestamp);

			moved.invoke(pi.normalizedPos, pi.type);

			if (pCurr.type == PointerType_General)
				dragWithGeneralPointer.invokeInMainRunLoop(speed, offset);

			drag.invoke(speed, pi.type);
		}
	}
	else
	{
		cancelWaitingForClicks();

		_pointers[pi.id].moved = true;
		_pointers[pi.id].previous = _pointers[pi.id].current;
		_pointers[pi.id].current = pi;

		bool allMoved = true;
		for (auto& p : _pointers)
		{
			if (!p.second.moved)
			{
				allMoved = false;
				break;
			}
		};

		if (allMoved)
			handlePointersMovement();
	}
}

void GesturesRecognizer::onPointerReleased(et::PointerInputInfo pi)
{
	pointerReleased.invoke(pi);

	_gesture = RecognizedGesture_NoGesture;
	_pointers.erase(pi.id);

	released.invoke(pi.normalizedPos, pi.type);

	if (pi.id == _singlePointer.id)
	{
		if ((pi.normalizedPos - _singlePointer.normalizedPos).dotSelf() > sqr(_clickSpatialThreshold))
		{
			cancelWaitingForClicks();
		}
		else if (_shouldPerformClick)
		{
			float dt = pi.timestamp - _singlePointer.timestamp;
			if ((dt > _clickTemporalThreshold))
			{
				click.invoke(_singlePointer);
				cancelWaitingForClicks();
			}
			else
			{
				startUpdates();
			}
		}
		else if (_shouldPerformDoubleClick)
		{
			doubleClick.invoke(_singlePointer);
			cancelWaitingForClicks();
		}
	}
}

void GesturesRecognizer::onPointerCancelled(et::PointerInputInfo pi)
{
	pointerCancelled.invoke(pi);

	_pointers.erase(pi.id);
	cancelled.invoke(pi.normalizedPos, pi.type);

	if (pi.id == _singlePointer.id)
		cancelWaitingForClicks();
}

void GesturesRecognizer::onPointerScrolled(et::PointerInputInfo i)
{
	pointerScrolled.invoke(i);
	scroll.invoke(i.scroll, i.origin);
}

void GesturesRecognizer::onGesturePerformed(GestureInputInfo i)
{
	if (i.mask & GestureTypeMask_Zoom)
		zoom.invoke(1.0f - i.values.z);

	if (i.mask & GestureTypeMask_Swipe)
		drag.invoke(i.values.xy(), PointerType_None);

	if (i.mask & GestureTypeMask_Rotate)
		rotate.invokeInMainRunLoop(i.values.w);
}

void GesturesRecognizer::setRecognizedGestures(size_t values)
{
	_recognizedGestures = values;

	if ((values & _gesture) == 0)
		_gesture = RecognizedGesture_NoGesture;
}
<commit_msg>gestures default threshold changed<commit_after>/*
 * This file is part of `et engine`
 * Copyright 2009-2013 by Sergey Reznik
 * Please, do not modify content without approval.
 *
 */

#include <et/geometry/geometry.h>
#include <et/app/application.h>
#include <et/input/gestures.h>

using namespace et;

const float GesturesRecognizer::defaultClickTemporalThreshold = 0.25f;
const float GesturesRecognizer::defaultClickSpatialTreshold = std::sqrt(50.0f);
const float GesturesRecognizer::defaultHoldTemporalThreshold = 1.0f;

GesturesRecognizer::GesturesRecognizer(bool automaticMode) : InputHandler(automaticMode),
	_clickTemporalThreshold(defaultClickTemporalThreshold),
	_clickSpatialThreshold(defaultClickSpatialTreshold),
	_holdTemporalThreshold(defaultHoldTemporalThreshold)
{
}

void GesturesRecognizer::handlePointersMovement()
{
    if (_pointers.size() == 2)
    {
        vec2 currentPositions[2];
        vec2 previousPositions[2];

        size_t index = 0;
		for (auto& i : _pointers)
        {
            currentPositions[index] = i.second.current.normalizedPos;
            previousPositions[index] = i.second.previous.normalizedPos;
			i.second.moved = false;
			++index;
        }

		vec2 dir0 = currentPositions[0] - previousPositions[0];
		vec2 dir1 = currentPositions[1] - previousPositions[1];
		vec2 center = 0.5f * (previousPositions[0] + previousPositions[1]);

		RecognizedGesture gesture = _gesture;
		if (gesture == RecognizedGesture_NoGesture)
		{
			vec2 nDir0 = normalize(dir0);
			vec2 nDir1 = normalize(dir1);
			float direction = dot(nDir0, nDir1);
			if (direction < -0.5f)
			{
				bool catchZoom = (_recognizedGestures & RecognizedGesture_Zoom) == RecognizedGesture_Zoom;
				bool catchRotate = (_recognizedGestures & RecognizedGesture_Rotate) == RecognizedGesture_Rotate;

				if (catchZoom && catchRotate)
				{
					float aspect = std::abs(dot(nDir0, normalize(previousPositions[0] - center))) +
						std::abs(dot(nDir1, normalize(previousPositions[1] - center)));
					gesture = (aspect > SQRT_3) ? RecognizedGesture_Zoom : RecognizedGesture_Rotate;
				}
				else if (catchZoom)
				{
					gesture = RecognizedGesture_Zoom;
				}
				else if (catchRotate)
				{
					gesture = RecognizedGesture_Rotate;
				}
			}
			else if ((direction > 0.5f) && (_recognizedGestures & RecognizedGesture_Swipe))
			{
				gesture = RecognizedGesture_Swipe;
			}
		}

		switch (gesture)
		{
			case RecognizedGesture_Zoom:
			{
				float zoomValue = (currentPositions[0] - currentPositions[1]).length() /
					(previousPositions[0] - previousPositions[1]).length();

				zoomAroundPoint.invoke(zoomValue, center);
				zoom.invoke(zoomValue);
				break;
			}

			case RecognizedGesture_Rotate:
			{
				vec2 centerToCurrent0 = currentPositions[0] - center;
				vec2 centerToCurrent1 = currentPositions[1] - center;
				float angle0 = std::atan2(dir0.length(), centerToCurrent0.length());
				float angle1 = std::atan2(dir1.length(), centerToCurrent1.length());
				float angleValue = (outerProduct(centerToCurrent0, dir0) < 0.0f ? 0.5f : -0.5f) * (angle0 + angle1);
				rotate.invoke(angleValue);
				break;
			}

			case RecognizedGesture_Swipe:
			{
				swipe.invoke(0.5f * (dir0 + dir1), 2);
				break;
			}

			default:
				break;
		}

		if (_lockGestures)
			_gesture = gesture;

    }
}

void GesturesRecognizer::cancelWaitingForClicks()
{
	_shouldPerformClick = false;
	_shouldPerformDoubleClick = false;
	_singlePointer = PointerInputInfo();
	cancelUpdates();
}

void GesturesRecognizer::update(float t)
{
	if (t - _singlePointer.timestamp >= _clickTemporalThreshold)
	{
		click.invoke(_singlePointer);
		cancelWaitingForClicks();
	}
}

void GesturesRecognizer::onPointerPressed(et::PointerInputInfo pi)
{
	pointerPressed.invoke(pi);

	_pointers[pi.id] = PointersInputDelta(pi, pi);

	pressed.invoke(pi.normalizedPos, pi.type);

	if (_pointers.size() == 1)
	{
		if (_shouldPerformClick)
		{
			if ((pi.pos - _singlePointer.pos).dotSelf() <= sqr(_clickSpatialThreshold))
			{
				_shouldPerformClick = false;
				_shouldPerformDoubleClick = true;
			}
			else
			{
				click.invoke(_singlePointer);

				_singlePointer = pi;
				_shouldPerformClick = true;
				_shouldPerformDoubleClick = false;
			}
		}
		else
		{
			_shouldPerformClick = true;
			_singlePointer = pi;
		}

		_singlePointer.id = pi.id;
	}
	else
	{
		_singlePointer = PointerInputInfo();
		cancelWaitingForClicks();
	}
}

void GesturesRecognizer::onPointerMoved(et::PointerInputInfo pi)
{
	pointerMoved.invoke(pi);

	if ((pi.id == 0) || (_pointers.count(pi.id) == 0)) return;

	if (_pointers.size() == 1)
	{
		bool hasPressedPointer = (_singlePointer.id != 0);
		bool shouldPerformMovement = !hasPressedPointer;

		if (hasPressedPointer && (pi.id == _singlePointer.id))
		{
			float len = (pi.pos - _singlePointer.pos).dotSelf();
			shouldPerformMovement = (len >= sqr(_clickSpatialThreshold));
		}

		if (shouldPerformMovement)
		{
			if (hasPressedPointer)
			{
				cancelWaitingForClicks();
				clickCancelled.invoke();
			}

			_pointers[pi.id].moved = true;
			_pointers[pi.id].previous = _pointers[pi.id].current;
			_pointers[pi.id].current = pi;

			const PointerInputInfo& pPrev = _pointers[pi.id].previous;
			const PointerInputInfo& pCurr = _pointers[pi.id].current;

			vec2 offset = pCurr.normalizedPos - pPrev.normalizedPos;
			vec2 speed = offset / etMax(0.01f, pCurr.timestamp - pPrev.timestamp);

			moved.invoke(pi.normalizedPos, pi.type);

			if (pCurr.type == PointerType_General)
				dragWithGeneralPointer.invokeInMainRunLoop(speed, offset);

			drag.invoke(speed, pi.type);
		}
	}
	else
	{
		cancelWaitingForClicks();

		_pointers[pi.id].moved = true;
		_pointers[pi.id].previous = _pointers[pi.id].current;
		_pointers[pi.id].current = pi;

		bool allMoved = true;
		for (auto& p : _pointers)
		{
			if (!p.second.moved)
			{
				allMoved = false;
				break;
			}
		};

		if (allMoved)
			handlePointersMovement();
	}
}

void GesturesRecognizer::onPointerReleased(et::PointerInputInfo pi)
{
	pointerReleased.invoke(pi);

	_gesture = RecognizedGesture_NoGesture;
	_pointers.erase(pi.id);

	released.invoke(pi.normalizedPos, pi.type);

	if (pi.id == _singlePointer.id)
	{
		if ((pi.normalizedPos - _singlePointer.normalizedPos).dotSelf() > sqr(_clickSpatialThreshold))
		{
			cancelWaitingForClicks();
		}
		else if (_shouldPerformClick)
		{
			float dt = pi.timestamp - _singlePointer.timestamp;
			if ((dt > _clickTemporalThreshold))
			{
				click.invoke(_singlePointer);
				cancelWaitingForClicks();
			}
			else
			{
				startUpdates();
			}
		}
		else if (_shouldPerformDoubleClick)
		{
			doubleClick.invoke(_singlePointer);
			cancelWaitingForClicks();
		}
	}
}

void GesturesRecognizer::onPointerCancelled(et::PointerInputInfo pi)
{
	pointerCancelled.invoke(pi);

	_pointers.erase(pi.id);
	cancelled.invoke(pi.normalizedPos, pi.type);

	if (pi.id == _singlePointer.id)
		cancelWaitingForClicks();
}

void GesturesRecognizer::onPointerScrolled(et::PointerInputInfo i)
{
	pointerScrolled.invoke(i);
	scroll.invoke(i.scroll, i.origin);
}

void GesturesRecognizer::onGesturePerformed(GestureInputInfo i)
{
	if (i.mask & GestureTypeMask_Zoom)
		zoom.invoke(1.0f - i.values.z);

	if (i.mask & GestureTypeMask_Swipe)
		drag.invoke(i.values.xy(), PointerType_None);

	if (i.mask & GestureTypeMask_Rotate)
		rotate.invokeInMainRunLoop(i.values.w);
}

void GesturesRecognizer::setRecognizedGestures(size_t values)
{
	_recognizedGestures = values;

	if ((values & _gesture) == 0)
		_gesture = RecognizedGesture_NoGesture;
}
<|endoftext|>


<commit_before>#include "BasicTexture.h"

BasicTexture::BasicTexture(const std::string& file)
{
    loadFromFile(file);
}

void BasicTexture::loadFromImage(const sf::Image& i)
{
    glGenTextures(1, &m_id);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_id);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, i.getSize().x, i.getSize().y,
                 0, GL_RGBA, GL_UNSIGNED_BYTE, i.getPixelsPtr());

    glGenerateMipmap(GL_TEXTURE_2D);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);

}
void BasicTexture::loadFromFile(const std::string& file)
{
    sf::Image i;
    if(!i.loadFromFile("Res/Textures/" + file + ".png"))
    {
        throw std::runtime_error("Unable to load BasicTexture: " + file);
    }

    loadFromImage(i);
}

BasicTexture::~BasicTexture()
{
    glDeleteTextures(1, &m_id);
}

void BasicTexture::bindTexture() const
{
    glBindTexture(GL_TEXTURE_2D, m_id);
}

<commit_msg>Modified texture mapping.<commit_after>#include "BasicTexture.h"

BasicTexture::BasicTexture(const std::string& file)
{
    loadFromFile(file);
}

void BasicTexture::loadFromImage(const sf::Image& i)
{
    glGenTextures(1, &m_id);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_id);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, i.getSize().x, i.getSize().y,
                 0, GL_RGBA, GL_UNSIGNED_BYTE, i.getPixelsPtr());

    glGenerateMipmap(GL_TEXTURE_2D);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);

}
void BasicTexture::loadFromFile(const std::string& file)
{
    sf::Image i;
    if(!i.loadFromFile("Res/Textures/" + file + ".png"))
    {
        throw std::runtime_error("Unable to load BasicTexture: " + file);
    }

    loadFromImage(i);
}

BasicTexture::~BasicTexture()
{
    glDeleteTextures(1, &m_id);
}

void BasicTexture::bindTexture() const
{
    glBindTexture(GL_TEXTURE_2D, m_id);
}

<|endoftext|>


<commit_before>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

// needed for IDE
#include "DistrhoPluginInfo.h"

#include "DistrhoUI.hpp"

#if defined(DISTRHO_OS_MAC)
# import <Cocoa/Cocoa.h>
#elif defined(DISTRHO_OS_WINDOWS)
#else
# include <sys/types.h>
# include <X11/Xatom.h>
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# define X11Key_Escape 9
#endif

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------------------------------------------

class EmbedExternalExampleUI : public UI
{
#if defined(DISTRHO_OS_MAC)
    NSView* fView;
    id fWindow;
#elif defined(DISTRHO_OS_WINDOWS)
#else
    ::Display* fDisplay;
    ::Window fWindow;
#endif

public:
    EmbedExternalExampleUI()
        : UI(512, 256),
#if defined(DISTRHO_OS_MAC)
          fView(nullptr),
          fWindow(nil),
#elif defined(DISTRHO_OS_WINDOWS)
#else
          fDisplay(nullptr),
          fWindow(0),
#endif
          fValue(0.0f)
    {
#if defined(DISTRHO_OS_MAC)
        NSAutoreleasePool* const pool = [[NSAutoreleasePool alloc] init];
        [NSApplication sharedApplication];

        if (isEmbed())
        {
            // [fView retain];
            // [(NSView*)getParentWindowHandle() fView];
        }
        else
        {
            fWindow = [[NSWindow new]retain];
            DISTRHO_SAFE_ASSERT_RETURN(fWindow != nil,);

            [fWindow setIsVisible:NO];

            if (NSString* const nsTitle = [[NSString alloc]
                                            initWithBytes:getTitle()
                                                   length:strlen(getTitle())
                                                 encoding:NSUTF8StringEncoding])
                [fWindow setTitle:nsTitle];

            // [fWindow setContentView:impl->view];
            // [fWindow makeFirstResponder:impl->view];
            [fWindow makeKeyAndOrderFront:fWindow];
        }

        [pool release];
#elif defined(DISTRHO_OS_WINDOWS)
#else
        fDisplay = XOpenDisplay(nullptr);
        DISTRHO_SAFE_ASSERT_RETURN(fDisplay != nullptr,);

        const int screen = DefaultScreen(fDisplay);
        const ::Window root   = RootWindow(fDisplay, screen);
        const ::Window parent = isEmbed() ? (::Window)getParentWindowHandle() : root;

        fWindow = XCreateSimpleWindow(fDisplay, parent, 0, 0, getWidth(), getHeight(), 0, 0, 0);
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);

        XSizeHints sizeHints = {};
        sizeHints.flags      = PMinSize;
        sizeHints.min_width  = getWidth();
        sizeHints.min_height = getHeight();
        XSetNormalHints(fDisplay, fWindow, &sizeHints);
        XStoreName(fDisplay, fWindow, getTitle());

        if (parent == root)
        {
            // grab Esc key for auto-close
            XGrabKey(fDisplay, X11Key_Escape, AnyModifier, fWindow, 1, GrabModeAsync, GrabModeAsync);

            // destroy window on close
            Atom wmDelete = XInternAtom(fDisplay, "WM_DELETE_WINDOW", True);
            XSetWMProtocols(fDisplay, fWindow, &wmDelete, 1);

            // set pid WM hint
            const pid_t pid = getpid();
            const Atom _nwp = XInternAtom(fDisplay, "_NET_WM_PID", False);
            XChangeProperty(fDisplay, fWindow, _nwp, XA_CARDINAL, 32, PropModeReplace, (const uchar*)&pid, 1);

            // set the window to both dialog and normal to produce a decorated floating dialog
            // order is important: DIALOG needs to come before NORMAL
            const Atom _wt = XInternAtom(fDisplay, "_NET_WM_WINDOW_TYPE", False);
            const Atom _wts[2] = {
                XInternAtom(fDisplay, "_NET_WM_WINDOW_TYPE_DIALOG", False),
                XInternAtom(fDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False)
            };
            XChangeProperty(fDisplay, fWindow, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, 2);
        }
#endif
    }

    ~EmbedExternalExampleUI()
    {
#if defined(DISTRHO_OS_MAC)
        if (fWindow != nil)
            [fWindow close];

        if (fView != nullptr)
            [fView release];

        if (fWindow != nil)
            [fWindow release];
#elif defined(DISTRHO_OS_WINDOWS)
#else
        if (fDisplay == nullptr)
            return;

        if (fWindow != 0)
            XDestroyWindow(fDisplay, fWindow);

        XCloseDisplay(fDisplay);
#endif
    }

protected:
   /* --------------------------------------------------------------------------------------------------------
    * DSP/Plugin Callbacks */

   /**
      A parameter has changed on the plugin side.
      This is called by the host to inform the UI about parameter changes.
    */
    void parameterChanged(uint32_t index, float value) override
    {
        if (index != 0)
            return;

        fValue = value;
    }

   /* --------------------------------------------------------------------------------------------------------
    * External Window overrides */

    uintptr_t getNativeWindowHandle() const noexcept override
    {
#if defined(DISTRHO_OS_MAC)
        return (uintptr_t)fView;
#elif defined(DISTRHO_OS_WINDOWS)
#else
        return (uintptr_t)fWindow;
#endif
        return 0;
    }

    void titleChanged(const char* const title) override
    {
        d_stdout("visibilityChanged %s", title);
#if defined(DISTRHO_OS_MAC)
        if (fWindow != nil)
        {
            if (NSString* const nsTitle = [[NSString alloc]
                                           initWithBytes:title
                                                  length:strlen(title)
                                                encoding:NSUTF8StringEncoding])
            {
                [fWindow setTitle:nsTitle];
            }
        }
#elif defined(DISTRHO_OS_WINDOWS)
#else
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);
        XStoreName(fDisplay, fWindow, title);
#endif
    }

    void transientParentWindowChanged(const uintptr_t winId) override
    {
        d_stdout("transientParentWindowChanged %lu", winId);
#if defined(DISTRHO_OS_MAC)
#elif defined(DISTRHO_OS_WINDOWS)
#else
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);
        XSetTransientForHint(fDisplay, fWindow, (::Window)winId);
#endif
    }

    void visibilityChanged(const bool visible) override
    {
        d_stdout("visibilityChanged %d", visible);
#if defined(DISTRHO_OS_MAC)
        if (fWindow != nil)
            [fWindow setIsVisible:(visible ? YES : NO)];
        else if (fView != nullptr)
            [fView setHidden:(visible ? NO : YES)];
#elif defined(DISTRHO_OS_WINDOWS)
#else
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);
        if (visible)
            XMapRaised(fDisplay, fWindow);
        else
            XUnmapWindow(fDisplay, fWindow);
#endif
    }

    void uiIdle() override
    {
        // d_stdout("uiIdle");
#if defined(DISTRHO_OS_MAC)
        NSAutoreleasePool* const pool = [[NSAutoreleasePool alloc] init];
        NSDate* const date = [NSDate distantPast];

        for (NSEvent* event;;)
        {
            event = [NSApp
                     nextEventMatchingMask:NSAnyEventMask
                                 untilDate:date
                                    inMode:NSDefaultRunLoopMode
                                   dequeue:YES];

            if (event == nil)
                break;

            [NSApp sendEvent: event];
        }

        [pool release];
#elif defined(DISTRHO_OS_WINDOWS)
        MSG msg;
        if (! ::PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE))
            return true;

        if (::GetMessage(&msg, nullptr, 0, 0) >= 0)
        {
            if (msg.message == WM_QUIT)
                return false;

            //TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
#else
        if (fDisplay == nullptr)
            return;

        for (XEvent event; XPending(fDisplay) > 0;)
        {
            XNextEvent(fDisplay, &event);

            if (! isVisible())
                continue;

            switch (event.type)
            {
            case ClientMessage:
                if (char* const type = XGetAtomName(fDisplay, event.xclient.message_type))
                {
                    if (std::strcmp(type, "WM_PROTOCOLS") == 0)
                        hide();
                }
                break;

            case KeyRelease:
                if (event.xkey.keycode == X11Key_Escape)
                    hide();
                break;
            }
        }
#endif
    }

    // -------------------------------------------------------------------------------------------------------

private:
    // Current value, cached for when UI becomes visible
    float fValue;

   /**
      Set our UI class as non-copyable and add a leak detector just in case.
    */
    DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EmbedExternalExampleUI)
};

/* ------------------------------------------------------------------------------------------------------------
 * UI entry point, called by DPF to create a new UI instance. */

UI* createUI()
{
    return new EmbedExternalExampleUI();
}

// -----------------------------------------------------------------------------------------------------------

END_NAMESPACE_DISTRHO
<commit_msg>More embed-external-ui example macOS code, but still no window :(<commit_after>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

// needed for IDE
#include "DistrhoPluginInfo.h"

#include "DistrhoUI.hpp"

#if defined(DISTRHO_OS_MAC)
# import <Cocoa/Cocoa.h>
#elif defined(DISTRHO_OS_WINDOWS)
#else
# include <sys/types.h>
# include <X11/Xatom.h>
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# define X11Key_Escape 9
#endif

#if defined(DISTRHO_OS_MAC)
@interface NSExternalWindow : NSWindow
@end
@implementation NSExternalWindow
- (id)initWithContentRect:(NSRect)contentRect
                styleMask:(unsigned long)aStyle
                  backing:(NSBackingStoreType)bufferingType
                    defer:(BOOL)flag
{
    NSWindow* result = [super initWithContentRect:contentRect
                                        styleMask:aStyle
                                          backing:bufferingType
                                            defer:flag];
    [result setAcceptsMouseMovedEvents:YES];
    return (NSExternalWindow*)result;
}
- (BOOL)canBecomeKeyWindow
{
    return YES;
}
- (BOOL)canBecomeMainWindow
{
    return NO;
}
@end
#endif

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------------------------------------------

class EmbedExternalExampleUI : public UI
{
#if defined(DISTRHO_OS_MAC)
    NSView* fView;
    NSExternalWindow* fWindow;
#elif defined(DISTRHO_OS_WINDOWS)
#else
    ::Display* fDisplay;
    ::Window fWindow;
#endif

public:
    EmbedExternalExampleUI()
        : UI(512, 256),
#if defined(DISTRHO_OS_MAC)
          fView(nullptr),
          fWindow(nullptr),
#elif defined(DISTRHO_OS_WINDOWS)
#else
          fDisplay(nullptr),
          fWindow(0),
#endif
          fValue(0.0f)
    {
#if defined(DISTRHO_OS_MAC)
        if (isStandalone())
        {
            [[NSApplication sharedApplication]new];
            [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
            [NSApp activateIgnoringOtherApps:YES];
        }

        NSAutoreleasePool* const pool = [[NSAutoreleasePool alloc] init];
        [NSApplication sharedApplication];

        fView = [NSView new];
        DISTRHO_SAFE_ASSERT_RETURN(fView != nullptr,);

        [fView initWithFrame:NSMakeRect(0, 0, getWidth(), getHeight())];
        [fView setAutoresizesSubviews:YES];
        [fView setFrame:NSMakeRect(0, 0, getWidth(), getHeight())];
        [fView setHidden:NO];
        [fView setNeedsDisplay:YES];

        if (isEmbed())
        {
            [fView retain];
            [(NSView*)getParentWindowHandle() addSubview:fView];
        }
        else
        {
            fWindow = [[[NSExternalWindow alloc]
                         initWithContentRect:[fView frame]
                                   styleMask:(NSWindowStyleMaskClosable | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable)
                                     backing:NSBackingStoreBuffered
                                       defer:NO]retain];
            DISTRHO_SAFE_ASSERT_RETURN(fWindow != nullptr,);

            // [fWindow setIsVisible:NO];

            if (NSString* const nsTitle = [[NSString alloc]
                                            initWithBytes:getTitle()
                                                   length:strlen(getTitle())
                                                 encoding:NSUTF8StringEncoding])
                [fWindow setTitle:nsTitle];

            [fWindow setContentView:fView];
            [fWindow setContentSize:NSMakeSize(getWidth(), getHeight())];
            [fWindow makeFirstResponder:fView];
            [fWindow makeKeyAndOrderFront:fWindow];
            d_stdout("created window with size %u %u", getWidth(), getHeight());
        }

        [pool release];
#elif defined(DISTRHO_OS_WINDOWS)
#else
        fDisplay = XOpenDisplay(nullptr);
        DISTRHO_SAFE_ASSERT_RETURN(fDisplay != nullptr,);

        const int screen = DefaultScreen(fDisplay);
        const ::Window root   = RootWindow(fDisplay, screen);
        const ::Window parent = isEmbed() ? (::Window)getParentWindowHandle() : root;

        fWindow = XCreateSimpleWindow(fDisplay, parent, 0, 0, getWidth(), getHeight(), 0, 0, 0);
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);

        XSizeHints sizeHints = {};
        sizeHints.flags      = PMinSize;
        sizeHints.min_width  = getWidth();
        sizeHints.min_height = getHeight();
        XSetNormalHints(fDisplay, fWindow, &sizeHints);
        XStoreName(fDisplay, fWindow, getTitle());

        if (parent == root)
        {
            // grab Esc key for auto-close
            XGrabKey(fDisplay, X11Key_Escape, AnyModifier, fWindow, 1, GrabModeAsync, GrabModeAsync);

            // destroy window on close
            Atom wmDelete = XInternAtom(fDisplay, "WM_DELETE_WINDOW", True);
            XSetWMProtocols(fDisplay, fWindow, &wmDelete, 1);

            // set pid WM hint
            const pid_t pid = getpid();
            const Atom _nwp = XInternAtom(fDisplay, "_NET_WM_PID", False);
            XChangeProperty(fDisplay, fWindow, _nwp, XA_CARDINAL, 32, PropModeReplace, (const uchar*)&pid, 1);

            // set the window to both dialog and normal to produce a decorated floating dialog
            // order is important: DIALOG needs to come before NORMAL
            const Atom _wt = XInternAtom(fDisplay, "_NET_WM_WINDOW_TYPE", False);
            const Atom _wts[2] = {
                XInternAtom(fDisplay, "_NET_WM_WINDOW_TYPE_DIALOG", False),
                XInternAtom(fDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False)
            };
            XChangeProperty(fDisplay, fWindow, _wt, XA_ATOM, 32, PropModeReplace, (const uchar*)&_wts, 2);
        }
#endif
    }

    ~EmbedExternalExampleUI()
    {
#if defined(DISTRHO_OS_MAC)
        if (fView == nullptr)
            return;

        if (fWindow != nil)
            [fWindow close];

        [fView release];

        if (fWindow != nil)
            [fWindow release];
#elif defined(DISTRHO_OS_WINDOWS)
#else
        if (fDisplay == nullptr)
            return;

        if (fWindow != 0)
            XDestroyWindow(fDisplay, fWindow);

        XCloseDisplay(fDisplay);
#endif
    }

protected:
   /* --------------------------------------------------------------------------------------------------------
    * DSP/Plugin Callbacks */

   /**
      A parameter has changed on the plugin side.
      This is called by the host to inform the UI about parameter changes.
    */
    void parameterChanged(uint32_t index, float value) override
    {
        if (index != 0)
            return;

        fValue = value;
    }

   /* --------------------------------------------------------------------------------------------------------
    * External Window overrides */

    void focus() override
    {
        d_stdout("focus");
#if defined(DISTRHO_OS_MAC)
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != nil,);
        [fWindow orderFrontRegardless];
#elif defined(DISTRHO_OS_WINDOWS)
#else
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);
        XRaiseWindow(fDisplay, fWindow);
#endif
    }

    uintptr_t getNativeWindowHandle() const noexcept override
    {
#if defined(DISTRHO_OS_MAC)
        return (uintptr_t)fView;
#elif defined(DISTRHO_OS_WINDOWS)
#else
        return (uintptr_t)fWindow;
#endif
        return 0;
    }

    void titleChanged(const char* const title) override
    {
        d_stdout("titleChanged %s", title);
#if defined(DISTRHO_OS_MAC)
        if (fWindow != nil)
        {
            if (NSString* const nsTitle = [[NSString alloc]
                                           initWithBytes:title
                                                  length:strlen(title)
                                                encoding:NSUTF8StringEncoding])
            {
                [fWindow setTitle:nsTitle];
                [nsTitle release];
            }
        }
#elif defined(DISTRHO_OS_WINDOWS)
#else
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);
        XStoreName(fDisplay, fWindow, title);
#endif
    }

    void transientParentWindowChanged(const uintptr_t winId) override
    {
        d_stdout("transientParentWindowChanged %lu", winId);
#if defined(DISTRHO_OS_MAC)
#elif defined(DISTRHO_OS_WINDOWS)
#else
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);
        XSetTransientForHint(fDisplay, fWindow, (::Window)winId);
#endif
    }

    void visibilityChanged(const bool visible) override
    {
        d_stdout("visibilityChanged %d", visible);
#if defined(DISTRHO_OS_MAC)
        DISTRHO_SAFE_ASSERT_RETURN(fView != nullptr,);
        if (fWindow != nil)
            [fWindow setIsVisible:(visible ? YES : NO)];
        else
            [fView setHidden:(visible ? NO : YES)];
#elif defined(DISTRHO_OS_WINDOWS)
#else
        DISTRHO_SAFE_ASSERT_RETURN(fWindow != 0,);
        if (visible)
            XMapRaised(fDisplay, fWindow);
        else
            XUnmapWindow(fDisplay, fWindow);
#endif
    }

    void uiIdle() override
    {
        // d_stdout("uiIdle");
#if defined(DISTRHO_OS_MAC)
        NSAutoreleasePool* const pool = [[NSAutoreleasePool alloc] init];
        NSDate* const date = [NSDate distantPast];

        for (NSEvent* event;;)
        {
            event = [NSApp
                     nextEventMatchingMask:NSAnyEventMask
                                 untilDate:date
                                    inMode:NSDefaultRunLoopMode
                                   dequeue:YES];

            if (event == nil)
                break;
            d_stdout("uiIdle with event %p", event);

            [NSApp sendEvent:event];
        }

        [pool release];
#elif defined(DISTRHO_OS_WINDOWS)
        MSG msg;
        if (! ::PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE))
            return true;

        if (::GetMessage(&msg, nullptr, 0, 0) >= 0)
        {
            if (msg.message == WM_QUIT)
                return false;

            //TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
#else
        if (fDisplay == nullptr)
            return;

        for (XEvent event; XPending(fDisplay) > 0;)
        {
            XNextEvent(fDisplay, &event);

            if (! isVisible())
                continue;

            switch (event.type)
            {
            case ClientMessage:
                if (char* const type = XGetAtomName(fDisplay, event.xclient.message_type))
                {
                    if (std::strcmp(type, "WM_PROTOCOLS") == 0)
                        hide();
                }
                break;

            case KeyRelease:
                if (event.xkey.keycode == X11Key_Escape)
                    hide();
                break;
            }
        }
#endif
    }

    // -------------------------------------------------------------------------------------------------------

private:
    // Current value, cached for when UI becomes visible
    float fValue;

   /**
      Set our UI class as non-copyable and add a leak detector just in case.
    */
    DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EmbedExternalExampleUI)
};

/* ------------------------------------------------------------------------------------------------------------
 * UI entry point, called by DPF to create a new UI instance. */

UI* createUI()
{
    return new EmbedExternalExampleUI();
}

// -----------------------------------------------------------------------------------------------------------

END_NAMESPACE_DISTRHO
<|endoftext|>


<commit_before>// Class for kernels, llvm::Functions that represent OpenCL C kernels.
//
// Copyright (c) 2011 Universidad Rey Juan Carlos and
//               2012 Pekka Jääskeläinen / TUT
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "Kernel.h"
#include "Barrier.h"
#include <iostream>

#include "config.h"
#ifdef LLVM_3_1
#include "llvm/Support/IRBuilder.h"
#elif defined LLVM_3_2
#include "llvm/IRBuilder.h"
#include "llvm/InlineAsm.h"
#else
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#endif

//#define DEBUG_PR_CREATION

using namespace llvm;
using namespace pocl;

static void add_predecessors(SmallVectorImpl<BasicBlock *> &v,
                             BasicBlock *b);
static bool verify_no_barriers(const BasicBlock *B);

void
Kernel::getExitBlocks(SmallVectorImpl<BarrierBlock *> &B)
{
  for (iterator i = begin(), e = end(); i != e; ++i) {
    const TerminatorInst *t = i->getTerminator();
    if (t->getNumSuccessors() == 0) {
      // All exits must be barrier blocks.
      B.push_back(cast<BarrierBlock>(i));
    }
  }
}

ParallelRegion *
Kernel::createParallelRegionBefore(BarrierBlock *B)
{
  SmallVector<BasicBlock *, 4> pending_blocks;
  SmallPtrSet<BasicBlock *, 8> blocks_in_region;
  BarrierBlock *region_entry_barrier = NULL;
  llvm::BasicBlock *entry = NULL;
  llvm::BasicBlock *exit = B->getSinglePredecessor();
  add_predecessors(pending_blocks, B);

#ifdef DEBUG_PR_CREATION
  std::cerr << "createParallelRegionBefore " << B->getName().str() << std::endl;
#endif

  while (!pending_blocks.empty()) {
    BasicBlock *current = pending_blocks.back();
    pending_blocks.pop_back();

#ifdef DEBUG_PR_CREATION
    std::cerr << "considering " << current->getName().str() << std::endl;
#endif

    // avoid infinite recursion of loops
    if (blocks_in_region.count(current) != 0)
      {
#ifdef DEBUG_PR_CREATION
        std::cerr << "already in the region!" << std::endl;
#endif
        continue;
      }

    // If we reach another barrier this must be the
    // parallel region entry.
    if (isa<BarrierBlock>(current)) {
      if (region_entry_barrier == NULL)
        region_entry_barrier = cast<BarrierBlock>(current);
#ifdef DEBUG_PR_CREATION
      std::cerr << "### it's a barrier!" << std::endl;
#endif
      continue;
    }

    if (!verify_no_barriers(current))
      {
        assert(verify_no_barriers(current) &&
               "Barrier found in a non-barrier block! (forgot barrier canonicalization?)");
      }

#ifdef DEBUG_PR_CREATION
    std::cerr << "added it to the region" << std::endl;
#endif
    // Non-barrier block, this must be on the region.
    blocks_in_region.insert(current);

    // Add predecessors to pending queue.
    add_predecessors(pending_blocks, current);
  }

  if (blocks_in_region.empty())
    return NULL;

  // Find the entry node.
  assert (region_entry_barrier != NULL);
  for (unsigned suc = 0, num = region_entry_barrier->getTerminator()->getNumSuccessors();
       suc < num; ++suc)
    {
      llvm::BasicBlock *entryCandidate =
        region_entry_barrier->getTerminator()->getSuccessor(suc);
      if (blocks_in_region.count(entryCandidate) == 0)
        continue;
      entry = entryCandidate;
      break;
    }
  assert (blocks_in_region.count(entry) != 0);

  // We got all the blocks in a region, create it.
  return ParallelRegion::Create(blocks_in_region, entry, exit);
}

static void
add_predecessors(SmallVectorImpl<BasicBlock *> &v, BasicBlock *b)
{
  for (pred_iterator i = pred_begin(b), e = pred_end(b);
       i != e; ++i) {
    if ((isa<BarrierBlock> (*i)) && isa<BarrierBlock> (b)) {
      // Ignore barrier-to-barrier edges * Why? --Pekka
      add_predecessors(v, *i);
      continue;
    }
    v.push_back(*i);
  }
}

static bool
verify_no_barriers(const BasicBlock *B)
{
  for (BasicBlock::const_iterator i = B->begin(), e = B->end(); i != e; ++i) {
    if (isa<Barrier>(i))
      return false;
  }

  return true;
}

ParallelRegion::ParallelRegionVector *
Kernel::getParallelRegions(llvm::LoopInfo *LI) {
  ParallelRegion::ParallelRegionVector *parallel_regions =
    new ParallelRegion::ParallelRegionVector;

  SmallVector<BarrierBlock *, 4> exit_blocks;
  getExitBlocks(exit_blocks);

  // We need to keep track of traversed barriers to detect back edges.
  SmallPtrSet<BarrierBlock *, 8> found_barriers;

  // First find all the ParallelRegions in the Function.
  while (!exit_blocks.empty()) {

    // We start on an exit block and process the parallel regions upwards
    // (finding an execution trace).
    BarrierBlock *exit = exit_blocks.back();
    exit_blocks.pop_back();

    while (ParallelRegion *PR = createParallelRegionBefore(exit)) {
      assert(PR != NULL && !PR->empty() &&
             "Empty parallel region in kernel (contiguous barriers)!");

      found_barriers.insert(exit);
      exit = NULL;
      parallel_regions->push_back(PR);
      BasicBlock *entry = PR->entryBB();
      int found_predecessors = 0;
      BarrierBlock *loop_barrier = NULL;
      for (pred_iterator i = pred_begin(entry), e = pred_end(entry);
           i != e; ++i) {
        BarrierBlock *barrier = cast<BarrierBlock> (*i);
        if (!found_barriers.count(barrier)) {
          /* If this is a loop header block we might have edges from two
             unprocessed barriers. The one inside the loop (coming from a
             computation block after a branch block) should be processed
             first. */
          std::string bbName = "";
          const bool IS_IN_THE_SAME_LOOP =
              LI->getLoopFor(barrier) != NULL &&
              LI->getLoopFor(entry) != NULL &&
              LI->getLoopFor(entry) == LI->getLoopFor(barrier);

          if (IS_IN_THE_SAME_LOOP)
            {
#ifdef DEBUG_PR_CREATION
              std::cout << "### found a barrier inside the loop:" << std::endl;
              std::cout << barrier->getName().str() << std::endl;
#endif
              if (loop_barrier != NULL) {
                // there can be multiple latches and each have their barrier,
                // save the previously found inner loop barrier
                exit_blocks.push_back(loop_barrier);
              }
              loop_barrier = barrier;
            }
          else
            {
#ifdef DEBUG_PR_CREATION
              std::cout << "### found a barrier:" << std::endl;
              std::cout << barrier->getName().str() << std::endl;
#endif
              exit = barrier;
            }
          ++found_predecessors;
        }
      }

      if (loop_barrier != NULL)
        {
          /* The secondary barrier to process in case it was a loop
             header. Push it for later processing. */
          if (exit != NULL)
            exit_blocks.push_back(exit);
          /* always process the inner loop regions first */
          if (!found_barriers.count(loop_barrier))
            exit = loop_barrier;
        }

#ifdef DEBUG_PR_CREATION
      std::cout << "### created a ParallelRegion:" << std::endl;
      PR->dumpNames();
      std::cout << std::endl;
#endif

      if (found_predecessors == 0)
        {
          /* This path has been traversed and we encountered no more
             unprocessed regions. It means we have either traversed all
             paths from the exit or have transformed a loop and thus
             encountered only a barrier that was seen (and thus
             processed) before. */
          break;
        }
      assert ((exit != NULL) && "Parallel region without entry barrier!");
    }
  }
  return parallel_regions;

}

void
Kernel::addLocalSizeInitCode(size_t LocalSizeX, size_t LocalSizeY, size_t LocalSizeZ) {

  IRBuilder<> builder(getEntryBlock().getFirstNonPHI());

  GlobalVariable *gv;

  llvm::Module* M = getParent();

  int size_t_width = 32;
  if (M->getPointerSize() == llvm::Module::Pointer64)
    size_t_width = 64;

  gv = M->getGlobalVariable("_local_size_x");
  if (gv != NULL)
    builder.CreateStore
      (ConstantInt::get
       (IntegerType::get(M->getContext(), size_t_width),
        LocalSizeX), gv);
  gv = M->getGlobalVariable("_local_size_y");

  if (gv != NULL)
    builder.CreateStore
      (ConstantInt::get
       (IntegerType::get(M->getContext(), size_t_width),
        LocalSizeY), gv);
  gv = M->getGlobalVariable("_local_size_z");

  if (gv != NULL)
    builder.CreateStore
      (ConstantInt::get
       (IntegerType::get(M->getContext(), size_t_width),
        LocalSizeZ), gv);

}

<commit_msg>Add documentation.<commit_after>// Class for kernels, llvm::Functions that represent OpenCL C kernels.
//
// Copyright (c) 2011 Universidad Rey Juan Carlos and
//               2012 Pekka Jääskeläinen / TUT
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "Kernel.h"
#include "Barrier.h"
#include <iostream>

#include "config.h"
#ifdef LLVM_3_1
#include "llvm/Support/IRBuilder.h"
#elif defined LLVM_3_2
#include "llvm/IRBuilder.h"
#include "llvm/InlineAsm.h"
#else
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#endif

//#define DEBUG_PR_CREATION

using namespace llvm;
using namespace pocl;

static void add_predecessors(SmallVectorImpl<BasicBlock *> &v,
                             BasicBlock *b);
static bool verify_no_barriers(const BasicBlock *B);

void
Kernel::getExitBlocks(SmallVectorImpl<BarrierBlock *> &B)
{
  for (iterator i = begin(), e = end(); i != e; ++i) {
    const TerminatorInst *t = i->getTerminator();
    if (t->getNumSuccessors() == 0) {
      // All exits must be barrier blocks.
      B.push_back(cast<BarrierBlock>(i));
    }
  }
}

ParallelRegion *
Kernel::createParallelRegionBefore(BarrierBlock *B)
{
  SmallVector<BasicBlock *, 4> pending_blocks;
  SmallPtrSet<BasicBlock *, 8> blocks_in_region;
  BarrierBlock *region_entry_barrier = NULL;
  llvm::BasicBlock *entry = NULL;
  llvm::BasicBlock *exit = B->getSinglePredecessor();
  add_predecessors(pending_blocks, B);

#ifdef DEBUG_PR_CREATION
  std::cerr << "createParallelRegionBefore " << B->getName().str() << std::endl;
#endif

  while (!pending_blocks.empty()) {
    BasicBlock *current = pending_blocks.back();
    pending_blocks.pop_back();

#ifdef DEBUG_PR_CREATION
    std::cerr << "considering " << current->getName().str() << std::endl;
#endif

    // avoid infinite recursion of loops
    if (blocks_in_region.count(current) != 0)
      {
#ifdef DEBUG_PR_CREATION
        std::cerr << "already in the region!" << std::endl;
#endif
        continue;
      }

    // If we reach another barrier this must be the
    // parallel region entry.
    if (isa<BarrierBlock>(current)) {
      if (region_entry_barrier == NULL)
        region_entry_barrier = cast<BarrierBlock>(current);
#ifdef DEBUG_PR_CREATION
      std::cerr << "### it's a barrier!" << std::endl;
#endif
      continue;
    }

    if (!verify_no_barriers(current))
      {
        assert(verify_no_barriers(current) &&
               "Barrier found in a non-barrier block! (forgot barrier canonicalization?)");
      }

#ifdef DEBUG_PR_CREATION
    std::cerr << "added it to the region" << std::endl;
#endif
    // Non-barrier block, this must be on the region.
    blocks_in_region.insert(current);

    // Add predecessors to pending queue.
    add_predecessors(pending_blocks, current);
  }

  if (blocks_in_region.empty())
    return NULL;

  // Find the entry node.
  assert (region_entry_barrier != NULL);
  for (unsigned suc = 0, num = region_entry_barrier->getTerminator()->getNumSuccessors();
       suc < num; ++suc)
    {
      llvm::BasicBlock *entryCandidate =
        region_entry_barrier->getTerminator()->getSuccessor(suc);
      if (blocks_in_region.count(entryCandidate) == 0)
        continue;
      entry = entryCandidate;
      break;
    }
  assert (blocks_in_region.count(entry) != 0);

  // We got all the blocks in a region, create it.
  return ParallelRegion::Create(blocks_in_region, entry, exit);
}

static void
add_predecessors(SmallVectorImpl<BasicBlock *> &v, BasicBlock *b)
{
  for (pred_iterator i = pred_begin(b), e = pred_end(b);
       i != e; ++i) {
    if ((isa<BarrierBlock> (*i)) && isa<BarrierBlock> (b)) {
      // Ignore barrier-to-barrier edges * Why? --Pekka
      add_predecessors(v, *i);
      continue;
    }
    v.push_back(*i);
  }
}

static bool
verify_no_barriers(const BasicBlock *B)
{
  for (BasicBlock::const_iterator i = B->begin(), e = B->end(); i != e; ++i) {
    if (isa<Barrier>(i))
      return false;
  }

  return true;
}

/**
 * The main entry to the "parallel region formation", phase which search
 * for the regions between barriers that can be freely parallelized
 * across work-items in the work-group.
 */
ParallelRegion::ParallelRegionVector *
Kernel::getParallelRegions(llvm::LoopInfo *LI) {
  ParallelRegion::ParallelRegionVector *parallel_regions =
    new ParallelRegion::ParallelRegionVector;

  SmallVector<BarrierBlock *, 4> exit_blocks;
  getExitBlocks(exit_blocks);

  // We need to keep track of traversed barriers to detect back edges.
  SmallPtrSet<BarrierBlock *, 8> found_barriers;

  // First find all the ParallelRegions in the Function.
  while (!exit_blocks.empty()) {

    // We start on an exit block and process the parallel regions upwards
    // (finding an execution trace).
    BarrierBlock *exit = exit_blocks.back();
    exit_blocks.pop_back();

    while (ParallelRegion *PR = createParallelRegionBefore(exit)) {
      assert(PR != NULL && !PR->empty() &&
             "Empty parallel region in kernel (contiguous barriers)!");

      found_barriers.insert(exit);
      exit = NULL;
      parallel_regions->push_back(PR);
      BasicBlock *entry = PR->entryBB();
      int found_predecessors = 0;
      BarrierBlock *loop_barrier = NULL;
      for (pred_iterator i = pred_begin(entry), e = pred_end(entry);
           i != e; ++i) {
        BarrierBlock *barrier = cast<BarrierBlock> (*i);
        if (!found_barriers.count(barrier)) {
          /* If this is a loop header block we might have edges from two
             unprocessed barriers. The one inside the loop (coming from a
             computation block after a branch block) should be processed
             first. */
          std::string bbName = "";
          const bool IS_IN_THE_SAME_LOOP =
              LI->getLoopFor(barrier) != NULL &&
              LI->getLoopFor(entry) != NULL &&
              LI->getLoopFor(entry) == LI->getLoopFor(barrier);

          if (IS_IN_THE_SAME_LOOP)
            {
#ifdef DEBUG_PR_CREATION
              std::cout << "### found a barrier inside the loop:" << std::endl;
              std::cout << barrier->getName().str() << std::endl;
#endif
              if (loop_barrier != NULL) {
                // there can be multiple latches and each have their barrier,
                // save the previously found inner loop barrier
                exit_blocks.push_back(loop_barrier);
              }
              loop_barrier = barrier;
            }
          else
            {
#ifdef DEBUG_PR_CREATION
              std::cout << "### found a barrier:" << std::endl;
              std::cout << barrier->getName().str() << std::endl;
#endif
              exit = barrier;
            }
          ++found_predecessors;
        }
      }

      if (loop_barrier != NULL)
        {
          /* The secondary barrier to process in case it was a loop
             header. Push it for later processing. */
          if (exit != NULL)
            exit_blocks.push_back(exit);
          /* always process the inner loop regions first */
          if (!found_barriers.count(loop_barrier))
            exit = loop_barrier;
        }

#ifdef DEBUG_PR_CREATION
      std::cout << "### created a ParallelRegion:" << std::endl;
      PR->dumpNames();
      std::cout << std::endl;
#endif

      if (found_predecessors == 0)
        {
          /* This path has been traversed and we encountered no more
             unprocessed regions. It means we have either traversed all
             paths from the exit or have transformed a loop and thus
             encountered only a barrier that was seen (and thus
             processed) before. */
          break;
        }
      assert ((exit != NULL) && "Parallel region without entry barrier!");
    }
  }
  return parallel_regions;

}

void
Kernel::addLocalSizeInitCode(size_t LocalSizeX, size_t LocalSizeY, size_t LocalSizeZ) {

  IRBuilder<> builder(getEntryBlock().getFirstNonPHI());

  GlobalVariable *gv;

  llvm::Module* M = getParent();

  int size_t_width = 32;
  if (M->getPointerSize() == llvm::Module::Pointer64)
    size_t_width = 64;

  gv = M->getGlobalVariable("_local_size_x");
  if (gv != NULL)
    builder.CreateStore
      (ConstantInt::get
       (IntegerType::get(M->getContext(), size_t_width),
        LocalSizeX), gv);
  gv = M->getGlobalVariable("_local_size_y");

  if (gv != NULL)
    builder.CreateStore
      (ConstantInt::get
       (IntegerType::get(M->getContext(), size_t_width),
        LocalSizeY), gv);
  gv = M->getGlobalVariable("_local_size_z");

  if (gv != NULL)
    builder.CreateStore
      (ConstantInt::get
       (IntegerType::get(M->getContext(), size_t_width),
        LocalSizeZ), gv);

}

<|endoftext|>


<commit_before>/*
 * statereader.cpp
 *
 *  Created on: 05.08.2014
 *      Author: Ralph
 */

#include "statereader.h"

#include "loader.h"

#include "../data/globalpropertymodel.h"
#include "../data/models.h"
#include "../data/roiarea.h"
#include "../data/roibox.h"
#include "../data/vptr.h"

#include "../data/datasets/datasetguides.h"
#include "../data/datasets/datasetlabel.h"
#include "../data/datasets/datasetplane.h"
#include "../data/datasets/datasetscalar.h"

#include "../gui/gl/colormapfunctions.h"
#include "../gui/gl/glfunctions.h"

#include <QDebug>
#include <QFile>

StateReader::StateReader()
{
}

StateReader::~StateReader()
{
}

void StateReader::load( QString fileName )
{
    m_fileInfo = QFileInfo( fileName );
    QFile file(fileName);
    if ( !file.open( QFile::ReadOnly | QFile::Text ) )
    {
        qCritical() << "StateReader: Cannot read file " << fileName << " : " << file.errorString();
        return;
    }
    xml.read( &file );

    if ( xml.getHeaderValue( "appName" ) != "brainGL" )
    {
        qCritical() << "Not a brainGL xml file";
        return;
    }

    if ( xml.getHeaderValue( "content" ).toString() == "scene" )
    {
        loadScene();
    }

    if ( xml.getHeaderValue( "content" ).toString() == "colormaps" )
    {
        loadColormaps();
    }

    file.close();
}

void StateReader::loadScene()
{
    bool packAndGo = xml.getHeaderValue( "packAndGo" ).toBool();

    QList<QVariant>globals = xml.getGlobals();
    dynamic_cast<GlobalPropertyModel*>( Models::g() )->setState( globals );
    m_cameras = xml.getCameras();

    QList< QList<QVariant> >datasets = xml.getDatasets();
    for ( int i = 0; i < datasets.size(); ++i )
    {
        QList<QVariant> state = datasets[i];
        int type = getFromStateList( Fn::Property::D_TYPE, state ).toInt();
        if ( type == (int)Fn::DatasetType::GUIDE  )
        {
            DatasetGuides* g = new DatasetGuides();
            g->properties().setState( state );
            Models::addDataset( g );
        }
        else if ( type == (int)Fn::DatasetType::PLANE  )
        {
            DatasetPlane* plane = new DatasetPlane();
            plane->properties().setState( state );
            Models::addDataset( plane );
        }
        else if ( type == (int)Fn::DatasetType::LABEL  )
        {
            DatasetLabel* label = new DatasetLabel();
            label->properties().setState( state );
            Models::addDataset( label );
        }
        else
        {
            QString fn = getFromStateList( Fn::Property::D_FILENAME, state ).toString();
            if ( packAndGo )
            {
                QFileInfo fi( fn );
                QString fn = fi.fileName();
                loadDataset( m_fileInfo.path() + QDir::separator() + fn, state );
            }
            else
            {
                loadDataset( fn, state );
            }
        }
    }

    int numBranches = Models::r()->rowCount( QModelIndex() );
    QList< QList< QList<QVariant> > > rois = xml.getRois();
    for ( int i = 0; i < rois.size(); ++i )
    {
        QList< QList<QVariant> >branch = rois[i];

        QList<QVariant>roiState = branch[0];

        int shape = getFromStateList( Fn::Property::D_SHAPE, roiState ).toInt();

        if ( shape == 10 )
        {
            if ( packAndGo )
            {
                QFileInfo fi( getFromStateList( Fn::Property::D_FILENAME, roiState ).toString() );
                QString fn = fi.fileName();
                GLFunctions::roi = loadRoi( m_fileInfo.path() + QDir::separator() + fn );
            }
            else
            {
                QString fn = getFromStateList( Fn::Property::D_FILENAME, roiState ).toString();
                GLFunctions::roi = loadRoi( fn );
                GLFunctions::roi->properties()->setState( roiState );
            }
        }
        else
        {
            GLFunctions::roi = new ROIBox();
            GLFunctions::roi->properties()->setState( roiState );
        }

        for ( int l = 0; l < roiState.size() / 2; ++l )
        {
            if ( (Fn::Property)( roiState[l*2].toInt() ) == Fn::Property::D_COLOR )
            {
                GLFunctions::roi->properties()->set( (Fn::Property)( roiState[l*2].toInt() ), roiState[l*2+1] );
            }
        }

        Models::r()->insertRows( 0, 0, QModelIndex() );

        if ( branch.size() > 1 )
        {
            for ( int k = 1; k < branch.size(); ++k )
            {
                QList<QVariant>roiState = branch[k];

                int shape = getFromStateList( Fn::Property::D_SHAPE, roiState ).toInt();
                if ( shape == 10 )
                {
                    if ( packAndGo )
                    {
                        QFileInfo fi( getFromStateList( Fn::Property::D_FILENAME, roiState ).toString() );
                        QString fn = fi.fileName();
                        GLFunctions::roi = loadRoi( fi.path() + QDir::separator() + fn );
                    }
                    else
                    {
                        QString fn = getFromStateList( Fn::Property::D_FILENAME, roiState ).toString();
                        GLFunctions::roi = loadRoi( fn );
                        GLFunctions::roi->properties()->setState( roiState );
                    }
                    Models::r()->insertRows( 0, 0, Models::createRoiIndex( numBranches + i, 0, 0 ) );
                }
                else
                {
                    GLFunctions::roi = new ROIBox();
                    GLFunctions::roi->properties()->setState( roiState );
                    Models::r()->insertRows( 0, 0, Models::createRoiIndex( numBranches + i, 0, 0 ) );
                }
                for ( int l = 0; l < roiState.size() / 2; ++l )
                {
                    if ( (Fn::Property)( roiState[l*2].toInt() ) == Fn::Property::D_COLOR )
                    {
                        GLFunctions::roi->properties()->set( (Fn::Property)( roiState[l*2].toInt() ), roiState[l*2+1] );
                    }
                }
            }
        }
    }
}

QVariant StateReader::getFromStateList( Fn::Property prop, QList<QVariant>& state )
{
    for ( int i = 0; i < state.size() / 2; ++i )
    {
        if ( (Fn::Property)( state[i*2].toInt() ) == prop )
        {
            return state[i*2+1];
        }
    }
    return QVariant();
}

void StateReader::loadDataset( QString fileName, QList<QVariant> state )
{
    Loader loader;
    loader.setFilename( QDir( fileName ) );
    if ( loader.load() )
    {
        for ( int k = 0; k < loader.getNumDatasets(); ++k )
        {
            loader.getDataset( k )->properties().setState( state );
            Models::d()->setData( Models::d()->index( Models::d()->rowCount(), (int)Fn::Property::D_NEW_DATASET ), VPtr<Dataset>::asQVariant( loader.getDataset( k ) ), Qt::DisplayRole );
        }
        QFileInfo fi( fileName );
        QDir dir = fi.absoluteDir();
        QString lastPath = dir.absolutePath();
        Models::g()->setData( Models::g()->index( (int)Fn::Property::G_LAST_PATH, 0 ), lastPath );
    }
}

ROIArea* StateReader::loadRoi( QString fileName )
{
    Loader loader;
    loader.setFilename( QDir( fileName ) );
    if ( loader.load() )
    {
        DatasetScalar* dss = static_cast<DatasetScalar*>( loader.getDataset( 0 ) );
        std::vector<float>* data = dss->getData();
        std::vector<float> out( data->size(), 0.0 );

        for ( unsigned int i = 0; i < data->size(); ++i )
        {
            out[i] = data->at( i );
        }

        ROIArea* roiOut = new ROIArea( out, dss->properties() );

        QFileInfo fi( fileName );
        QDir dir = fi.absoluteDir();
        QString lastPath = dir.absolutePath();
        Models::g()->setData( Models::g()->index( (int)Fn::Property::G_LAST_PATH, 0 ), lastPath );

        return roiOut;
    }
    return NULL;
}

void StateReader::loadColormaps()
{
    QList< QList<QVariant> >cms = xml.getColormaps();

    for ( int i = 0; i < cms.size(); ++i )
    {
        ColormapBase cm( cms[i] );
        ColormapFunctions::addColormap( cm );
    }
}
<commit_msg>when loading a scene set the globals last<commit_after>/*
 * statereader.cpp
 *
 *  Created on: 05.08.2014
 *      Author: Ralph
 */

#include "statereader.h"

#include "loader.h"

#include "../data/globalpropertymodel.h"
#include "../data/models.h"
#include "../data/roiarea.h"
#include "../data/roibox.h"
#include "../data/vptr.h"

#include "../data/datasets/datasetguides.h"
#include "../data/datasets/datasetlabel.h"
#include "../data/datasets/datasetplane.h"
#include "../data/datasets/datasetscalar.h"

#include "../gui/gl/colormapfunctions.h"
#include "../gui/gl/glfunctions.h"

#include <QDebug>
#include <QFile>

StateReader::StateReader()
{
}

StateReader::~StateReader()
{
}

void StateReader::load( QString fileName )
{
    m_fileInfo = QFileInfo( fileName );
    QFile file(fileName);
    if ( !file.open( QFile::ReadOnly | QFile::Text ) )
    {
        qCritical() << "StateReader: Cannot read file " << fileName << " : " << file.errorString();
        return;
    }
    xml.read( &file );

    if ( xml.getHeaderValue( "appName" ) != "brainGL" )
    {
        qCritical() << "Not a brainGL xml file";
        return;
    }

    if ( xml.getHeaderValue( "content" ).toString() == "scene" )
    {
        loadScene();
    }

    if ( xml.getHeaderValue( "content" ).toString() == "colormaps" )
    {
        loadColormaps();
    }

    file.close();
}

void StateReader::loadScene()
{
    bool packAndGo = xml.getHeaderValue( "packAndGo" ).toBool();

    QList<QVariant>globals = xml.getGlobals();
    m_cameras = xml.getCameras();

    QList< QList<QVariant> >datasets = xml.getDatasets();
    for ( int i = 0; i < datasets.size(); ++i )
    {
        QList<QVariant> state = datasets[i];
        int type = getFromStateList( Fn::Property::D_TYPE, state ).toInt();
        if ( type == (int)Fn::DatasetType::GUIDE  )
        {
            DatasetGuides* g = new DatasetGuides();
            g->properties().setState( state );
            Models::addDataset( g );
        }
        else if ( type == (int)Fn::DatasetType::PLANE  )
        {
            DatasetPlane* plane = new DatasetPlane();
            plane->properties().setState( state );
            Models::addDataset( plane );
        }
        else if ( type == (int)Fn::DatasetType::LABEL  )
        {
            DatasetLabel* label = new DatasetLabel();
            label->properties().setState( state );
            Models::addDataset( label );
        }
        else
        {
            QString fn = getFromStateList( Fn::Property::D_FILENAME, state ).toString();
            if ( packAndGo )
            {
                QFileInfo fi( fn );
                QString fn = fi.fileName();
                loadDataset( m_fileInfo.path() + QDir::separator() + fn, state );
            }
            else
            {
                loadDataset( fn, state );
            }
        }
    }

    int numBranches = Models::r()->rowCount( QModelIndex() );
    QList< QList< QList<QVariant> > > rois = xml.getRois();
    for ( int i = 0; i < rois.size(); ++i )
    {
        QList< QList<QVariant> >branch = rois[i];

        QList<QVariant>roiState = branch[0];

        int shape = getFromStateList( Fn::Property::D_SHAPE, roiState ).toInt();

        if ( shape == 10 )
        {
            if ( packAndGo )
            {
                QFileInfo fi( getFromStateList( Fn::Property::D_FILENAME, roiState ).toString() );
                QString fn = fi.fileName();
                GLFunctions::roi = loadRoi( m_fileInfo.path() + QDir::separator() + fn );
            }
            else
            {
                QString fn = getFromStateList( Fn::Property::D_FILENAME, roiState ).toString();
                GLFunctions::roi = loadRoi( fn );
                GLFunctions::roi->properties()->setState( roiState );
            }
        }
        else
        {
            GLFunctions::roi = new ROIBox();
            GLFunctions::roi->properties()->setState( roiState );
        }

        for ( int l = 0; l < roiState.size() / 2; ++l )
        {
            if ( (Fn::Property)( roiState[l*2].toInt() ) == Fn::Property::D_COLOR )
            {
                GLFunctions::roi->properties()->set( (Fn::Property)( roiState[l*2].toInt() ), roiState[l*2+1] );
            }
        }

        Models::r()->insertRows( 0, 0, QModelIndex() );

        if ( branch.size() > 1 )
        {
            for ( int k = 1; k < branch.size(); ++k )
            {
                QList<QVariant>roiState = branch[k];

                int shape = getFromStateList( Fn::Property::D_SHAPE, roiState ).toInt();
                if ( shape == 10 )
                {
                    if ( packAndGo )
                    {
                        QFileInfo fi( getFromStateList( Fn::Property::D_FILENAME, roiState ).toString() );
                        QString fn = fi.fileName();
                        GLFunctions::roi = loadRoi( fi.path() + QDir::separator() + fn );
                    }
                    else
                    {
                        QString fn = getFromStateList( Fn::Property::D_FILENAME, roiState ).toString();
                        GLFunctions::roi = loadRoi( fn );
                        GLFunctions::roi->properties()->setState( roiState );
                    }
                    Models::r()->insertRows( 0, 0, Models::createRoiIndex( numBranches + i, 0, 0 ) );
                }
                else
                {
                    GLFunctions::roi = new ROIBox();
                    GLFunctions::roi->properties()->setState( roiState );
                    Models::r()->insertRows( 0, 0, Models::createRoiIndex( numBranches + i, 0, 0 ) );
                }
                for ( int l = 0; l < roiState.size() / 2; ++l )
                {
                    if ( (Fn::Property)( roiState[l*2].toInt() ) == Fn::Property::D_COLOR )
                    {
                        GLFunctions::roi->properties()->set( (Fn::Property)( roiState[l*2].toInt() ), roiState[l*2+1] );
                    }
                }
            }
        }
    }
    dynamic_cast<GlobalPropertyModel*>( Models::g() )->setState( globals );
}

QVariant StateReader::getFromStateList( Fn::Property prop, QList<QVariant>& state )
{
    for ( int i = 0; i < state.size() / 2; ++i )
    {
        if ( (Fn::Property)( state[i*2].toInt() ) == prop )
        {
            return state[i*2+1];
        }
    }
    return QVariant();
}

void StateReader::loadDataset( QString fileName, QList<QVariant> state )
{
    Loader loader;
    loader.setFilename( QDir( fileName ) );
    if ( loader.load() )
    {
        for ( int k = 0; k < loader.getNumDatasets(); ++k )
        {
            loader.getDataset( k )->properties().setState( state );
            Models::d()->setData( Models::d()->index( Models::d()->rowCount(), (int)Fn::Property::D_NEW_DATASET ), VPtr<Dataset>::asQVariant( loader.getDataset( k ) ), Qt::DisplayRole );
        }
        QFileInfo fi( fileName );
        QDir dir = fi.absoluteDir();
        QString lastPath = dir.absolutePath();
        Models::g()->setData( Models::g()->index( (int)Fn::Property::G_LAST_PATH, 0 ), lastPath );
    }
}

ROIArea* StateReader::loadRoi( QString fileName )
{
    Loader loader;
    loader.setFilename( QDir( fileName ) );
    if ( loader.load() )
    {
        DatasetScalar* dss = static_cast<DatasetScalar*>( loader.getDataset( 0 ) );
        std::vector<float>* data = dss->getData();
        std::vector<float> out( data->size(), 0.0 );

        for ( unsigned int i = 0; i < data->size(); ++i )
        {
            out[i] = data->at( i );
        }

        ROIArea* roiOut = new ROIArea( out, dss->properties() );

        QFileInfo fi( fileName );
        QDir dir = fi.absoluteDir();
        QString lastPath = dir.absolutePath();
        Models::g()->setData( Models::g()->index( (int)Fn::Property::G_LAST_PATH, 0 ), lastPath );

        return roiOut;
    }
    return NULL;
}

void StateReader::loadColormaps()
{
    QList< QList<QVariant> >cms = xml.getColormaps();

    for ( int i = 0; i < cms.size(); ++i )
    {
        ColormapBase cm( cms[i] );
        ColormapFunctions::addColormap( cm );
    }
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include <iostream>
#include <map>
#include <math.h>

typedef unsigned int ruint;

class Uniform01
{
protected:
	Uniform01(ruint seed): m_seed(seed)
	{}

	double generate01()
	{
		m_seed = m_seed * 69069 + 1;
		return m_seed / 4294967296.0;
	}

private:
	ruint m_seed;
};

class Triang: public Uniform01
{
public:
	Triang(const double& mean, const int& min, const int& max, ruint seed)
		: Uniform01(seed  )
		, m_mean   (mean  )
		, m_min	   (min	  )
		, m_max	   (max   )
	{}

	double generate()
	{
		double result;
		double u01 = generate01();
		double h = 2/(m_max-m_min);
		double a1 = h/(m_mean-m_min);
		double b1 = h;
		double a2 = -h/(m_max-m_mean);
		double b2 = h;
		if ( u01 >= (m_mean-m_min)/(m_max-m_min))
		{
			result = -(m_max-m_mean)*(sqrt(generate01()) - 1);
		}
		else
		{
			result = (m_mean-m_min)*(sqrt(generate01()) - 1);
		}
		return result + m_mean;
	}

private:
	double m_mean;
	double m_min;
	double m_max;
};

void main()
{
	Triang				triang			(4, 0, 5, 2345236);

	double step = 0.1;
	typedef std::map<int, ruint> Histogram;
	Histogram m_histogram;

	for (ruint i = 0; i < 100000; i++)
	{
		double value = triang.generate();
		ruint index = static_cast<ruint>(value / step);
		std::pair<Histogram::iterator, bool> result =
			m_histogram.insert(Histogram::value_type(index, 0));
		if (!result.second)
		{
			++result.first->second;
		}
	}

	Histogram::const_iterator it = m_histogram.begin();
	while (it != m_histogram.end())
	{
		std::cout
			<< it->first
			<< ";"
			<< it->second
			<< std::endl;
		++it;
	}

	int i = 1;
}
<commit_msg> - убрал лишнее<commit_after>#include "stdafx.h"
#include <iostream>
#include <map>
#include <math.h>

typedef unsigned int ruint;

class Uniform01
{
protected:
	Uniform01(ruint seed): m_seed(seed)
	{}

	double generate01()
	{
		m_seed = m_seed * 69069 + 1;
		return m_seed / 4294967296.0;
	}

private:
	ruint m_seed;
};

class Triang: public Uniform01
{
public:
	Triang(const double& mean, const int& min, const int& max, ruint seed)
		: Uniform01(seed  )
		, m_mean   (mean  )
		, m_min	   (min	  )
		, m_max	   (max   )
	{}

	double generate()
	{
		double result;
		double u01 = generate01();
		if ( u01 >= (m_mean-m_min)/(m_max-m_min))
		{
			result = -(m_max-m_mean)*(sqrt(u01) - 1);
		}
		else
		{
			result = (m_mean-m_min)*(sqrt(u01) - 1);
		}
		return result + m_mean;
	}

private:
	double m_mean;
	double m_min;
	double m_max;
};

void main()
{
	Triang				triang			(3, 0, 5, 2345236);

	double step = 0.1;
	typedef std::map<int, ruint> Histogram;
	Histogram m_histogram;

	for (ruint i = 0; i < 100000; i++)
	{
		double value = triang.generate();
		ruint index = static_cast<ruint>(value / step);
		std::pair<Histogram::iterator, bool> result =
			m_histogram.insert(Histogram::value_type(index, 0));
		if (!result.second)
		{
			++result.first->second;
		}
	}

	Histogram::const_iterator it = m_histogram.begin();
	while (it != m_histogram.end())
	{
		std::cout
			<< it->first
			<< ";"
			<< it->second
			<< std::endl;
		++it;
	}

	int i = 1;
}
<|endoftext|>