<commit_before>#include "Test.h"
#include "SkRandom.h"
#include "SkRefCnt.h"
#include "SkTSearch.h"
#include "SkTSort.h"
#include "SkUtils.h"

class RefClass : public SkRefCnt {
public:
    RefClass(int n) : fN(n) {}
    int get() const { return fN; }

private:
    int fN;
};

static void test_refptr(skiatest::Reporter* reporter) {
    RefClass* r0 = new RefClass(0);

    SkRefPtr<RefClass> rc0;
    REPORTER_ASSERT(reporter, rc0.get() == NULL);
    REPORTER_ASSERT(reporter, !rc0);

    SkRefPtr<RefClass> rc1;
    REPORTER_ASSERT(reporter, rc0 == rc1);
    REPORTER_ASSERT(reporter, rc0.get() != r0);

    rc0 = r0;
    REPORTER_ASSERT(reporter, rc0);
    REPORTER_ASSERT(reporter, rc0 != rc1);
    REPORTER_ASSERT(reporter, rc0.get() == r0);

    rc1 = rc0;
    REPORTER_ASSERT(reporter, rc1);
    REPORTER_ASSERT(reporter, rc0 == rc1);
    REPORTER_ASSERT(reporter, rc0.get() == r0);

    rc0 = NULL;
    REPORTER_ASSERT(reporter, rc0.get() == NULL);
    REPORTER_ASSERT(reporter, !rc0);
    REPORTER_ASSERT(reporter, rc0 != rc1);

    r0->unref();
}

static void test_autounref(skiatest::Reporter* reporter) {
    RefClass obj(0);
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());

    SkAutoTUnref<RefClass> tmp(&obj);
    REPORTER_ASSERT(reporter, &obj == tmp.get());
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());

    REPORTER_ASSERT(reporter, &obj == tmp.detach());
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
    REPORTER_ASSERT(reporter, NULL == tmp.detach());
    REPORTER_ASSERT(reporter, NULL == tmp.get());

    obj.ref();
    REPORTER_ASSERT(reporter, 2 == obj.getRefCnt());
    {
        SkAutoTUnref<RefClass> tmp2(&obj);
    }
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
}

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

#define kSEARCH_COUNT   91

static void test_search(skiatest::Reporter* reporter) {
    int         i, array[kSEARCH_COUNT];
    SkRandom    rand;

    for (i = 0; i < kSEARCH_COUNT; i++) {
        array[i] = rand.nextS();
    }

    SkTHeapSort<int>(array, kSEARCH_COUNT);
    // make sure we got sorted properly
    for (i = 1; i < kSEARCH_COUNT; i++) {
        REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
    }

    // make sure we can find all of our values
    for (i = 0; i < kSEARCH_COUNT; i++) {
        int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
        REPORTER_ASSERT(reporter, index == i);
    }

    // make sure that random values are either found, or the correct
    // insertion index is returned
    for (i = 0; i < 10000; i++) {
        int value = rand.nextS();
        int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));

        if (index >= 0) {
            REPORTER_ASSERT(reporter,
                            index < kSEARCH_COUNT && array[index] == value);
        } else {
            index = ~index;
            REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
            if (index < kSEARCH_COUNT) {
                REPORTER_ASSERT(reporter, value < array[index]);
                if (index > 0) {
                    REPORTER_ASSERT(reporter, value > array[index - 1]);
                }
            } else {
                // we should append the new value
                REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
            }
        }
    }
}

static void test_utf16(skiatest::Reporter* reporter) {
    static const SkUnichar gUni[] = {
        0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234
    };

    uint16_t buf[2];

    for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) {
        size_t count = SkUTF16_FromUnichar(gUni[i], buf);
        REPORTER_ASSERT(reporter, count == 2);
        size_t count2 = SkUTF16_CountUnichars(buf, 2);
        REPORTER_ASSERT(reporter, count2 == 1);
        const uint16_t* ptr = buf;
        SkUnichar c = SkUTF16_NextUnichar(&ptr);
        REPORTER_ASSERT(reporter, c == gUni[i]);
        REPORTER_ASSERT(reporter, ptr - buf == 2);
    }
}

static void TestUTF(skiatest::Reporter* reporter) {
    static const struct {
        const char* fUtf8;
        SkUnichar   fUni;
    } gTest[] = {
        { "a",                  'a' },
        { "\x7f",               0x7f },
        { "\xC2\x80",           0x80 },
        { "\xC3\x83",           (3 << 6) | 3    },
        { "\xDF\xBF",           0x7ff },
        { "\xE0\xA0\x80",       0x800 },
        { "\xE0\xB0\xB8",       0xC38 },
        { "\xE3\x83\x83",       (3 << 12) | (3 << 6) | 3    },
        { "\xEF\xBF\xBF",       0xFFFF },
        { "\xF0\x90\x80\x80",   0x10000 },
        { "\xF3\x83\x83\x83",   (3 << 18) | (3 << 12) | (3 << 6) | 3    }
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) {
        const char* p = gTest[i].fUtf8;
        int         n = SkUTF8_CountUnichars(p);
        SkUnichar   u0 = SkUTF8_ToUnichar(gTest[i].fUtf8);
        SkUnichar   u1 = SkUTF8_NextUnichar(&p);

        REPORTER_ASSERT(reporter, n == 1);
        REPORTER_ASSERT(reporter, u0 == u1);
        REPORTER_ASSERT(reporter, u0 == gTest[i].fUni);
        REPORTER_ASSERT(reporter,
                        p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8));
    }

    test_utf16(reporter);
    test_search(reporter);
    test_refptr(reporter);
    test_autounref(reporter);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("Utils", UtfTestClass, TestUTF)
<commit_msg>Another comment-only change to test notifications<commit_after>#include "Test.h"
#include "SkRandom.h"
#include "SkRefCnt.h"
#include "SkTSearch.h"
#include "SkTSort.h"
#include "SkUtils.h"

class RefClass : public SkRefCnt {
public:
    RefClass(int n) : fN(n) {}
    int get() const { return fN; }

private:
    int fN;
};

static void test_refptr(skiatest::Reporter* reporter) {
    RefClass* r0 = new RefClass(0);

    SkRefPtr<RefClass> rc0;
    REPORTER_ASSERT(reporter, rc0.get() == NULL);
    REPORTER_ASSERT(reporter, !rc0);

    SkRefPtr<RefClass> rc1;
    REPORTER_ASSERT(reporter, rc0 == rc1);
    REPORTER_ASSERT(reporter, rc0.get() != r0);

    rc0 = r0;
    REPORTER_ASSERT(reporter, rc0);
    REPORTER_ASSERT(reporter, rc0 != rc1);
    REPORTER_ASSERT(reporter, rc0.get() == r0);

    rc1 = rc0;
    REPORTER_ASSERT(reporter, rc1);
    REPORTER_ASSERT(reporter, rc0 == rc1);
    REPORTER_ASSERT(reporter, rc0.get() == r0);

    rc0 = NULL;
    REPORTER_ASSERT(reporter, rc0.get() == NULL);
    REPORTER_ASSERT(reporter, !rc0);
    REPORTER_ASSERT(reporter, rc0 != rc1);

    r0->unref();
}

static void test_autounref(skiatest::Reporter* reporter) {
    RefClass obj(0);
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());

    SkAutoTUnref<RefClass> tmp(&obj);
    REPORTER_ASSERT(reporter, &obj == tmp.get());
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());

    REPORTER_ASSERT(reporter, &obj == tmp.detach());
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
    REPORTER_ASSERT(reporter, NULL == tmp.detach());
    REPORTER_ASSERT(reporter, NULL == tmp.get());

    obj.ref();
    REPORTER_ASSERT(reporter, 2 == obj.getRefCnt());
    {
        SkAutoTUnref<RefClass> tmp2(&obj);
    }
    REPORTER_ASSERT(reporter, 1 == obj.getRefCnt());
}

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

#define kSEARCH_COUNT   91

static void test_search(skiatest::Reporter* reporter) {
    int         i, array[kSEARCH_COUNT];
    SkRandom    rand;

    for (i = 0; i < kSEARCH_COUNT; i++) {
        array[i] = rand.nextS();
    }

    SkTHeapSort<int>(array, kSEARCH_COUNT);
    // make sure we got sorted properly
    for (i = 1; i < kSEARCH_COUNT; i++) {
        REPORTER_ASSERT(reporter, array[i-1] <= array[i]);
    }

    // make sure we can find all of our values
    for (i = 0; i < kSEARCH_COUNT; i++) {
        int index = SkTSearch<int>(array, kSEARCH_COUNT, array[i], sizeof(int));
        REPORTER_ASSERT(reporter, index == i);
    }

    // make sure that random values are either found, or the correct
    // insertion index is returned
    for (i = 0; i < 10000; i++) {
        int value = rand.nextS();
        int index = SkTSearch<int>(array, kSEARCH_COUNT, value, sizeof(int));

        if (index >= 0) {
            REPORTER_ASSERT(reporter,
                            index < kSEARCH_COUNT && array[index] == value);
        } else {
            index = ~index;
            REPORTER_ASSERT(reporter, index <= kSEARCH_COUNT);
            if (index < kSEARCH_COUNT) {
                REPORTER_ASSERT(reporter, value < array[index]);
                if (index > 0) {
                    REPORTER_ASSERT(reporter, value > array[index - 1]);
                }
            } else {
                // we should append the new value
                REPORTER_ASSERT(reporter, value > array[kSEARCH_COUNT - 1]);
            }
        }
    }
}

static void test_utf16(skiatest::Reporter* reporter) {
    static const SkUnichar gUni[] = {
        0x10000, 0x18080, 0x20202, 0xFFFFF, 0x101234
    };

    uint16_t buf[2];

    for (size_t i = 0; i < SK_ARRAY_COUNT(gUni); i++) {
        size_t count = SkUTF16_FromUnichar(gUni[i], buf);
        REPORTER_ASSERT(reporter, count == 2);
        size_t count2 = SkUTF16_CountUnichars(buf, 2);
        REPORTER_ASSERT(reporter, count2 == 1);
        const uint16_t* ptr = buf;
        SkUnichar c = SkUTF16_NextUnichar(&ptr);
        REPORTER_ASSERT(reporter, c == gUni[i]);
        REPORTER_ASSERT(reporter, ptr - buf == 2);
    }
}

static void TestUTF(skiatest::Reporter* reporter) {
    static const struct {
        const char* fUtf8;
        SkUnichar   fUni;
    } gTest[] = {
        { "a",                  'a' },
        { "\x7f",               0x7f },
        { "\xC2\x80",           0x80 },
        { "\xC3\x83",           (3 << 6) | 3    },
        { "\xDF\xBF",           0x7ff },
        { "\xE0\xA0\x80",       0x800 },
        { "\xE0\xB0\xB8",       0xC38 },
        { "\xE3\x83\x83",       (3 << 12) | (3 << 6) | 3    },
        { "\xEF\xBF\xBF",       0xFFFF },
        { "\xF0\x90\x80\x80",   0x10000 },
        { "\xF3\x83\x83\x83",   (3 << 18) | (3 << 12) | (3 << 6) | 3    }
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) {
        const char* p = gTest[i].fUtf8;
        int         n = SkUTF8_CountUnichars(p);
        SkUnichar   u0 = SkUTF8_ToUnichar(gTest[i].fUtf8);
        SkUnichar   u1 = SkUTF8_NextUnichar(&p);

        REPORTER_ASSERT(reporter, n == 1);
        REPORTER_ASSERT(reporter, u0 == u1);
        REPORTER_ASSERT(reporter, u0 == gTest[i].fUni);
        REPORTER_ASSERT(reporter,
                        p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8));
    }

    test_utf16(reporter);
    test_search(reporter);
    test_refptr(reporter);
    test_autounref(reporter);
}

#include "TestClassDef.h"
DEFINE_TESTCLASS("Utils", UtfTestClass, TestUTF)
<|endoftext|>


<commit_before>/* This file is part of Ingen.
 * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "LV2Node.hpp"
#include <iostream>
#include <cassert>
#include <float.h>
#include <stdint.h>
#include <cmath>
#include "InputPort.hpp"
#include "OutputPort.hpp"
#include "Plugin.hpp"
#include "AudioBuffer.hpp"
#include "MidiBuffer.hpp"
#include "OSCBuffer.hpp"

namespace Ingen {

/** Partially construct a LV2Node.
 *
 * Object is not usable until instantiate() is called with success.
 * (It _will_ crash!)
 */
LV2Node::LV2Node(const Plugin*      plugin,
                 const string&      name,
                 uint32_t           poly,
                 Patch*             parent,
                 SampleRate         srate,
                 size_t             buffer_size)
: NodeBase(plugin, name, poly, parent, srate, buffer_size),
  _lv2_plugin(plugin->slv2_plugin()),
  _instances(NULL)
{
	assert(_lv2_plugin);
}

/** Instantiate self from LV2 plugin descriptor.
 *
 * Implemented as a seperate function (rather than in the constructor) to
 * allow graceful error-catching of broken plugins.
 *
 * Returns whether or not plugin was successfully instantiated.  If return
 * value is false, this object may not be used.
 */
bool
LV2Node::instantiate()
{
	uint32_t num_ports = slv2_plugin_get_num_ports(_lv2_plugin);
	assert(num_ports > 0);

	_ports = new Raul::Array<Port*>(num_ports);

	_instances = new SLV2Instance[_poly];

	uint32_t port_buffer_size = 0;

	for (uint32_t i=0; i < _poly; ++i) {
		_instances[i] = slv2_plugin_instantiate(_lv2_plugin, _srate, NULL);
		if (_instances[i] == NULL) {
			cerr << "Failed to instantiate plugin!" << endl;
			return false;
		}
	}

	string port_name;
	string port_path;

	Port* port = NULL;

	for (uint32_t j=0; j < num_ports; ++j) {
		SLV2Port id = slv2_plugin_get_port_by_index(_lv2_plugin, j);

		// LV2 shortnames are guaranteed to be unique, valid C identifiers
		port_name = (char*)slv2_port_get_symbol(_lv2_plugin, id);

		assert(port_name.find("/") == string::npos);

		port_path = path() + "/" + port_name;

		SLV2PortDirection port_direction = slv2_port_get_direction(_lv2_plugin, id);
		SLV2PortType      port_type      = slv2_port_get_type(_lv2_plugin, id);

		// FIXME: MIDI/OSC buffer size?
		if (port_type != SLV2_PORT_TYPE_CONTROL)
			port_buffer_size = _buffer_size;
		else
			port_buffer_size = 1;

		DataType data_type = DataType::UNKNOWN;
		switch (port_type) {
		case SLV2_PORT_TYPE_CONTROL:
		case SLV2_PORT_TYPE_AUDIO:
			data_type = DataType::FLOAT; break;
		case SLV2_PORT_TYPE_MIDI:
			data_type = DataType::MIDI; break;
		case SLV2_PORT_TYPE_OSC:
			data_type = DataType::OSC;
		default:
			break;
		}

		if (data_type == DataType::UNKNOWN || port_direction == SLV2_PORT_DIRECTION_UNKNOWN) {
			delete _ports;
			_ports = NULL;
			delete _instances;
			_instances = NULL;
			return false;
		}

		bool is_input = (port_direction == SLV2_PORT_DIRECTION_INPUT);

		if (is_input)
			port = new InputPort(this, port_name, j, _poly, data_type, port_buffer_size);
		else
			port = new OutputPort(this, port_name, j, _poly, data_type, port_buffer_size);

		if (is_input && port_type == SLV2_PORT_TYPE_CONTROL)
			((AudioBuffer*)port->buffer(0))->set(slv2_port_get_default_value(_lv2_plugin, id), 0);

		_ports->at(j) = port;
	}
	return true;
}

LV2Node::~LV2Node()
{
	for (uint32_t i=0; i < _poly; ++i)
		slv2_instance_free(_instances[i]);

	delete[] _instances;
}

void
LV2Node::activate()
{
	NodeBase::activate();

	for (uint32_t i=0; i < _poly; ++i) {
		for (unsigned long j=0; j < num_ports(); ++j) {
			Port* const port = _ports->at(j);
			set_port_buffer(i, j, port->buffer(i));
			if (port->type() == DataType::FLOAT && port->buffer_size() == 1) {
				((AudioBuffer*)port->buffer(i))->set(
					slv2_port_get_default_value(_lv2_plugin,
							slv2_plugin_get_port_by_index(_lv2_plugin, j)),
					0);
			} else if (port->type() == DataType::FLOAT) {
				((AudioBuffer*)port->buffer(i))->set(0.0f, 0);
			}
		}
		slv2_instance_activate(_instances[i]);
	}
}

void
LV2Node::deactivate()
{
	NodeBase::deactivate();

	for (uint32_t i=0; i < _poly; ++i)
		slv2_instance_deactivate(_instances[i]);
}

void
LV2Node::process(SampleCount nframes, FrameTime start, FrameTime end)
{
	NodeBase::pre_process(nframes, start, end);

	for (uint32_t i=0; i < _poly; ++i)
		slv2_instance_run(_instances[i], nframes);

	NodeBase::post_process(nframes, start, end);
}

void
LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf)
{
	assert(voice < _poly);

	if (buf->type() == DataType::FLOAT) {
		slv2_instance_connect_port(_instances[voice], port_num, ((AudioBuffer*)buf)->data());
	} else if (buf->type() == DataType::MIDI) {
		slv2_instance_connect_port(_instances[voice], port_num, ((MidiBuffer*)buf)->data());
	} else if (buf->type() == DataType::OSC) {
		slv2_instance_connect_port(_instances[voice], port_num, ((OSCBuffer*)buf)->data());
	}
}

#if 0
// Based on code stolen from jack-rack
void
LV2Node::get_port_vals(ulong port_index, PortInfo* info)
{
	LV2_Data upper = 0.0f;
	LV2_Data lower = 0.0f;
	LV2_Data normal = 0.0f;
	LV2_PortRangeHintDescriptor hint_descriptor = _descriptor->PortRangeHints[port_index].HintDescriptor;

	/* set upper and lower, possibly adjusted to the sample rate */
	if (LV2_IS_HINT_SAMPLE_RATE(hint_descriptor)) {
		upper = _descriptor->PortRangeHints[port_index].UpperBound * _srate;
		lower = _descriptor->PortRangeHints[port_index].LowerBound * _srate;
	} else {
		upper = _descriptor->PortRangeHints[port_index].UpperBound;
		lower = _descriptor->PortRangeHints[port_index].LowerBound;
	}

	if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
		/* FLT_EPSILON is defined as the different between 1.0 and the minimum
		 * float greater than 1.0.  So, if lower is < FLT_EPSILON, it will be 1.0
		 * and the logarithmic control will have a base of 1 and thus not change
		 */
		if (lower < FLT_EPSILON) lower = FLT_EPSILON;
	}

	if (LV2_IS_HINT_HAS_DEFAULT(hint_descriptor)) {

		if (LV2_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) {
			normal = lower;
		} else if (LV2_IS_HINT_DEFAULT_LOW(hint_descriptor)) {
			if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
				normal = exp(log(lower) * 0.75 + log(upper) * 0.25);
			} else {
				normal = lower * 0.75 + upper * 0.25;
			}
		} else if (LV2_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) {
			if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
				normal = exp(log(lower) * 0.5 + log(upper) * 0.5);
			} else {
				normal = lower * 0.5 + upper * 0.5;
			}
		} else if (LV2_IS_HINT_DEFAULT_HIGH(hint_descriptor)) {
			if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
				normal = exp(log(lower) * 0.25 + log(upper) * 0.75);
			} else {
				normal = lower * 0.25 + upper * 0.75;
			}
		} else if (LV2_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) {
			normal = upper;
		} else if (LV2_IS_HINT_DEFAULT_0(hint_descriptor)) {
			normal = 0.0;
		} else if (LV2_IS_HINT_DEFAULT_1(hint_descriptor)) {
			normal = 1.0;
		} else if (LV2_IS_HINT_DEFAULT_100(hint_descriptor)) {
			normal = 100.0;
		} else if (LV2_IS_HINT_DEFAULT_440(hint_descriptor)) {
			normal = 440.0;
		}
	} else {  // No default hint
		if (LV2_IS_HINT_BOUNDED_BELOW(hint_descriptor)) {
			normal = lower;
		} else if (LV2_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) {
			normal = upper;
		}
	}

	info->min_val(lower);
	info->default_val(normal);
	info->max_val(upper);
}
#endif

} // namespace Ingen

<commit_msg>Update ingen for SLV2 changes. SLV2 0.2.0.<commit_after>/* This file is part of Ingen.
 * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
 *
 * Ingen is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "LV2Node.hpp"
#include <iostream>
#include <cassert>
#include <float.h>
#include <stdint.h>
#include <cmath>
#include "InputPort.hpp"
#include "OutputPort.hpp"
#include "Plugin.hpp"
#include "AudioBuffer.hpp"
#include "MidiBuffer.hpp"
#include "OSCBuffer.hpp"

namespace Ingen {

/** Partially construct a LV2Node.
 *
 * Object is not usable until instantiate() is called with success.
 * (It _will_ crash!)
 */
LV2Node::LV2Node(const Plugin*      plugin,
                 const string&      name,
                 uint32_t           poly,
                 Patch*             parent,
                 SampleRate         srate,
                 size_t             buffer_size)
: NodeBase(plugin, name, poly, parent, srate, buffer_size),
  _lv2_plugin(plugin->slv2_plugin()),
  _instances(NULL)
{
	assert(_lv2_plugin);
}

/** Instantiate self from LV2 plugin descriptor.
 *
 * Implemented as a seperate function (rather than in the constructor) to
 * allow graceful error-catching of broken plugins.
 *
 * Returns whether or not plugin was successfully instantiated.  If return
 * value is false, this object may not be used.
 */
bool
LV2Node::instantiate()
{
	uint32_t num_ports = slv2_plugin_get_num_ports(_lv2_plugin);
	assert(num_ports > 0);

	_ports = new Raul::Array<Port*>(num_ports);

	_instances = new SLV2Instance[_poly];

	uint32_t port_buffer_size = 0;

	for (uint32_t i=0; i < _poly; ++i) {
		_instances[i] = slv2_plugin_instantiate(_lv2_plugin, _srate, NULL);
		if (_instances[i] == NULL) {
			cerr << "Failed to instantiate plugin!" << endl;
			return false;
		}
	}

	string port_name;
	string port_path;

	Port* port = NULL;

	for (uint32_t j=0; j < num_ports; ++j) {
		SLV2Port id = slv2_plugin_get_port_by_index(_lv2_plugin, j);

		// LV2 shortnames are guaranteed to be unique, valid C identifiers
		port_name = (char*)slv2_port_get_symbol(_lv2_plugin, id);

		assert(port_name.find("/") == string::npos);

		port_path = path() + "/" + port_name;

		SLV2PortDirection port_direction = slv2_port_get_direction(_lv2_plugin, id);
		SLV2PortDataType  port_type      = slv2_port_get_data_type(_lv2_plugin, id);

		// FIXME: MIDI/OSC buffer size?
		if (port_type != SLV2_PORT_DATA_TYPE_CONTROL)
			port_buffer_size = _buffer_size;
		else
			port_buffer_size = 1;

		DataType data_type = DataType::UNKNOWN;
		switch (port_type) {
		case SLV2_PORT_DATA_TYPE_CONTROL:
		case SLV2_PORT_DATA_TYPE_AUDIO:
			data_type = DataType::FLOAT; break;
		case SLV2_PORT_DATA_TYPE_MIDI:
			data_type = DataType::MIDI; break;
		case SLV2_PORT_DATA_TYPE_OSC:
			data_type = DataType::OSC;
		default:
			break;
		}

		if (data_type == DataType::UNKNOWN || port_direction == SLV2_PORT_DIRECTION_UNKNOWN) {
			delete _ports;
			_ports = NULL;
			delete _instances;
			_instances = NULL;
			return false;
		}

		bool is_input = (port_direction == SLV2_PORT_DIRECTION_INPUT);

		if (is_input)
			port = new InputPort(this, port_name, j, _poly, data_type, port_buffer_size);
		else
			port = new OutputPort(this, port_name, j, _poly, data_type, port_buffer_size);

		if (is_input && port_type == SLV2_PORT_DATA_TYPE_CONTROL)
			((AudioBuffer*)port->buffer(0))->set(slv2_port_get_default_value(_lv2_plugin, id), 0);

		_ports->at(j) = port;
	}
	return true;
}

LV2Node::~LV2Node()
{
	for (uint32_t i=0; i < _poly; ++i)
		slv2_instance_free(_instances[i]);

	delete[] _instances;
}

void
LV2Node::activate()
{
	NodeBase::activate();

	for (uint32_t i=0; i < _poly; ++i) {
		for (unsigned long j=0; j < num_ports(); ++j) {
			Port* const port = _ports->at(j);
			set_port_buffer(i, j, port->buffer(i));
			if (port->type() == DataType::FLOAT && port->buffer_size() == 1) {
				((AudioBuffer*)port->buffer(i))->set(
					slv2_port_get_default_value(_lv2_plugin,
							slv2_plugin_get_port_by_index(_lv2_plugin, j)),
					0);
			} else if (port->type() == DataType::FLOAT) {
				((AudioBuffer*)port->buffer(i))->set(0.0f, 0);
			}
		}
		slv2_instance_activate(_instances[i]);
	}
}

void
LV2Node::deactivate()
{
	NodeBase::deactivate();

	for (uint32_t i=0; i < _poly; ++i)
		slv2_instance_deactivate(_instances[i]);
}

void
LV2Node::process(SampleCount nframes, FrameTime start, FrameTime end)
{
	NodeBase::pre_process(nframes, start, end);

	for (uint32_t i=0; i < _poly; ++i)
		slv2_instance_run(_instances[i], nframes);

	NodeBase::post_process(nframes, start, end);
}

void
LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf)
{
	assert(voice < _poly);

	if (buf->type() == DataType::FLOAT) {
		slv2_instance_connect_port(_instances[voice], port_num, ((AudioBuffer*)buf)->data());
	} else if (buf->type() == DataType::MIDI) {
		slv2_instance_connect_port(_instances[voice], port_num, ((MidiBuffer*)buf)->data());
	} else if (buf->type() == DataType::OSC) {
		slv2_instance_connect_port(_instances[voice], port_num, ((OSCBuffer*)buf)->data());
	}
}

#if 0
// Based on code stolen from jack-rack
void
LV2Node::get_port_vals(ulong port_index, PortInfo* info)
{
	LV2_Data upper = 0.0f;
	LV2_Data lower = 0.0f;
	LV2_Data normal = 0.0f;
	LV2_PortRangeHintDescriptor hint_descriptor = _descriptor->PortRangeHints[port_index].HintDescriptor;

	/* set upper and lower, possibly adjusted to the sample rate */
	if (LV2_IS_HINT_SAMPLE_RATE(hint_descriptor)) {
		upper = _descriptor->PortRangeHints[port_index].UpperBound * _srate;
		lower = _descriptor->PortRangeHints[port_index].LowerBound * _srate;
	} else {
		upper = _descriptor->PortRangeHints[port_index].UpperBound;
		lower = _descriptor->PortRangeHints[port_index].LowerBound;
	}

	if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
		/* FLT_EPSILON is defined as the different between 1.0 and the minimum
		 * float greater than 1.0.  So, if lower is < FLT_EPSILON, it will be 1.0
		 * and the logarithmic control will have a base of 1 and thus not change
		 */
		if (lower < FLT_EPSILON) lower = FLT_EPSILON;
	}

	if (LV2_IS_HINT_HAS_DEFAULT(hint_descriptor)) {

		if (LV2_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) {
			normal = lower;
		} else if (LV2_IS_HINT_DEFAULT_LOW(hint_descriptor)) {
			if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
				normal = exp(log(lower) * 0.75 + log(upper) * 0.25);
			} else {
				normal = lower * 0.75 + upper * 0.25;
			}
		} else if (LV2_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) {
			if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
				normal = exp(log(lower) * 0.5 + log(upper) * 0.5);
			} else {
				normal = lower * 0.5 + upper * 0.5;
			}
		} else if (LV2_IS_HINT_DEFAULT_HIGH(hint_descriptor)) {
			if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) {
				normal = exp(log(lower) * 0.25 + log(upper) * 0.75);
			} else {
				normal = lower * 0.25 + upper * 0.75;
			}
		} else if (LV2_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) {
			normal = upper;
		} else if (LV2_IS_HINT_DEFAULT_0(hint_descriptor)) {
			normal = 0.0;
		} else if (LV2_IS_HINT_DEFAULT_1(hint_descriptor)) {
			normal = 1.0;
		} else if (LV2_IS_HINT_DEFAULT_100(hint_descriptor)) {
			normal = 100.0;
		} else if (LV2_IS_HINT_DEFAULT_440(hint_descriptor)) {
			normal = 440.0;
		}
	} else {  // No default hint
		if (LV2_IS_HINT_BOUNDED_BELOW(hint_descriptor)) {
			normal = lower;
		} else if (LV2_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) {
			normal = upper;
		}
	}

	info->min_val(lower);
	info->default_val(normal);
	info->max_val(upper);
}
#endif

} // namespace Ingen

<|endoftext|>


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

#include <libxstream_begin.h>
#include <algorithm>
#include <cstdio>
#if defined(LIBXSTREAM_STDFEATURES)
# include <thread>
# include <atomic>
#else
# if defined(__GNUC__)
#   include <pthread.h>
# else
#   include <Windows.h>
# endif
#endif
#include <libxstream_end.h>

namespace libxstream_workitem_internal {

class scheduler_type {
public:
  typedef libxstream_workqueue::entry_type entry_type;

public:
  scheduler_type()
    : m_global_queue()
    , m_stream(0)
#if defined(LIBXSTREAM_STDFEATURES)
    , m_thread() // do not start here
#else
    , m_thread(0)
#endif
  {}

  ~scheduler_type() {
    if (running()) {
      // terminates the background thread
      entry_type& entry = m_global_queue.allocate_entry();
      delete entry.dangling();
      entry = entry_type(&m_global_queue);
      entry.wait();

#if defined(LIBXSTREAM_STDFEATURES)
      m_thread.detach();
#else
# if defined(__GNUC__)
      pthread_detach(m_thread);
# else
      CloseHandle(m_thread);
# endif
#endif
    }
  }

public:
  bool running() const {
#if defined(LIBXSTREAM_STDFEATURES)
    return m_thread.joinable();
#else
    return 0 != m_thread;
#endif
  }

  void start() {
    if (!running()) {
      libxstream_lock *const lock = libxstream_lock_get(this);
      libxstream_lock_acquire(lock);

      if (!running()) {
#if defined(LIBXSTREAM_STDFEATURES)
        std::thread(run, this).swap(m_thread);
#else
# if defined(__GNUC__)
        pthread_create(&m_thread, 0, run, this);
# else
        m_thread = CreateThread(0, 0, run, this, 0, 0);
# endif
#endif
      }

      libxstream_lock_release(lock);
    }
  }

  entry_type& get() {
    entry_type* result = &m_global_queue.get();

    if (0 == result->item()) { // no item in global queue
      m_stream = libxstream_stream::schedule(m_stream);
      libxstream_workqueue* queue = m_stream ? m_stream->queue_begin() : 0;

      if (0 != queue) {
        result = &queue->get();

        // item in stream-local queue is a wait-item
        const libxstream_workitem *const item = result->item();
        if (0 != item && 0 != (LIBXSTREAM_CALL_SYNC & item->flags())) {
          queue = m_stream->queue_next(); // next/other queue

          while (0 != queue) {
            entry_type& i = queue->get();

            if (0 == i.item()) {
              queue = m_stream->queue_next();
            }
            else {
              result = &i;
              queue = 0; // break
            }
          }
        }
      }
    }

    return *result;
  }

  entry_type& push(libxstream_workitem& workitem) {
    entry_type& entry = m_global_queue.allocate_entry_mt();
    entry.push(workitem);
    return entry;
  }

private:
#if defined(LIBXSTREAM_STDFEATURES) || defined(__GNUC__)
  static void* run(void* scheduler)
#else
  static DWORD WINAPI run(_In_ LPVOID scheduler)
#endif
  {
    scheduler_type& s = *static_cast<scheduler_type*>(scheduler);
    bool continue_run = true;

#if defined(LIBXSTREAM_ASYNCHOST) && (201307 <= _OPENMP)
#   pragma omp parallel
#   pragma omp master
#endif
    for (; continue_run;) {
      scheduler_type::entry_type* entry = &s.get();
      bool valid = entry->valid();
      size_t cycle = 0;

      while (0 == entry->item() && valid) {
        this_thread_wait(cycle);
        entry = &s.get();
        valid = entry->valid();
      }

      if (valid) {
        entry->execute();
#if defined(LIBXSTREAM_ASYNCHOST) && (201307 <= _OPENMP)
#       pragma omp taskwait
#endif
      }
      else {
        continue_run = false;
      }

      entry->pop();
    }

#if defined(LIBXSTREAM_STDFEATURES) || defined(__GNUC__)
    return scheduler;
#else
    return EXIT_SUCCESS;
#endif
  }

private:
  libxstream_workqueue m_global_queue;
  libxstream_stream* m_stream;
#if defined(LIBXSTREAM_STDFEATURES)
  std::thread m_thread;
#elif defined(__GNUC__)
  pthread_t m_thread;
#else
  HANDLE m_thread;
#endif
};
static/*IPO*/ scheduler_type scheduler;

} // namespace libxstream_workitem_internal

libxstream_workitem::libxstream_workitem(libxstream_stream* stream, int flags, size_t argc, const arg_type argv[], const char* name)
  : m_function(0)
  , m_stream(stream)
  , m_flags(flags)
  , m_thread(this_thread_id())
#if defined(LIBXSTREAM_DEBUG)
  , m_name(name)
#endif
{
#if !defined(LIBXSTREAM_DEBUG)
  libxstream_use_sink(name);
#endif
  if (2 == argc && (argv[0].signature() || argv[1].signature())) {
    const libxstream_argument* signature = 0;
    if (argv[1].signature()) {
      m_function = *reinterpret_cast<const libxstream_function*>(argv + 0);
      signature = static_cast<const libxstream_argument*>(libxstream_get_value(argv[1]).const_pointer);
    }
    else {
      LIBXSTREAM_ASSERT(argv[0].signature());
      m_function = *reinterpret_cast<const libxstream_function*>(argv + 1);
      signature = static_cast<const libxstream_argument*>(libxstream_get_value(argv[0]).const_pointer);
    }

    size_t arity = 0;
    if (signature) {
      LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_get_arity(signature, &arity));
      LIBXSTREAM_PRAGMA_LOOP_COUNT(0, LIBXSTREAM_MAX_NARGS, LIBXSTREAM_MAX_NARGS/2)
      for (size_t i = 0; i < arity; ++i) m_signature[i] = signature[i];
    }
    LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(m_signature, arity, libxstream_argument::kind_invalid, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
  }
  else {
    LIBXSTREAM_ASSERT(argc <= (LIBXSTREAM_MAX_NARGS));
    for (size_t i = 0; i < argc; ++i) m_signature[i] = argv[i];
    LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(m_signature, argc, libxstream_argument::kind_invalid, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
#if defined(LIBXSTREAM_DEBUG)
    size_t arity = 0;
    LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_get_arity(m_signature, &arity) && arity == argc);
#endif
  }

  libxstream_workitem_internal::scheduler.start();
}

libxstream_workitem* libxstream_workitem::clone() const
{
  libxstream_workitem *const instance = virtual_clone();
  LIBXSTREAM_ASSERT(0 != instance);
  return instance;
}

void libxstream_workitem::operator()(libxstream_workqueue::entry_type& entry)
{
  virtual_run(entry);
}

libxstream_workqueue::entry_type& libxstream_enqueue(libxstream_workitem& workitem)
{
  return libxstream_workitem_internal::scheduler.push(workitem);
}

#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
<commit_msg>Implemented terminated-flags in order to avoid resurrecting the background thread in case the queue already terminated.<commit_after>/******************************************************************************
** Copyright (c) 2014-2015, Intel Corporation                                **
** All rights reserved.                                                      **
**                                                                           **
** Redistribution and use in source and binary forms, with or without        **
** modification, are permitted provided that the following conditions        **
** are met:                                                                  **
** 1. Redistributions of source code must retain the above copyright         **
**    notice, this list of conditions and the following disclaimer.          **
** 2. Redistributions in binary form must reproduce the above copyright      **
**    notice, this list of conditions and the following disclaimer in the    **
**    documentation and/or other materials provided with the distribution.   **
** 3. Neither the name of the copyright holder nor the names of its          **
**    contributors may be used to endorse or promote products derived        **
**    from this software without specific prior written permission.          **
**                                                                           **
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       **
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         **
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR     **
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      **
** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    **
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED  **
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR    **
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    **
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      **
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        **
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              **
******************************************************************************/
/* Hans Pabst (Intel Corp.)
******************************************************************************/
#if defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
#include "libxstream_workitem.hpp"

#include <libxstream_begin.h>
#include <algorithm>
#include <cstdio>
#if defined(LIBXSTREAM_STDFEATURES)
# include <thread>
# include <atomic>
#else
# if defined(__GNUC__)
#   include <pthread.h>
# else
#   include <Windows.h>
# endif
#endif
#include <libxstream_end.h>

namespace libxstream_workitem_internal {

class scheduler_type {
public:
  typedef libxstream_workqueue::entry_type entry_type;

public:
  scheduler_type()
    : m_global_queue()
    , m_stream(0)
#if defined(LIBXSTREAM_STDFEATURES)
    , m_thread() // do not start here
#else
    , m_thread(0)
#endif
    , m_terminated(false)
  {}

  ~scheduler_type() {
    if (running()) {
      // terminates the background thread
      entry_type& entry = m_global_queue.allocate_entry();
      delete entry.dangling();
      entry = entry_type(&m_global_queue);
      entry.wait();

      m_terminated = true;
#if defined(LIBXSTREAM_STDFEATURES)
      m_thread.detach();
#else
# if defined(__GNUC__)
      pthread_detach(m_thread);
# else
      CloseHandle(m_thread);
# endif
#endif
    }
  }

public:
  bool running() const {
#if defined(LIBXSTREAM_STDFEATURES)
    return m_thread.joinable();
#else
    return 0 != m_thread;
#endif
  }

  void start() {
    if (!m_terminated && !running()) {
      libxstream_lock *const lock = libxstream_lock_get(this);
      libxstream_lock_acquire(lock);

      if (!running()) {
#if defined(LIBXSTREAM_STDFEATURES)
        std::thread(run, this).swap(m_thread);
#else
# if defined(__GNUC__)
        pthread_create(&m_thread, 0, run, this);
# else
        m_thread = CreateThread(0, 0, run, this, 0, 0);
# endif
#endif
      }

      libxstream_lock_release(lock);
    }
  }

  entry_type& get() {
    entry_type* result = &m_global_queue.get();

    if (0 == result->item()) { // no item in global queue
      m_stream = libxstream_stream::schedule(m_stream);
      libxstream_workqueue* queue = m_stream ? m_stream->queue_begin() : 0;

      if (0 != queue) {
        result = &queue->get();

        // item in stream-local queue is a wait-item
        const libxstream_workitem *const item = result->item();
        if (0 != item && 0 != (LIBXSTREAM_CALL_SYNC & item->flags())) {
          queue = m_stream->queue_next(); // next/other queue

          while (0 != queue) {
            entry_type& i = queue->get();

            if (0 == i.item()) {
              queue = m_stream->queue_next();
            }
            else {
              result = &i;
              queue = 0; // break
            }
          }
        }
      }
    }

    return *result;
  }

  entry_type& push(libxstream_workitem& workitem) {
    entry_type& entry = m_global_queue.allocate_entry_mt();
    entry.push(workitem);
    return entry;
  }

private:
#if defined(LIBXSTREAM_STDFEATURES) || defined(__GNUC__)
  static void* run(void* scheduler)
#else
  static DWORD WINAPI run(_In_ LPVOID scheduler)
#endif
  {
    scheduler_type& s = *static_cast<scheduler_type*>(scheduler);
    bool continue_run = true;

#if defined(LIBXSTREAM_ASYNCHOST) && (201307 <= _OPENMP)
#   pragma omp parallel
#   pragma omp master
#endif
    for (; continue_run;) {
      scheduler_type::entry_type* entry = &s.get();
      bool valid = entry->valid();
      size_t cycle = 0;

      while (0 == entry->item() && valid) {
        this_thread_wait(cycle);
        entry = &s.get();
        valid = entry->valid();
      }

      if (valid) {
        entry->execute();
#if defined(LIBXSTREAM_ASYNCHOST) && (201307 <= _OPENMP)
#       pragma omp taskwait
#endif
      }
      else {
        continue_run = false;
      }

      entry->pop();
    }

#if defined(LIBXSTREAM_STDFEATURES) || defined(__GNUC__)
    return scheduler;
#else
    return EXIT_SUCCESS;
#endif
  }

private:
  libxstream_workqueue m_global_queue;
  libxstream_stream* m_stream;
#if defined(LIBXSTREAM_STDFEATURES)
  std::thread m_thread;
#elif defined(__GNUC__)
  pthread_t m_thread;
#else
  HANDLE m_thread;
#endif
  bool m_terminated;
};
static/*IPO*/ scheduler_type scheduler;

} // namespace libxstream_workitem_internal

libxstream_workitem::libxstream_workitem(libxstream_stream* stream, int flags, size_t argc, const arg_type argv[], const char* name)
  : m_function(0)
  , m_stream(stream)
  , m_flags(flags)
  , m_thread(this_thread_id())
#if defined(LIBXSTREAM_DEBUG)
  , m_name(name)
#endif
{
#if !defined(LIBXSTREAM_DEBUG)
  libxstream_use_sink(name);
#endif
  if (2 == argc && (argv[0].signature() || argv[1].signature())) {
    const libxstream_argument* signature = 0;
    if (argv[1].signature()) {
      m_function = *reinterpret_cast<const libxstream_function*>(argv + 0);
      signature = static_cast<const libxstream_argument*>(libxstream_get_value(argv[1]).const_pointer);
    }
    else {
      LIBXSTREAM_ASSERT(argv[0].signature());
      m_function = *reinterpret_cast<const libxstream_function*>(argv + 1);
      signature = static_cast<const libxstream_argument*>(libxstream_get_value(argv[0]).const_pointer);
    }

    size_t arity = 0;
    if (signature) {
      LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_get_arity(signature, &arity));
      LIBXSTREAM_PRAGMA_LOOP_COUNT(0, LIBXSTREAM_MAX_NARGS, LIBXSTREAM_MAX_NARGS/2)
      for (size_t i = 0; i < arity; ++i) m_signature[i] = signature[i];
    }
    LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(m_signature, arity, libxstream_argument::kind_invalid, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
  }
  else {
    LIBXSTREAM_ASSERT(argc <= (LIBXSTREAM_MAX_NARGS));
    for (size_t i = 0; i < argc; ++i) m_signature[i] = argv[i];
    LIBXSTREAM_CHECK_CALL_ASSERT(libxstream_construct(m_signature, argc, libxstream_argument::kind_invalid, 0, LIBXSTREAM_TYPE_INVALID, 0, 0));
#if defined(LIBXSTREAM_DEBUG)
    size_t arity = 0;
    LIBXSTREAM_ASSERT(LIBXSTREAM_ERROR_NONE == libxstream_get_arity(m_signature, &arity) && arity == argc);
#endif
  }

  libxstream_workitem_internal::scheduler.start();
}

libxstream_workitem* libxstream_workitem::clone() const
{
  libxstream_workitem *const instance = virtual_clone();
  LIBXSTREAM_ASSERT(0 != instance);
  return instance;
}

void libxstream_workitem::operator()(libxstream_workqueue::entry_type& entry)
{
  virtual_run(entry);
}

libxstream_workqueue::entry_type& libxstream_enqueue(libxstream_workitem& workitem)
{
  return libxstream_workitem_internal::scheduler.push(workitem);
}

#endif // defined(LIBXSTREAM_EXPORTED) || defined(__LIBXSTREAM)
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////
//
// The MIT License (MIT)
//
// Copyright (c) 2014 stevehalliwell
//
// 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 <ResourceManager/ResourceManager.hpp>
#include <ResourceManager/BaseResource.hpp>
#include <ResourceManager/LuaParser.hpp>
#include <string>
namespace rm
{

////////////////////////////////////////////////////////////
/// Initialise static members
////////////////////////////////////////////////////////////
ResourceLookup ResourceManager::resources = {};
ResourceLookup ResourceManager::errorResources = {};
ResourceQueue ResourceManager::loadingQueue = {};
ResourceQueue ResourceManager::unloadQueue = {};
ResourceQueue ResourceManager::reloadQueue = {};
bool ResourceManager::useNullForErrorRes = true;

LoadCompleteCallback ResourceManager::loadCompleteCallback = nullptr;

enum class LoadMode
{
    Queue,
    Block,
};
////////////////////////////////////////////////////////////
/// Function definitions
////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////
/// \brief ResourceManager unloads this single resource and
///     assigns the mode for the queue.
///
/// \param name The resource's alias
///
/// \param mode If the resource hasn't been unloaded yet, mode determines
///     whether it should queue it for unloading or unload it immediately
///
////////////////////////////////////////////////////////////
void ResourceManager::unloadResource(const std::string& name, LoadMode mode)
{
    // Setting a new Resource pointer to append to &name if found
    ResourcePtr pointer;

    // Checking if resource exists in resources
   if (resources.find(name) != resources.end())
   {
       // Assigns a new pointer to the key for the resource
       pointer = resources.find(name)->second;

       // If the resource has to be removed immediately
       if(mode == LoadMode::Block)
       {
           // Change the status of the BaseResource
           pointer->isLoaded = false;
           // Unload the BaseResource
           pointer->unload;
       }
       else
       {
           // Change the status of the BaseResource
           pointer->isLoaded = false;
           // Send to unloadQueue list
           unloadQueue.push(pointer);
       }
    }

    // if not return
    // is so, check mode//if queue, send to queue
    //else unload now

    throw("Not implemented");
    // Must appropriately set isLoaded in resource
    return;

}

void ResourceManager::reloadResource(const std::string& name)
{
    throw("Not implemented");
    // Must appropriately set isLoaded in resource
}

void ResourceManager::initResource(const std::string& path)
{
	//How do you check if a string is a valid file path? Does this even need to be checked?
	/*
	if(path is not a valid filepath)
	{
		return error?
	}
	*/

	bool exists = false;

	//Check if resource with file path already exists.
	for(ResourceLookup::iterator iter = resources.begin(); iter != resources.end(); iter++)
	{
		if(resources[iter].second->getFilePath() == path)
		{
			exists = true;
		}
	}

	//If it does not already exist then create and add to resources.
	if(!exists)
	{
		ResourcePtr res = ResourceFactory::createResource(path, /*type?*/);
		resources.insert({path, res});

		//return success?
	}
	else
	{
		//return error (already exists)?
	}
}

void ResourceManager::initPack(const std::string& path)
{
    //How do you check if a string is a valid file path? Does this even need to be checked?
	/*
	if(path is not a valid filepath)
	{
		return error?
	}
	*/

	//Get a list of data from the resource pack lua table
	ResourceDataList list = LuaParser::parsePack(path);

	//iterate through the list and create a new resource if one does not already exist.
	for(ResourceDataList::iterator iter = list.begin(); iter != list.end(); iter++)
	{
		//is this supposed to call initResource()? It seems like initResource() will not set an alias as it only takes a path, whereas this function can set the alias and type returned from the luaparser.
		//initResource(list[iter].path);

		//If it does not call initResource()
		bool exists = false;
		for(ResourceLookup::iterator iter2 = resources.begin(); iter2 != resources.end(); iter2++)
		{
			if(resources[iter2].second->getFilePath() == path)
			{
				exists = true;
			}
		}

		if(!exists)
		{
			ResourcePtr res = ResourceFactory::createResource(list[iter]->path, list[iter]->type);
			res->SetAlias(list[iter]->alias);
			resources.insert({list[iter]->alias, res});

			//return success?
		}
		else
		{
			//return error (already exists)?
		}
	}
}

void ResourceManager::loadPack(const std::string& path, LoadMode mode)
{
    throw("Not implemented");

}

void ResourceManager::unloadPack(const std::string& path, LoadMode mode)
{
    throw("Not implemented");

}

void ResourceManager::reloadPack(const std::string& path)
{
    throw("Not implemented");

}

void ResourceManager::switchPack(const std::string& fromPath, const std::string& toPath)
{
    throw("Not implemented");

}

void ResourceManager::init(bool _useNullForErrorRes)
{
    useNullForErrorRes = _useNullForErrorRes;

    if(!useNullForErrorRes)
    {
        // Init default resources
        // but we don't have any yet
    }
}

void ResourceManager::update()
{
    loadFromQueue();
    unloadFromQueue();
    reloadFromQueue();
}

void ResourceManager::cleanupUnused()
{
   for(ResourcePtr r : resources)
   {
      if(r.unique())
      {
          r->setIsLoaded(false);
          r->unload();
      }
   }
}

}

bool ResourceManager::isLoading()
{
    return getNumToLoad() > 0;
}

size_t ResourceManager::getNumToLoad()
{
    return loadingQueue.size();
}

ResourceList ResourceManager::listAll()
{
    throw("Not implemented");
    return ResourceList();
}

size_t ResourceManager::getMemUsage()
{
    throw("Not implemented");

}

size_t ResourceManager::getNumResources()
{
    return resources.size();
}

void ResourceManager::setLoadCompleteCallback(LoadCompleteCallback callback)
{
    loadCompleteCallback = callback;
}

void ResourceManager::loadFromQueue()
{
    throw("Not implemented");
    // Must appropriately set isLoaded in resource

    // bail if queue empty
    // load
    // pop
    // if queue empty call loadCompleteCallback
}

void ResourceManager::unloadFromQueue()
{
    throw("Not implemented");
    // Must appropriately set isLoaded in resource
}

void ResourceManager::reloadFromQueue()
{
    throw("Not implemented");

}

} // rm
<commit_msg>Error fixed in unloadResource<commit_after>////////////////////////////////////////////////////////////
//
// The MIT License (MIT)
//
// Copyright (c) 2014 stevehalliwell
//
// 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 <ResourceManager/ResourceManager.hpp>
#include <ResourceManager/BaseResource.hpp>
#include <ResourceManager/LuaParser.hpp>
#include <string>
namespace rm
{

////////////////////////////////////////////////////////////
/// Initialise static members
////////////////////////////////////////////////////////////
ResourceLookup ResourceManager::resources = {};
ResourceLookup ResourceManager::errorResources = {};
ResourceQueue ResourceManager::loadingQueue = {};
ResourceQueue ResourceManager::unloadQueue = {};
ResourceQueue ResourceManager::reloadQueue = {};
bool ResourceManager::useNullForErrorRes = true;

LoadCompleteCallback ResourceManager::loadCompleteCallback = nullptr;

enum class LoadMode
{
    Queue,
    Block,
};
////////////////////////////////////////////////////////////
/// Function definitions
////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////
/// \brief ResourceManager unloads this single resource and
///     assigns the mode for the queue.
///
/// \param name The resource's alias
///
/// \param mode If the resource hasn't been unloaded yet, mode determines
///     whether it should queue it for unloading or unload it immediately
///
////////////////////////////////////////////////////////////
void ResourceManager::unloadResource(const std::string& name, LoadMode mode)
{
    // Setting a new Resource pointer to append to &name if found
    ResourcePtr pointer;

    // Checking if resource exists in resources
   if (resources.find(name) != resources.end())
   {
       // Assigns a new pointer to the key for the resource
       pointer = resources.find(name)->second;

       // If the resource has to be removed immediately
       if(mode == LoadMode::Block)
       {
           // Change the status of the BaseResource
           pointer->setIsLoaded(false);
           // Unload the BaseResource
           pointer->unload;
       }
       else
       {
           // Change the status of the BaseResource
           pointer->setIsLoaded(false);
           // Send to unloadQueue list
           unloadQueue.push(pointer);
       }
    }

    throw("Not implemented");

    return;

}

void ResourceManager::reloadResource(const std::string& name)
{
    throw("Not implemented");
    // Must appropriately set isLoaded in resource
}

void ResourceManager::initResource(const std::string& path)
{
	//How do you check if a string is a valid file path? Does this even need to be checked?
	/*
	if(path is not a valid filepath)
	{
		return error?
	}
	*/

	bool exists = false;

	//Check if resource with file path already exists.
	for(ResourceLookup::iterator iter = resources.begin(); iter != resources.end(); iter++)
	{
		if(resources[iter].second->getFilePath() == path)
		{
			exists = true;
		}
	}

	//If it does not already exist then create and add to resources.
	if(!exists)
	{
		ResourcePtr res = ResourceFactory::createResource(path, /*type?*/);
		resources.insert({path, res});

		//return success?
	}
	else
	{
		//return error (already exists)?
	}
}

void ResourceManager::initPack(const std::string& path)
{
    //How do you check if a string is a valid file path? Does this even need to be checked?
	/*
	if(path is not a valid filepath)
	{
		return error?
	}
	*/

	//Get a list of data from the resource pack lua table
	ResourceDataList list = LuaParser::parsePack(path);

	//iterate through the list and create a new resource if one does not already exist.
	for(ResourceDataList::iterator iter = list.begin(); iter != list.end(); iter++)
	{
		//is this supposed to call initResource()? It seems like initResource() will not set an alias as it only takes a path, whereas this function can set the alias and type returned from the luaparser.
		//initResource(list[iter].path);

		//If it does not call initResource()
		bool exists = false;
		for(ResourceLookup::iterator iter2 = resources.begin(); iter2 != resources.end(); iter2++)
		{
			if(resources[iter2].second->getFilePath() == path)
			{
				exists = true;
			}
		}

		if(!exists)
		{
			ResourcePtr res = ResourceFactory::createResource(list[iter]->path, list[iter]->type);
			res->SetAlias(list[iter]->alias);
			resources.insert({list[iter]->alias, res});

			//return success?
		}
		else
		{
			//return error (already exists)?
		}
	}
}

void ResourceManager::loadPack(const std::string& path, LoadMode mode)
{
    throw("Not implemented");

}

void ResourceManager::unloadPack(const std::string& path, LoadMode mode)
{
    throw("Not implemented");

}

void ResourceManager::reloadPack(const std::string& path)
{
    throw("Not implemented");

}

void ResourceManager::switchPack(const std::string& fromPath, const std::string& toPath)
{
    throw("Not implemented");

}

void ResourceManager::init(bool _useNullForErrorRes)
{
    useNullForErrorRes = _useNullForErrorRes;

    if(!useNullForErrorRes)
    {
        // Init default resources
        // but we don't have any yet
    }
}

void ResourceManager::update()
{
    loadFromQueue();
    unloadFromQueue();
    reloadFromQueue();
}

void ResourceManager::cleanupUnused()
{
   for(ResourcePtr r : resources)
   {
      if(r.unique())
      {
          r->setIsLoaded(false);
          r->unload();
      }
   }
}

}

bool ResourceManager::isLoading()
{
    return getNumToLoad() > 0;
}

size_t ResourceManager::getNumToLoad()
{
    return loadingQueue.size();
}

ResourceList ResourceManager::listAll()
{
    throw("Not implemented");
    return ResourceList();
}

size_t ResourceManager::getMemUsage()
{
    throw("Not implemented");

}

size_t ResourceManager::getNumResources()
{
    return resources.size();
}

void ResourceManager::setLoadCompleteCallback(LoadCompleteCallback callback)
{
    loadCompleteCallback = callback;
}

void ResourceManager::loadFromQueue()
{
    throw("Not implemented");
    // Must appropriately set isLoaded in resource

    // bail if queue empty
    // load
    // pop
    // if queue empty call loadCompleteCallback
}

void ResourceManager::unloadFromQueue()
{
    throw("Not implemented");
    // Must appropriately set isLoaded in resource
}

void ResourceManager::reloadFromQueue()
{
    throw("Not implemented");

}

} // rm
<|endoftext|>


<commit_before>#include "SalomeApp_VTKSelector.h"
#include "SalomeApp_DataOwner.h"

#include "SVTK_ViewModel.h"
#include "SVTK_Selector.h"
#include "SVTK_ViewWindow.h"
#include "SALOME_Actor.h"

#include "SALOME_ListIteratorOfListIO.hxx"

#include "utilities.h"

#ifdef _DEBUG_
static int MYDEBUG = 1;
#else
static int MYDEBUG = 0;
#endif

SalomeApp_SVTKDataOwner
::SalomeApp_SVTKDataOwner( const Handle(SALOME_InteractiveObject)& theIO,
			   const TColStd_IndexedMapOfInteger& theIds,
			   Selection_Mode theMode,
			   SALOME_Actor* theActor):
  SalomeApp_DataOwner( theIO ),
  mySelectionMode(theMode),
  myActor(theActor)
{
  myIds = theIds; // workaround - there is no constructor copy for the container
}

SalomeApp_SVTKDataOwner
::~SalomeApp_SVTKDataOwner()
{
}

SALOME_Actor*
SalomeApp_SVTKDataOwner
::GetActor() const
{
  return myActor.GetPointer();
}

SalomeApp_VTKSelector
::SalomeApp_VTKSelector( SVTK_Viewer* viewer,
			 SUIT_SelectionMgr* mgr ):
  QObject( 0 ),
  SUIT_Selector( mgr ),
  myViewer( viewer )
{
  if ( myViewer )
    connect( myViewer, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) );
}

SalomeApp_VTKSelector
::~SalomeApp_VTKSelector()
{
}

SVTK_Viewer*
SalomeApp_VTKSelector
::viewer() const
{
  return myViewer;
}

QString
SalomeApp_VTKSelector
::type() const
{
  return SVTK_Viewer::Type();
}

void
SalomeApp_VTKSelector
::onSelectionChanged()
{
  selectionChanged();
}

void
SalomeApp_VTKSelector
::getSelection( SUIT_DataOwnerPtrList& aList ) const
{
  if(myViewer){
    if(SUIT_ViewManager* aViewMgr = myViewer->getViewManager()){
      if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewMgr->getActiveView())){
	if(SVTK_Selector* aSelector = aView->GetSelector()){
	  Selection_Mode aMode = aSelector->SelectionMode();
	  const SALOME_ListIO& aListIO = aSelector->StoredIObjects();
	  SALOME_ListIteratorOfListIO anIter(aListIO);
	  for(; anIter.More(); anIter.Next()){
	    Handle(SALOME_InteractiveObject) anIO = anIter.Value();
	    if(anIO->hasEntry()){
	      TColStd_IndexedMapOfInteger anIds;
	      aSelector->GetIndex(anIO,anIds);
	      SALOME_Actor* anActor = aSelector->GetActor(anIO);
	      aList.append(new SalomeApp_SVTKDataOwner(anIO,anIds,aMode,anActor));
	      if(MYDEBUG) MESSAGE("VTKSelector::getSelection - "<<anIO->getEntry());
	    }
	  }
	}
      }
    }
  }
}

void
SalomeApp_VTKSelector
::setSelection( const SUIT_DataOwnerPtrList& theList )
{
  if(myViewer){
    if(SUIT_ViewManager* aViewMgr = myViewer->getViewManager()){
      if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewMgr->getActiveView())){
	if(SVTK_Selector* aSelector = aView->GetSelector()){
	  SALOME_ListIO anAppendList;
	  const SALOME_ListIO& aStoredList = aSelector->StoredIObjects();
	  SUIT_DataOwnerPtrList::const_iterator anIter = theList.begin();
	  for(; anIter != theList.end(); ++anIter){
	    const SUIT_DataOwner* aDataOwner = (*anIter).get();
	    if(const SalomeApp_SVTKDataOwner* anOwner = dynamic_cast<const SalomeApp_SVTKDataOwner*>(aDataOwner)){
	      aSelector->SetSelectionMode(anOwner->GetMode());
	      Handle(SALOME_InteractiveObject) anIO = anOwner->IO();
	      aSelector->AddIObject(anIO);
	      anAppendList.Append(anIO);
	      aSelector->AddOrRemoveIndex(anIO,anOwner->GetIds(),false);
	      if(MYDEBUG) MESSAGE("VTKSelector::setSelection - SVTKDataOwner - "<<anIO->getEntry());
	    }else if(const SalomeApp_DataOwner* anOwner = dynamic_cast<const SalomeApp_DataOwner*>(aDataOwner)){
	      Handle(SALOME_InteractiveObject) anIO =
		new SALOME_InteractiveObject(anOwner->entry().latin1(),"");
	      aSelector->AddIObject(anIO);
	      anAppendList.Append(anIO);
	      if(MYDEBUG) MESSAGE("VTKSelector::setSelection - DataOwner - "<<anIO->getEntry());
	    }
	  }
	  // To remove IOs, which is not selected.
	  QMap< QString, Handle( SALOME_InteractiveObject )> toRemove;
	  SALOME_ListIteratorOfListIO anIt( aStoredList );
	  for( ; anIt.More(); anIt.Next() )
	    if( !anIt.Value().IsNull() )
	      toRemove[ anIt.Value()->getEntry() ] = anIt.Value();

	  anIt = SALOME_ListIteratorOfListIO(anAppendList);
	  for( ; anIt.More(); anIt.Next() )
	    toRemove.remove( anIt.Value()->getEntry() );

/*	  SALOME_ListIO aRemoveList;
	  SALOME_ListIteratorOfListIO anAppendListIter(anAppendList);
	  for(; anAppendListIter.More(); anAppendListIter.Next()){
	    Handle(SALOME_InteractiveObject) anIO = anAppendListIter.Value();
	    SALOME_ListIteratorOfListIO aStoredListIter(aStoredList);
	    for(; aStoredListIter.More(); aStoredListIter.Next()){
	      if(anIO->isSame(aStoredListIter.Value())){
		aRemoveList.Append(anIO);
	      }
	    }
	  }
	  SALOME_ListIteratorOfListIO aRemoveListIter(aRemoveList);*/

	  QMap< QString, Handle( SALOME_InteractiveObject )>::const_iterator RIt = toRemove.begin(),
	                                                                     REnd = toRemove.end();
	  for( ; RIt!=REnd; RIt++ )
	    aSelector->RemoveIObject( RIt.data() );

	  aView->onSelectionChanged();
	}
      }
    }
  }
}
<commit_msg>*** empty log message ***<commit_after>#include "SalomeApp_VTKSelector.h"
#include "SalomeApp_DataOwner.h"

#include "SVTK_ViewModel.h"
#include "SVTK_Selector.h"
#include "SVTK_ViewWindow.h"
#include "SALOME_Actor.h"

#include "SALOME_ListIteratorOfListIO.hxx"

#include "utilities.h"

#ifdef _DEBUG_
static int MYDEBUG = 1;
#else
static int MYDEBUG = 0;
#endif

SalomeApp_SVTKDataOwner
::SalomeApp_SVTKDataOwner( const Handle(SALOME_InteractiveObject)& theIO,
			   const TColStd_IndexedMapOfInteger& theIds,
			   Selection_Mode theMode,
			   SALOME_Actor* theActor):
  SalomeApp_DataOwner( theIO ),
  mySelectionMode(theMode),
  myActor(theActor)
{
  myIds = theIds; // workaround - there is no constructor copy for the container
}

SalomeApp_SVTKDataOwner
::~SalomeApp_SVTKDataOwner()
{
}

SALOME_Actor*
SalomeApp_SVTKDataOwner
::GetActor() const
{
  return myActor.GetPointer();
}

SalomeApp_VTKSelector
::SalomeApp_VTKSelector( SVTK_Viewer* viewer,
			 SUIT_SelectionMgr* mgr ):
  QObject( 0 ),
  SUIT_Selector( mgr ),
  myViewer( viewer )
{
  if ( myViewer )
    connect( myViewer, SIGNAL( selectionChanged() ), this, SLOT( onSelectionChanged() ) );
}

SalomeApp_VTKSelector
::~SalomeApp_VTKSelector()
{
}

SVTK_Viewer*
SalomeApp_VTKSelector
::viewer() const
{
  return myViewer;
}

QString
SalomeApp_VTKSelector
::type() const
{
  return SVTK_Viewer::Type();
}

void
SalomeApp_VTKSelector
::onSelectionChanged()
{
  selectionChanged();
}

void
SalomeApp_VTKSelector
::getSelection( SUIT_DataOwnerPtrList& aList ) const
{
  if(myViewer){
    if(SUIT_ViewManager* aViewMgr = myViewer->getViewManager()){
      if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewMgr->getActiveView())){
	if(SVTK_Selector* aSelector = aView->GetSelector()){
	  Selection_Mode aMode = aSelector->SelectionMode();
	  const SALOME_ListIO& aListIO = aSelector->StoredIObjects();
	  SALOME_ListIteratorOfListIO anIter(aListIO);
	  for(; anIter.More(); anIter.Next()){
	    Handle(SALOME_InteractiveObject) anIO = anIter.Value();
	    if(anIO->hasEntry()){
	      TColStd_IndexedMapOfInteger anIds;
	      aSelector->GetIndex(anIO,anIds);
	      SALOME_Actor* anActor = aSelector->GetActor(anIO);
	      aList.append(new SalomeApp_SVTKDataOwner(anIO,anIds,aMode,anActor));
	      if(MYDEBUG) MESSAGE("VTKSelector::getSelection - "<<anIO->getEntry());
	    }
	  }
	}
      }
    }
  }
}

void
SalomeApp_VTKSelector
::setSelection( const SUIT_DataOwnerPtrList& theList )
{
  if(myViewer){
    if(SUIT_ViewManager* aViewMgr = myViewer->getViewManager()){
      if(SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewMgr->getActiveView())){
	if(SVTK_Selector* aSelector = aView->GetSelector()){
	  SALOME_ListIO anAppendList;
	  const SALOME_ListIO& aStoredList = aSelector->StoredIObjects();
	  SUIT_DataOwnerPtrList::const_iterator anIter = theList.begin();
	  for(; anIter != theList.end(); ++anIter){
	    const SUIT_DataOwner* aDataOwner = (*anIter).get();
	    if(const SalomeApp_SVTKDataOwner* anOwner = dynamic_cast<const SalomeApp_SVTKDataOwner*>(aDataOwner)){
	      aSelector->SetSelectionMode(anOwner->GetMode());
	      Handle(SALOME_InteractiveObject) anIO = anOwner->IO();
	      aSelector->AddIObject(anIO);
	      anAppendList.Append(anIO);
	      aSelector->AddOrRemoveIndex(anIO,anOwner->GetIds(),false);
	      if(MYDEBUG) MESSAGE("VTKSelector::setSelection - SVTKDataOwner - "<<anIO->getEntry());
	    }else if(const SalomeApp_DataOwner* anOwner = dynamic_cast<const SalomeApp_DataOwner*>(aDataOwner)){
	      Handle(SALOME_InteractiveObject) anIO =
		new SALOME_InteractiveObject(anOwner->entry().latin1(),"");
	      aSelector->AddIObject(anIO);
	      anAppendList.Append(anIO);
	      if(MYDEBUG) MESSAGE("VTKSelector::setSelection - DataOwner - "<<anIO->getEntry());
	    }
	  }
	  // To remove IOs, which is not selected.
	  QMap< QString, Handle( SALOME_InteractiveObject )> toRemove;
	  SALOME_ListIteratorOfListIO anIt( aStoredList );
	  for( ; anIt.More(); anIt.Next() )
	    if( !anIt.Value().IsNull() )
	      toRemove[ anIt.Value()->getEntry() ] = anIt.Value();

	  anIt = SALOME_ListIteratorOfListIO(anAppendList);
	  for( ; anIt.More(); anIt.Next() )
	    toRemove.remove( anIt.Value()->getEntry() );

	  QMap< QString, Handle( SALOME_InteractiveObject )>::const_iterator RIt = toRemove.begin(),
	                                                                     REnd = toRemove.end();
	  for( ; RIt!=REnd; RIt++ )
	    aSelector->RemoveIObject( RIt.data() );

	  aView->onSelectionChanged();
	}
      }
    }
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "browser/devtools_ui.h"

#include <string>

#include "browser/browser_context.h"

#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "ui/base/resource/resource_bundle.h"

using content::WebContents;

namespace brightray {

namespace {

const char kChromeUIDevToolsBundledHost[] = "devtools";

std::string PathWithoutParams(const std::string& path) {
  return GURL(std::string("chrome-devtools://devtools/") + path)
      .path().substr(1);
}

std::string GetMimeTypeForPath(const std::string& path) {
  std::string filename = PathWithoutParams(path);
  if (EndsWith(filename, ".html", false)) {
    return "text/html";
  } else if (EndsWith(filename, ".css", false)) {
    return "text/css";
  } else if (EndsWith(filename, ".js", false)) {
    return "application/javascript";
  } else if (EndsWith(filename, ".png", false)) {
    return "image/png";
  } else if (EndsWith(filename, ".gif", false)) {
    return "image/gif";
  } else if (EndsWith(filename, ".svg", false)) {
    return "image/svg+xml";
  } else if (EndsWith(filename, ".manifest", false)) {
    return "text/cache-manifest";
  }
  return "text/html";
}

class BundledDataSource : public content::URLDataSource {
 public:
  BundledDataSource() {}

  // content::URLDataSource implementation.
  std::string GetSource() const override {
    return kChromeUIDevToolsBundledHost;
  }

  void StartDataRequest(const std::string& path,
                        int render_process_id,
                        int render_view_id,
                        const GotDataCallback& callback) override {
    std::string filename = PathWithoutParams(path);

    int resource_id =
        content::DevToolsHttpHandler::GetFrontendResourceId(filename);

    DLOG_IF(WARNING, resource_id == -1)
        << "Unable to find dev tool resource: " << filename
        << ". If you compiled with debug_devtools=1, try running with "
           "--debug-devtools.";
    const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    scoped_refptr<base::RefCountedStaticMemory> bytes(rb.LoadDataResourceBytes(
        resource_id));
    callback.Run(bytes.get());
  }

  std::string GetMimeType(const std::string& path) const override {
    return GetMimeTypeForPath(path);
  }

  bool ShouldAddContentSecurityPolicy() const override {
    return false;
  }

  bool ShouldDenyXFrameOptions() const override {
    return false;
  }

  bool ShouldServeMimeTypeAsContentTypeHeader() const override {
    return true;
  }

 private:
  virtual ~BundledDataSource() {}
  DISALLOW_COPY_AND_ASSIGN(BundledDataSource);
};

}  // namespace

DevToolsUI::DevToolsUI(BrowserContext* browser_context, content::WebUI* web_ui)
    : WebUIController(web_ui) {
  web_ui->SetBindings(0);
  content::URLDataSource::Add(browser_context, new BundledDataSource());
}

}  // namespace brightray
<commit_msg>DevToolsHttpHandler::GetFrontendResourceId is removed.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-CHROMIUM file.

#include "browser/devtools_ui.h"

#include <string>

#include "browser/browser_context.h"

#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/devtools_frontend_host.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"

using content::WebContents;

namespace brightray {

namespace {

const char kChromeUIDevToolsBundledHost[] = "devtools";

std::string PathWithoutParams(const std::string& path) {
  return GURL(std::string("chrome-devtools://devtools/") + path)
      .path().substr(1);
}

std::string GetMimeTypeForPath(const std::string& path) {
  std::string filename = PathWithoutParams(path);
  if (EndsWith(filename, ".html", false)) {
    return "text/html";
  } else if (EndsWith(filename, ".css", false)) {
    return "text/css";
  } else if (EndsWith(filename, ".js", false)) {
    return "application/javascript";
  } else if (EndsWith(filename, ".png", false)) {
    return "image/png";
  } else if (EndsWith(filename, ".gif", false)) {
    return "image/gif";
  } else if (EndsWith(filename, ".svg", false)) {
    return "image/svg+xml";
  } else if (EndsWith(filename, ".manifest", false)) {
    return "text/cache-manifest";
  }
  return "text/html";
}

class BundledDataSource : public content::URLDataSource {
 public:
  BundledDataSource() {}

  // content::URLDataSource implementation.
  std::string GetSource() const override {
    return kChromeUIDevToolsBundledHost;
  }

  void StartDataRequest(const std::string& path,
                        int render_process_id,
                        int render_view_id,
                        const GotDataCallback& callback) override {
    std::string filename = PathWithoutParams(path);
    base::StringPiece resource =
      content::DevToolsFrontendHost::GetFrontendResource(filename);
    scoped_refptr<base::RefCountedStaticMemory> bytes(
        new base::RefCountedStaticMemory(resource.data(), resource.length()));
    callback.Run(bytes.get());
  }

  std::string GetMimeType(const std::string& path) const override {
    return GetMimeTypeForPath(path);
  }

  bool ShouldAddContentSecurityPolicy() const override {
    return false;
  }

  bool ShouldDenyXFrameOptions() const override {
    return false;
  }

  bool ShouldServeMimeTypeAsContentTypeHeader() const override {
    return true;
  }

 private:
  virtual ~BundledDataSource() {}
  DISALLOW_COPY_AND_ASSIGN(BundledDataSource);
};

}  // namespace

DevToolsUI::DevToolsUI(BrowserContext* browser_context, content::WebUI* web_ui)
    : WebUIController(web_ui) {
  web_ui->SetBindings(0);
  content::URLDataSource::Add(browser_context, new BundledDataSource());
}

}  // namespace brightray
<|endoftext|>


<commit_before>// Copyright (c) 2017 Pierre Fourgeaud
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <bandit/bandit.h>
#include "core/math/vector2.h"

using namespace bandit;
using namespace snowhouse;
using namespace CodeHero;

go_bandit([]() {
    describe("Vector2", []() {
        describe("Constructor", []() {
            it("should initialize vector with 0s if no arguments", [] {
                Vector2 test;

                AssertThat(test.x(), Equals(0.0f));
            });

            it("should initialize vector with correct x and y if provided", [] {
                float x = 1.5f;
                float y = 1.5f;
                Vector2 test(x, y);

                AssertThat(test.x(), Equals(x));
                AssertThat(test.y(), Equals(y));
            });
        });

        describe("::Length", [] {
            it("should compute the proper length", [] {
                float x = 2.0f;
                float y = 2.0f;
                Vector2 test(x, y);

                float res = 2.8284271247461903f;
                AssertThat(test.Length(), Equals(res));
            });
        });

        describe("::Normalize", [] {
            it("should compute the normalized vector", [] {
                Vector2 test(1.0f, 1.0f);

                float res = 0.70710678118f;
                test.Normalize();
                AssertThat(test.x(), Equals(res));
                AssertThat(test.y(), Equals(res));
            });
        });
    });
});<commit_msg>Fix incomplete test<commit_after>// Copyright (c) 2017 Pierre Fourgeaud
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <bandit/bandit.h>
#include "core/math/vector2.h"

using namespace bandit;
using namespace snowhouse;
using namespace CodeHero;

go_bandit([]() {
    describe("Vector2", []() {
        describe("Constructor", []() {
            it("should initialize vector with 0s if no arguments", [] {
                Vector2 test;

                AssertThat(test.x(), Equals(0.0f));
                AssertThat(test.y(), Equals(0.0f));
            });

            it("should initialize vector with correct x and y if provided", [] {
                float x = 1.5f;
                float y = 1.5f;
                Vector2 test(x, y);

                AssertThat(test.x(), Equals(x));
                AssertThat(test.y(), Equals(y));
            });
        });

        describe("::Length", [] {
            it("should compute the proper length", [] {
                float x = 2.0f;
                float y = 2.0f;
                Vector2 test(x, y);

                float res = 2.8284271247461903f;
                AssertThat(test.Length(), Equals(res));
            });
        });

        describe("::Normalize", [] {
            it("should compute the normalized vector", [] {
                Vector2 test(1.0f, 1.0f);

                float res = 0.70710678118f;
                test.Normalize();
                AssertThat(test.x(), Equals(res));
                AssertThat(test.y(), Equals(res));
            });
        });
    });
});<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdlib.h>
#include <string.h>

#include "content/public/app/content_main.h"

namespace node {
int Start(int argc, char *argv[]);
}

#if defined(OS_WIN)

#include <windows.h>  // NOLINT
#include <shellapi.h>  // NOLINT

#include "app/atom_main_delegate.h"
#include "content/public/app/startup_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"

int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
  int argc = 0;
  wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
  char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
  if (node_indicator != NULL && strcmp(node_indicator, "1") == 0)
    // Convert argv to to UTF8
    char** argv = new char*[argc];
    for (int i = 0; i < argc; i++) {
      // Compute the size of the required buffer
      DWORD size = WideCharToMultiByte(CP_UTF8,
                                       0,
                                       wargv[i],
                                       -1,
                                       NULL,
                                       0,
                                       NULL,
                                       NULL);
      if (size == 0) {
        // This should never happen.
        fprintf(stderr, "Could not convert arguments to utf8.");
        exit(1);
      }
      // Do the actual conversion
      argv[i] = new char[size];
      DWORD result = WideCharToMultiByte(CP_UTF8,
                                         0,
                                         wargv[i],
                                         -1,
                                         argv[i],
                                         size,
                                         NULL,
                                         NULL);
      if (result == 0) {
        // This should never happen.
        fprintf(stderr, "Could not convert arguments to utf8.");
        exit(1);
      }
    }
    // Now that conversion is done, we can finally start.
    return node::Start(argc, argv);
  }

  sandbox::SandboxInterfaceInfo sandbox_info = {0};
  content::InitializeSandboxInfo(&sandbox_info);
  atom::AtomMainDelegate delegate;
  return content::ContentMain(instance, &sandbox_info, &delegate);
}

#else  // defined(OS_WIN)

#include "app/atom_library_main.h"

int main(int argc, const char* argv[]) {
  char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
  if (node_indicator != NULL && strcmp(node_indicator, "1") == 0)
    return node::Start(argc, const_cast<char**>(argv));

  return AtomMain(argc, argv);
}

#endif
<commit_msg>Use base::Environment to replace getenv.<commit_after>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdlib.h>
#include <string.h>

#include "content/public/app/content_main.h"

namespace node {
int Start(int argc, char *argv[]);
}

#if defined(OS_WIN)

#include <windows.h>  // NOLINT
#include <shellapi.h>  // NOLINT

#include "app/atom_main_delegate.h"
#include "base/environment.h"
#include "content/public/app/startup_helper_win.h"
#include "sandbox/win/src/sandbox_types.h"

int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
  int argc = 0;
  wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);

  scoped_ptr<base::Environment> env(base::Environment::Create());
  std::string node_indicator;
  if (env->GetVar("ATOM_SHELL_INTERNAL_RUN_AS_NODE", &node_indicator) &&
      node_indicator == "1") {
    // Convert argv to to UTF8
    char** argv = new char*[argc];
    for (int i = 0; i < argc; i++) {
      // Compute the size of the required buffer
      DWORD size = WideCharToMultiByte(CP_UTF8,
                                       0,
                                       wargv[i],
                                       -1,
                                       NULL,
                                       0,
                                       NULL,
                                       NULL);
      if (size == 0) {
        // This should never happen.
        fprintf(stderr, "Could not convert arguments to utf8.");
        exit(1);
      }
      // Do the actual conversion
      argv[i] = new char[size];
      DWORD result = WideCharToMultiByte(CP_UTF8,
                                         0,
                                         wargv[i],
                                         -1,
                                         argv[i],
                                         size,
                                         NULL,
                                         NULL);
      if (result == 0) {
        // This should never happen.
        fprintf(stderr, "Could not convert arguments to utf8.");
        exit(1);
      }
    }
    // Now that conversion is done, we can finally start.
    return node::Start(argc, argv);
  }

  sandbox::SandboxInterfaceInfo sandbox_info = {0};
  content::InitializeSandboxInfo(&sandbox_info);
  atom::AtomMainDelegate delegate;
  return content::ContentMain(instance, &sandbox_info, &delegate);
}

#else  // defined(OS_WIN)

#include "app/atom_library_main.h"

int main(int argc, const char* argv[]) {
  char* node_indicator = getenv("ATOM_SHELL_INTERNAL_RUN_AS_NODE");
  if (node_indicator != NULL && strcmp(node_indicator, "1") == 0)
    return node::Start(argc, const_cast<char**>(argv));

  return AtomMain(argc, argv);
}

#endif
<|endoftext|>


<commit_before>#include <iostream>

int main()
{
    std::string number;
    std::cin >> number;

    bool isPalindrome = true;

    int l = number.length();

    for (int i = 0; i < l; ++i)
    {
        int digit = number[i];
        int digitFromEnd = number[l - i - 1];

        isPalindrome = (digit == digitFromEnd) && isPalindrome;
    }

    std::cout << (isPalindrome ? "Number is palindrome" : "Number is NOT palindrome") << std::endl;
}
<commit_msg>is_palindrome algorithm now stops at first not equal digit<commit_after>#include <iostream>

int main()
{
    std::string number;
    std::cin >> number;

    bool isPalindrome = true;

    int l = number.length();

    for (int i = 0; i < l; ++i)
    {
        int digit = number[i];
        int digitFromEnd = number[l - i - 1];

        isPalindrome = (digit == digitFromEnd) && isPalindrome;

        if (!isPalindrome)
            break;
    }

    std::cout << (isPalindrome ? "Number is palindrome" : "Number is NOT palindrome") << std::endl;
}
<|endoftext|>


<commit_before>#include <atomic>
#include <thread>
#include <cassert>
namespace example_01 {  // acquire-release and relaxed orederings

std::atomic<int> data[5];
std::atomic<int> sync{0};

void thread_1() {
    data[0].store(42, std::memory_order_relaxed);
    data[1].store(97, std::memory_order_relaxed);
    data[2].store(17, std::memory_order_relaxed);
    data[3].store(-141, std::memory_order_relaxed);
    data[4].store(2003, std::memory_order_relaxed);
    sync.store(1, std::memory_order_release);
}

void thread_2() {
    int expected{1};
    while (not sync.compare_exchange_strong(expected, 2, std::memory_order_acq_rel))
        expected = 1;
}

void thread_3() {
    while (sync.load(std::memory_order_acquire) < 2);
    assert(42 == data[0].load(std::memory_order_relaxed));
    assert(97 == data[1].load(std::memory_order_relaxed));
    assert(17 == data[2].load(std::memory_order_relaxed));
    assert(-141 == data[3].load(std::memory_order_relaxed));
    assert(2003 == data[4].load(std::memory_order_relaxed));
}

void run() {
    std::thread t1{ thread_1 }, t2{ thread_2 }, t3{ thread_3 };
    t1.join(); t2.join(); t3.join();
}

} // example_01

#include <iostream>
int main() {
    std::cout << "example_01 => [OK]"; example_01::run(); std::cout << std::endl << std::endl;

    return 0;
}
<commit_msg>[a_williams-cpp_concurrency_in_action-2-ed][05] change the 13-th example<commit_after>#include <atomic>
#include <thread>
#include <cassert>
namespace example_01 { // transitive sync with acquire-release ordering

std::atomic<int> data[5];
std::atomic<int> sync{0};

void thread_1() {
    data[0].store(42, std::memory_order_relaxed);
    data[1].store(97, std::memory_order_relaxed);
    data[2].store(17, std::memory_order_relaxed);
    data[3].store(-141, std::memory_order_relaxed);
    data[4].store(2003, std::memory_order_relaxed);
    sync.store(1, std::memory_order_release);
}

void thread_2() {
    int expected{1};
    while (not sync.compare_exchange_strong(expected, 2, std::memory_order_acq_rel))
        expected = 1;
}

void thread_3() {
    while (sync.load(std::memory_order_acquire) < 2);
    assert(42 == data[0].load(std::memory_order_relaxed));
    assert(97 == data[1].load(std::memory_order_relaxed));
    assert(17 == data[2].load(std::memory_order_relaxed));
    assert(-141 == data[3].load(std::memory_order_relaxed));
    assert(2003 == data[4].load(std::memory_order_relaxed));
}

void run() {
    std::thread t1{ thread_1 }, t2{ thread_2 }, t3{ thread_3 };
    t1.join(), t2.join(), t3.join();
}
} // example_01

#include <iostream>
int main() {
    std::cout << "[ok] - example_01" << std::endl; example_01::run(); std::cout << std::endl;

    return 0;
}
<|endoftext|>