<commit_before>#include <Poco/AutoPtr.h>

#include <gtest/gtest.h>
#include <exception>
#include <iostream>
#include <string>
#include <strstream>

#include "db.h"

#ifdef ENABLE_SQLITE3

extern "C" {
    extern DB::Connection *create_sqlite3_connection(void);
};

class SqliteInvalidTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open(".", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteInvalidTest, CannotConnectToDatabase) {
    ASSERT_EQ(connection->isConnected(), false);
}

class SqliteDefaultTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteDefaultTest, CanConnectToDatabase) {
    EXPECT_EQ(connection->isConnected(), true);
}

TEST_F(SqliteDefaultTest, CanExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP, updatedOn TIMESTAMP)"), true);
    EXPECT_EQ(connection->execute("DROP TABLE testing"), true);
}

TEST_F(SqliteDefaultTest, CannotExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("BYE"), false);
}

TEST_F(SqliteDefaultTest, EscapeCharacters) {
    EXPECT_STREQ(connection->escape("be'nden"), "'be''nden'");
}

TEST_F(SqliteDefaultTest, UnixTimeToSQL) {
    const char *t = connection->unixtimeToSql((time_t) 1414965631);
    EXPECT_STREQ(t, "'2014-11-02 22:00:31'");
}

TEST_F(SqliteDefaultTest, ErrorNumberAndMessage) {
    EXPECT_EQ(connection->errorno(), 0);
    EXPECT_STREQ(connection->errormsg(), "not an error");
}

TEST_F(SqliteDefaultTest, VersionString) {
    const char *v = connection->version();
    bool correct = false;
    if (strstr(v, "Sqlite3 Driver v0.2")) {
        correct = true;
    }
    EXPECT_EQ(correct, true);
}

class SqliteTransactionTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
            EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updatedOn TIMESTAMP)"), true);
            connection->beginTrans();
        }

        virtual void TearDown() {
            connection->commitTrans();
            connection->execute("DROP TABLE testing");
            connection->close();
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteTransactionTest, SingleInsert) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
}

TEST_F(SqliteTransactionTest, SingleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
    EXPECT_EQ(connection->commitTrans(), true);

    DB::ResultSet *rs = connection->executeQuery("SELECT * FROM testing;");
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 42);
    EXPECT_EQ(rs->getFloat(3), 42.0f);
    EXPECT_EQ(rs->getDouble(3), 42.0F);
    EXPECT_EQ(rs->getLong(3), 42l);
    EXPECT_EQ(rs->getBool(3), false);
    EXPECT_EQ(rs->getShort(3), (short) 42);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    EXPECT_EQ(rs->recordCount(), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, DoubleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->commitTrans(), true);

    DB::ResultSet *rs = connection->executeQuery("SELECT * FROM testing");
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 1);
    EXPECT_EQ(rs->getFloat(3), 1.0f);
    EXPECT_EQ(rs->getDouble(3), 1.0F);
    EXPECT_EQ(rs->getLong(3), 1l);
    EXPECT_EQ(rs->getBool(3), true);
    EXPECT_EQ(rs->getShort(3), (short) 1);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, QueryString) {
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::READ_UNCOMMITTED), true);
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::READ_COMMITTED), true);
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::REPEATABLE_READ), true);
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::SERIALIZABLE), true);

    EXPECT_EQ(connection->beginTrans(), false);

    DB::Query q(*connection);
    q << "INSERT INTO testing (text,fl) VALUES (" << DB::qstr("benden");
    q << "," << 42.0f << ");";
    EXPECT_EQ(connection->execute(q.str()), true);
    std::cout << q.str() << std::endl;
    std::cout << connection->errormsg() << std::endl;
    unsigned long id = connection->insertId();
    EXPECT_EQ(id, 1);
    EXPECT_EQ(connection->commitTrans(), true);
}

TEST_F(SqliteTransactionTest, RollbackTransaction) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text) VALUES ('benden');"), true);
    EXPECT_EQ(connection->rollbackTrans(), true);
}

TEST_F(SqliteTransactionTest, QueryStringTypes) {
    DB::Query q(*connection);

    q << "INSERT INTO test (text,fl,updatedOn) VALUES (";
    q << DB::qstr("benden") << "," << 42l << "," << DB::unixtime(time(NULL)) << ");";
    EXPECT_EQ(strlen(q.str()), 80);
}

TEST_F(SqliteTransactionTest, QueryStringTypes2) {
    DB::Query q(*connection);
    std::stringstream world;
    world << " World" << std::ends;

    q << std::string("Hello") << world;

    EXPECT_EQ(strlen(q.str()), 11);
}

TEST_F(SqliteTransactionTest, QueryNumberTypes) {
    DB::Query q(*connection);
    double d = 42.2;
    short s = 42;
    unsigned short su = 42;

    q << 42 << " " << d << " " << s << (const unsigned char *) " ";
    q << 42u << " " << 42ul << " " << su;
}

#endif

<commit_msg>Fixed schema for older sqlite3.<commit_after>#include <Poco/AutoPtr.h>

#include <gtest/gtest.h>
#include <exception>
#include <iostream>
#include <string>
#include <strstream>

#include "db.h"

#ifdef ENABLE_SQLITE3

extern "C" {
    extern DB::Connection *create_sqlite3_connection(void);
};

class SqliteInvalidTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open(".", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteInvalidTest, CannotConnectToDatabase) {
    ASSERT_EQ(connection->isConnected(), false);
}

class SqliteDefaultTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
        }

        virtual void TearDown() {
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteDefaultTest, CanConnectToDatabase) {
    EXPECT_EQ(connection->isConnected(), true);
}

TEST_F(SqliteDefaultTest, CanExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP, updatedOn TIMESTAMP)"), true);
    EXPECT_EQ(connection->execute("DROP TABLE testing"), true);
}

TEST_F(SqliteDefaultTest, CannotExecuteSimpleQuery) {
    EXPECT_EQ(connection->execute("BYE"), false);
}

TEST_F(SqliteDefaultTest, EscapeCharacters) {
    EXPECT_STREQ(connection->escape("be'nden"), "'be''nden'");
}

TEST_F(SqliteDefaultTest, UnixTimeToSQL) {
    const char *t = connection->unixtimeToSql((time_t) 1414965631);
    EXPECT_STREQ(t, "'2014-11-02 22:00:31'");
}

TEST_F(SqliteDefaultTest, ErrorNumberAndMessage) {
    EXPECT_EQ(connection->errorno(), 0);
    EXPECT_STREQ(connection->errormsg(), "not an error");
}

TEST_F(SqliteDefaultTest, VersionString) {
    const char *v = connection->version();
    bool correct = false;
    if (strstr(v, "Sqlite3 Driver v0.2")) {
        correct = true;
    }
    EXPECT_EQ(correct, true);
}

class SqliteTransactionTest : public ::testing::Test {
    protected:
        virtual void SetUp() {
            connection = create_sqlite3_connection();
            connection->open("test.db", NULL, 0, NULL, NULL);
            EXPECT_EQ(connection->execute("CREATE TABLE testing (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, text VARCHAR(128), num INTEGER, fl FLOAT, createdOn TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updatedOn TIMESTAMP)"), true);
            connection->beginTrans();
        }

        virtual void TearDown() {
            connection->commitTrans();
            connection->execute("DROP TABLE testing");
            connection->close();
            connection->release();
        }

        Poco::AutoPtr <DB::Connection> connection;
};

TEST_F(SqliteTransactionTest, SingleInsert) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
}

TEST_F(SqliteTransactionTest, SingleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42)"), true);
    EXPECT_EQ(connection->commitTrans(), true);

    DB::ResultSet *rs = connection->executeQuery("SELECT * FROM testing;");
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 42);
    EXPECT_EQ(rs->getFloat(3), 42.0f);
    EXPECT_EQ(rs->getDouble(3), 42.0F);
    EXPECT_EQ(rs->getLong(3), 42l);
    EXPECT_EQ(rs->getBool(3), false);
    EXPECT_EQ(rs->getShort(3), (short) 42);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    EXPECT_EQ(rs->recordCount(), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, DoubleSelect) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',1)"), true);
    EXPECT_EQ(connection->commitTrans(), true);

    DB::ResultSet *rs = connection->executeQuery("SELECT * FROM testing");
    EXPECT_NE(rs, (DB::ResultSet *) NULL);
    if (rs) {
    rs->next();
    EXPECT_EQ(rs->findColumn("text"), 1);
    EXPECT_STREQ(rs->getString(1), "benden");
    EXPECT_EQ(rs->findColumn("fl"), 3);
    EXPECT_EQ(rs->findColumn("r"), 6);
    EXPECT_EQ(rs->getInteger(3), 1);
    EXPECT_EQ(rs->getFloat(3), 1.0f);
    EXPECT_EQ(rs->getDouble(3), 1.0F);
    EXPECT_EQ(rs->getLong(3), 1l);
    EXPECT_EQ(rs->getBool(3), true);
    EXPECT_EQ(rs->getShort(3), (short) 1);
    EXPECT_NE(rs->getUnixTime(4), -1);
    EXPECT_EQ(rs->getUnixTime(5), 0);
    rs->close();
    }
}

TEST_F(SqliteTransactionTest, QueryString) {
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::READ_UNCOMMITTED), true);
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::READ_COMMITTED), true);
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::REPEATABLE_READ), true);
    EXPECT_EQ(connection->setTransactionMode(DB::Connection::SERIALIZABLE), true);

    EXPECT_EQ(connection->beginTrans(), false);

    DB::Query q(*connection);
    q << "INSERT INTO testing (text,fl) VALUES (" << DB::qstr("benden");
    q << "," << 42.0f << ");";
    EXPECT_EQ(connection->execute("INSERT INTO testing (text,fl) VALUES ('benden',42.0);"), true);
    std::cout << q.str() << std::endl;
    std::cout << connection->errormsg() << std::endl;
    unsigned long id = connection->insertId();
    EXPECT_EQ(id, 1);
    EXPECT_EQ(connection->commitTrans(), true);
}

TEST_F(SqliteTransactionTest, RollbackTransaction) {
    EXPECT_EQ(connection->execute("INSERT INTO testing (text) VALUES ('benden');"), true);
    EXPECT_EQ(connection->rollbackTrans(), true);
}

TEST_F(SqliteTransactionTest, QueryStringTypes) {
    DB::Query q(*connection);

    q << "INSERT INTO test (text,fl,updatedOn) VALUES (";
    q << DB::qstr("benden") << "," << 42l << "," << DB::unixtime(time(NULL)) << ");";
    EXPECT_EQ(strlen(q.str()), 80);
}

TEST_F(SqliteTransactionTest, QueryStringTypes2) {
    DB::Query q(*connection);
    std::stringstream world;
    world << " World" << std::ends;

    q << std::string("Hello") << world;

    EXPECT_EQ(strlen(q.str()), 11);
}

TEST_F(SqliteTransactionTest, QueryNumberTypes) {
    DB::Query q(*connection);
    double d = 42.2;
    short s = 42;
    unsigned short su = 42;

    q << 42 << " " << d << " " << s << (const unsigned char *) " ";
    q << 42u << " " << 42ul << " " << su;
}

#endif

<|endoftext|>


<commit_before>//
// Created by Mike on 5/17/2017.
//
#include "bitmap.h"
#include "integral_image.h"

#include <algorithm>
#include <iostream>

using namespace mcg;

int main()
{
    const int size = 100;
    bitmap bm(size, size);
    bm.m_data.resize(size*size);
    std::fill(bm.m_data.begin(), bm.m_data.end(), 128);
    integral_image ii(bm);
    std::cout << ii.at(0, 0) << "\n"
              << ii.at(0, size - 1) << "\n"
              << ii.at(size - 1, 0) << "\n"
              << ii.at(size - 1, size - 1);
    return 0;
}<commit_msg>Make fun test runner<commit_after>//
// Created by Mike on 5/17/2017.
//
#include "bitmap.h"
#include "integral_image.h"

#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>

using namespace mcg;

template <typename func_t>
void test_runner(std::string&& m_name, func_t&& m_func)
{
    std::cout << "Running " << m_name << "...\n";
    m_func();
    std::cout << "Finished " << m_name << ".\n";
}

#define MCG_RUN_TEST(test_name) \
    test_runner(#test_name, test_name);

void test_integral_image()
{
    const int size = 100;
    bitmap bm(size, size);
    bm.m_data.resize(size*size);
    std::fill(bm.m_data.begin(), bm.m_data.end(), 128);
    integral_image ii(bm);
    assert(ii.at(0, 0)               == 128 * 1);
    assert(ii.at(0, size - 1)        == 128 * size);
    assert(ii.at(size - 1, 0)        == 128 * size);
    assert(ii.at(size - 1, size - 1) == 128 * size * size);
    assert(ii.at(10, 23)             == 128 * 11 * 24);
}

int main()
{
    MCG_RUN_TEST(test_integral_image);
    return 0;
}<|endoftext|>


<commit_before>/**
 * Copyright © 2019 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "data_interface.hpp"
#include "elog_entry.hpp"
#include "event_logger.hpp"
#include "extensions.hpp"
#include "manager.hpp"
#include "pldm_interface.hpp"

namespace openpower
{
namespace pels
{

using namespace phosphor::logging;

std::unique_ptr<Manager> manager;

void pelStartup(internal::Manager& logManager)
{
    EventLogger::LogFunction logger = std::bind(
        std::mem_fn(&internal::Manager::create), &logManager,
        std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);

    std::unique_ptr<DataInterfaceBase> dataIface =
        std::make_unique<DataInterface>(logManager.getBus());

#ifndef DONT_SEND_PELS_TO_HOST
    std::unique_ptr<HostInterface> hostIface = std::make_unique<PLDMInterface>(
        logManager.getBus().get_event(), *(dataIface.get()));

    manager =
        std::make_unique<Manager>(logManager, std::move(dataIface),
                                  std::move(logger), std::move(hostIface));
#else
    manager = std::make_unique<Manager>(logManager, std::move(dataIface),
                                        std::move(logger));
#endif
}

REGISTER_EXTENSION_FUNCTION(pelStartup);

void pelCreate(const std::string& message, uint32_t id, uint64_t timestamp,
               Entry::Level severity, const AdditionalDataArg& additionalData,
               const AssociationEndpointsArg& assocs, const FFDCArg& ffdc)
{
    manager->create(message, id, timestamp, severity, additionalData, assocs,
                    ffdc);
}

REGISTER_EXTENSION_FUNCTION(pelCreate);

void pelDelete(uint32_t id)
{
    return manager->erase(id);
}

REGISTER_EXTENSION_FUNCTION(pelDelete);

void pelDeleteProhibited(uint32_t id, bool& prohibited)
{
    prohibited = manager->isDeleteProhibited(id);
}

REGISTER_EXTENSION_FUNCTION(pelDeleteProhibited);

} // namespace pels
} // namespace openpower
<commit_msg>PEL: Disable the default log entry capping<commit_after>/**
 * Copyright © 2019 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "data_interface.hpp"
#include "elog_entry.hpp"
#include "event_logger.hpp"
#include "extensions.hpp"
#include "manager.hpp"
#include "pldm_interface.hpp"

namespace openpower
{
namespace pels
{

using namespace phosphor::logging;

std::unique_ptr<Manager> manager;

DISABLE_LOG_ENTRY_CAPS();

void pelStartup(internal::Manager& logManager)
{
    EventLogger::LogFunction logger = std::bind(
        std::mem_fn(&internal::Manager::create), &logManager,
        std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);

    std::unique_ptr<DataInterfaceBase> dataIface =
        std::make_unique<DataInterface>(logManager.getBus());

#ifndef DONT_SEND_PELS_TO_HOST
    std::unique_ptr<HostInterface> hostIface = std::make_unique<PLDMInterface>(
        logManager.getBus().get_event(), *(dataIface.get()));

    manager =
        std::make_unique<Manager>(logManager, std::move(dataIface),
                                  std::move(logger), std::move(hostIface));
#else
    manager = std::make_unique<Manager>(logManager, std::move(dataIface),
                                        std::move(logger));
#endif
}

REGISTER_EXTENSION_FUNCTION(pelStartup);

void pelCreate(const std::string& message, uint32_t id, uint64_t timestamp,
               Entry::Level severity, const AdditionalDataArg& additionalData,
               const AssociationEndpointsArg& assocs, const FFDCArg& ffdc)
{
    manager->create(message, id, timestamp, severity, additionalData, assocs,
                    ffdc);
}

REGISTER_EXTENSION_FUNCTION(pelCreate);

void pelDelete(uint32_t id)
{
    return manager->erase(id);
}

REGISTER_EXTENSION_FUNCTION(pelDelete);

void pelDeleteProhibited(uint32_t id, bool& prohibited)
{
    prohibited = manager->isDeleteProhibited(id);
}

REGISTER_EXTENSION_FUNCTION(pelDeleteProhibited);

} // namespace pels
} // namespace openpower
<|endoftext|>


<commit_before>#ifndef PML_SPECIAL_H_
#define PML_SPECIAL_H_

#include "pml_vector.hpp"
#include "pml_matrix.hpp"

namespace pml{

  // ------- Log Gamma function -------
  double gammaln(double x){
    return std::lgamma(x);
  }

  inline Vector gammaln(const Vector &x){
    return apply(x, std::lgamma);
  }

  inline Matrix gammaln(const Matrix &m){
    return apply(m, std::lgamma);
  }

  // -------  Polygamma Function -------
  inline double psi(double d, int n = 0){
    return gsl_sf_psi_n(n, d);
  }

  inline Vector psi(const Vector &x, int n = 0){
    Vector y = x;
    for(auto &d : y)
      d = gsl_sf_psi_n(n, d);
    return y;
  }

  inline Matrix psi(const Matrix &x, int n = 0){
    Matrix y = x;
    for(auto &d : y)
      d = gsl_sf_psi_n(n, d);
    return y;
  }

  // Inverse Polygamma Function with Newton Method
  double inv_psi(double d){
    double x = d > -2.22 ? std::exp(d)+0.5 : -1/(d + 0.577215);
    // make 5 newton iterations
    for(int i=0; i < 5; ++i)
      x -= (psi(x)-d) / psi(x,1);
    return x;
  }

  inline Vector inv_psi(const Vector &v){
    return apply(v, inv_psi);
  }

  inline Matrix inv_psi(const Matrix  &m){
    return apply(m, inv_psi);
  }

} // namespace pml

#endif<commit_msg>check<commit_after>#ifndef PML_SPECIAL_H_
#define PML_SPECIAL_H_

#include "pml_vector.hpp"
#include "pml_matrix.hpp"

namespace pml{

  // ------- Log Gamma function -------
  double gammaln(double x){
    return std::lgamma(x);
  }

  inline Vector gammaln(const Vector &x){
    return apply(x, std::lgamma);
  }

  inline Matrix gammaln(const Matrix &m){
    return apply(m, std::lgamma);
  }

  // -------  Polygamma Function -------
  inline double psi(double d, int n = 0){
    if( d == 0){
      std::cout << "n is zero!!\n";
    }

    return gsl_sf_psi_n(n, d);
  }

  inline Vector psi(const Vector &x, int n = 0){
    Vector y = x;
    for(auto &d : y)
      d = gsl_sf_psi_n(n, d);
    return y;
  }

  inline Matrix psi(const Matrix &x, int n = 0){
    Matrix y = x;
    for(auto &d : y)
      d = gsl_sf_psi_n(n, d);
    return y;
  }

  // Inverse Polygamma Function with Newton Method
  double inv_psi(double d){
    double x = d > -2.22 ? std::exp(d)+0.5 : -1/(d + 0.577215);
    // make 5 newton iterations
    for(int i=0; i < 5; ++i)
      x -= (psi(x)-d) / psi(x,1);
    return x;
  }

  inline Vector inv_psi(const Vector &v){
    return apply(v, inv_psi);
  }

  inline Matrix inv_psi(const Matrix  &m){
    return apply(m, inv_psi);
  }

} // namespace pml

#endif<|endoftext|>


<commit_before>/**
 * @file Cosa/Power.cpp
 * @version 1.0
 *
 * @section License
 * Copyright (C) 2013, Mikael Patel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 *
 * This file is part of the Arduino Che Cosa project.
 */

#include "Cosa/Power.hh"

// Software disable low voltage detect (23 uA at 5 V)
// #define COSA_BOD_DISABLE

void
Power::sleep(uint8_t mode)
{
  set_sleep_mode(mode);
  sleep_enable();
#if defined(COSA_BOD_DISABLE)
  MCUCR = _BV(BODS) | _BV(BODSE);
  MCUCR = _BV(BODS);
#endif
  sleep_cpu();
  sleep_disable();
}

void
Power::clock_prescale(uint8_t factor)
{
  if (factor > 8) factor = 8;
  CLKPR = (1 << CLKPCE);
  CLKPR = factor;
}
<commit_msg>Fix possible synchronization error.<commit_after>/**
 * @file Cosa/Power.cpp
 * @version 1.0
 *
 * @section License
 * Copyright (C) 2013, Mikael Patel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 *
 * This file is part of the Arduino Che Cosa project.
 */

#include "Cosa/Power.hh"

// Software disable low voltage detect (23 uA at 5 V)
// #define COSA_BOD_DISABLE

void
Power::sleep(uint8_t mode)
{
  set_sleep_mode(mode);
  sleep_enable();
#if defined(COSA_BOD_DISABLE)
  MCUCR = _BV(BODS) | _BV(BODSE);
  MCUCR = _BV(BODS);
#endif
  sleep_cpu();
  sleep_disable();
}

void
Power::clock_prescale(uint8_t factor)
{
  if (factor > 8) factor = 8;
  synchronized {
    CLKPR = (1 << CLKPCE);
    CLKPR = factor;
  }
}
<|endoftext|>


<commit_before>/*
 * jcom.modular
 * External for Jamoma : to manage local and distant application
 *
 * By Theo de la Hogue, Copyright 2010
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "TTModularClassWrapperMax.h"

#define activity_out 0
#define config_out 1
#define dump_out 2

// Definitions
void	WrapTTApplicationManagerClass(WrappedClassPtr c);
void	WrappedApplicationManagerClass_new(TTPtr self, AtomCount argc, AtomPtr argv);

void	appmg_assist(TTPtr self, void *b, long msg, long arg, char *dst);

void	appmg_application_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_plugin_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);

void	appmg_read(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_doread(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_read_again(TTPtr self);
void	appmg_doread_again(TTPtr self);

void	appmg_write(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_dowrite(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_write_again(TTPtr self);
void	appmg_dowrite_again(TTPtr self);

void	appmg_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv);

int TTCLASSWRAPPERMAX_EXPORT main(void)
{
	ModularSpec *spec = new ModularSpec;
	spec->_wrap = &WrapTTApplicationManagerClass;
	spec->_new = &WrappedApplicationManagerClass_new;
	spec->_any = NULL;
	spec->_free = NULL;

	return wrapTTModularClassAsMaxClass(TT("ApplicationManager"), "jcom.modular", NULL, spec);
}

void WrapTTApplicationManagerClass(WrappedClassPtr c)
{
	class_addmethod(c->maxClass, (method)appmg_assist,						"assist",						A_CANT, 0L);

	class_addmethod(c->maxClass, (method)appmg_return_value,				"return_value",					A_CANT, 0);

	class_addmethod(c->maxClass, (method)appmg_application_configuration,	"application/configuration",	A_GIMME, 0);
	class_addmethod(c->maxClass, (method)appmg_plugin_configuration,		"plugin/configuration",			A_GIMME, 0);
	class_addmethod(c->maxClass, (method)appmg_configuration,				"configuration",				A_GIMME, 0);

	class_addmethod(c->maxClass, (method)appmg_read,						"read",							A_GIMME, 0);
	class_addmethod(c->maxClass, (method)appmg_write,						"write",						A_GIMME, 0);

	class_addmethod(c->maxClass, (method)appmg_read_again,					"read/again",					0);
	class_addmethod(c->maxClass, (method)appmg_write_again,					"write/again",					0);
}

void WrappedApplicationManagerClass_new(TTPtr self, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	SymbolPtr					localApplicationName = NULL;
	TTXmlHandlerPtr				aXmlHandler;
	TTValue						v, args;
 	long						attrstart = attr_args_offset(argc, argv);			// support normal arguments

	// optionnaly change the local application name (default : Jamoma)
	if (attrstart && argv)
		localApplicationName = atom_getsym(argv);

	// our wrapped object is the application manager
	x->wrappedObject = (TTObjectPtr)TTModularApplications;

	// change the local application name
	if (localApplicationName)
		x->wrappedObject->setAttributeValue(TT("applicationLocalName"), TT(localApplicationName->s_name));

	// Make two outlets
	x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 2);
	x->outlets[config_out] = outlet_new(x, NULL);					// anything outlet to output configuration
	x->outlets[activity_out] = outlet_new(x, NULL);					// anything outlet to output activity

	// Prepare Internals hash to store XmlHanler and TextHandler object
	x->internals = new TTHash();

	// create internal TTXmlHandler
	aXmlHandler = NULL;
	TTObjectInstantiate(TT("XmlHandler"), TTObjectHandle(&aXmlHandler), args);
	v = TTValue(TTPtr(aXmlHandler));
	x->internals->append(TT("XmlHandler"), v);
	v = TTValue(TTPtr(x->wrappedObject));
	aXmlHandler->setAttributeValue(kTTSym_object, v);

	attr_args_process(x, argc, argv);
}

// Method for Assistance Messages
void appmg_assist(TTPtr self, void *b, long msg, long arg, char *dst)
{
	if (msg==1) 						// Inlet
		strcpy(dst, "input");
	else {								// Outlets
		switch(arg) {
			case activity_out:
				strcpy(dst, "activity");
				break;
			case config_out:
				strcpy(dst, "configuration");
				break;
			case dump_out:
				strcpy(dst, "dumpout");
				break;
		}
 	}
}

void appmg_application_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTSymbolPtr			applicationName;
	TTApplicationPtr	anApplication;
	TTValue				v;
	AtomCount			ac = 0;
	AtomPtr				av = NULL;

	if (argc && argv) {

		if (atom_gettype(argv) == A_SYM) {

			applicationName = TT(atom_getsym(argv)->s_name);
			anApplication = TTApplicationManagerGetApplication(applicationName);

			if (anApplication) {
				anApplication->getAttributeValue(TT("pluginNames"), v);

				v.prepend(applicationName);
				jamoma_ttvalue_to_Atom(v, &ac, &av);
				outlet_anything(x->outlets[config_out], msg, ac, av);
			}
			else
				object_post((ObjectPtr)x, "%s is not an application", applicationName->getCString());
		}
	}
}

void appmg_plugin_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTSymbolPtr			pluginName;
	TTPluginHandlerPtr	aPlugin;
	TTValue				v;
	AtomCount			ac = 0;
	AtomPtr				av = NULL;

	if (argc && argv) {

		if (atom_gettype(argv) == A_SYM) {

			pluginName = TT(atom_getsym(argv)->s_name);
			aPlugin = TTApplicationManagerGetPlugin(pluginName);

			if (aPlugin) {
				aPlugin->getAttributeValue(TT("parameterNames"), v);

				v.prepend(pluginName);
				jamoma_ttvalue_to_Atom(v, &ac, &av);
				outlet_anything(x->outlets[config_out], msg, ac, av);
			}
			else
				object_post((ObjectPtr)x, "%s is not a plugin", pluginName->getCString());
		}
	}
}

void appmg_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTSymbolPtr			applicationName, pluginName, parameterName;
	TTApplicationPtr	anApplication;
	TTHashPtr			pluginParameters, parameters;
	TTValue				v;
	AtomCount			ac = 0;
	AtomPtr				av = NULL;
	TTErr				err;

	if (argc && argv) {

		if (atom_gettype(argv) == A_SYM) {
			applicationName = TT(atom_getsym(argv)->s_name);
			anApplication = TTApplicationManagerGetApplication(applicationName);

			if (anApplication) {
				anApplication->getAttributeValue(TT("pluginParameters"), v);
				v.get(0, (TTPtr*)&pluginParameters);

				if (atom_gettype(argv+1) == A_SYM) {
					pluginName = TT(atom_getsym(argv+1)->s_name);
					err = pluginParameters->lookup(pluginName, v);
					v.get(0, (TTPtr*)&parameters);

					if (!err && atom_gettype(argv+2) == A_SYM) {
						parameterName = TT(atom_getsym(argv+2)->s_name);
						err = parameters->lookup(parameterName, v);

						if (!err) {
							v.prepend(parameterName);
							v.prepend(pluginName);
							v.prepend(applicationName);
							jamoma_ttvalue_to_Atom(v, &ac, &av);
							outlet_anything(x->outlets[config_out], msg, ac, av);
						}
						else
							object_post((ObjectPtr)x, "%s is not a parameter of %s plugin", parameterName->getCString(), pluginName->getCString());
					}
					else
						object_post((ObjectPtr)x, "%s is not a plugin of %s application", pluginName->getCString(), applicationName->getCString());
				}
			}
			else
				object_post((ObjectPtr)x, "%s is not an application", applicationName->getCString());
		}
	}
}

void appmg_read(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	defer(self, (method)appmg_doread, msg, argc, argv);
}

void appmg_doread(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue			o, v;
	TTSymbolPtr		fullpath;
	TTXmlHandlerPtr	aXmlHandler = NULL;
	TTErr			tterr;

	if (x->wrappedObject) {

		fullpath = jamoma_file_read((ObjectPtr)x, argc, argv);
		v.append(fullpath);

		tterr = x->internals->lookup(TT("XmlHandler"), o);

		if (!tterr) {

			o.get(0, (TTPtr*)&aXmlHandler);

			critical_enter(0);
			aXmlHandler->sendMessage(TT("Read"), v);
			critical_exit(0);
		}
	}
}

void appmg_read_again(TTPtr self)
{
	defer(self, (method)appmg_doread_again, NULL, 0, NULL);
}

void appmg_doread_again(TTPtr self)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTXmlHandlerPtr	aXmlHandler = NULL;
	TTValue			o;
	TTErr			tterr;

	tterr = x->internals->lookup(TT("XmlHandler"), o);

	if (!tterr) {

		o.get(0, (TTPtr*)&aXmlHandler);

		critical_enter(0);
		aXmlHandler->sendMessage(TT("ReadAgain"));
		critical_exit(0);
	}
}

void appmg_write(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	defer(self, (method)appmg_dowrite, msg, argc, argv);
}

void appmg_dowrite(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	char 			filename[MAX_FILENAME_CHARS];
	TTSymbolPtr		fullpath;
	TTValue			o, v;
	TTXmlHandlerPtr	aXmlHandler;
	TTErr			tterr;

	if (x->wrappedObject) {

		// TODO : find a default XML File Name using the name of the patch
		snprintf(filename, MAX_FILENAME_CHARS, "ApplicationConfig.xml");
		fullpath = jamoma_file_write((ObjectPtr)x, argc, argv, filename);
		v.append(fullpath);

		tterr = x->internals->lookup(TT("XmlHandler"), o);

		if (!tterr) {
			o.get(0, (TTPtr*)&aXmlHandler);

			critical_enter(0);
			aXmlHandler->sendMessage(TT("Write"), v);
			critical_exit(0);
		}
	}
}

void appmg_write_again(TTPtr self)
{
	defer(self, (method)appmg_dowrite_again, NULL, 0, NULL);
}

void appmg_dowrite_again(TTPtr self)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTXmlHandlerPtr	aXmlHandler = NULL;
	TTValue			o;
	TTErr			tterr;

	tterr = x->internals->lookup(TT("XmlHandler"), o);

	if (!tterr) {

		o.get(0, (TTPtr*)&aXmlHandler);

		critical_enter(0);
		aXmlHandler->sendMessage(TT("WriteAgain"));
		critical_exit(0);
	}
}

void appmg_return_value(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	outlet_anything(x->outlets[activity_out], msg, argc, argv);
}<commit_msg>changing messages interface to configure the jcom.modular<commit_after>/*
 * jcom.modular
 * External for Jamoma : to manage local and distant application
 *
 * By Theo de la Hogue, Copyright 2010
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "TTModularClassWrapperMax.h"

#define activity_out 0
#define config_out 1
#define dump_out 2

// Definitions
void	WrapTTApplicationManagerClass(WrappedClassPtr c);
void	WrappedApplicationManagerClass_new(TTPtr self, AtomCount argc, AtomPtr argv);

void	appmg_assist(TTPtr self, void *b, long msg, long arg, char *dst);

void	appmg_application_plugins(TTPtr self, SymbolPtr msg);
void	appmg_plugin_parameters(TTPtr self, SymbolPtr msg);
void	appmg_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);

void	appmg_read(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_doread(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_read_again(TTPtr self);
void	appmg_doread_again(TTPtr self);

void	appmg_write(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_dowrite(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv);
void	appmg_write_again(TTPtr self);
void	appmg_dowrite_again(TTPtr self);

void	appmg_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv);

int TTCLASSWRAPPERMAX_EXPORT main(void)
{
	ModularSpec *spec = new ModularSpec;
	spec->_wrap = &WrapTTApplicationManagerClass;
	spec->_new = &WrappedApplicationManagerClass_new;
	spec->_any = NULL;
	spec->_free = NULL;

	return wrapTTModularClassAsMaxClass(TT("ApplicationManager"), "jcom.modular", NULL, spec);
}

void WrapTTApplicationManagerClass(WrappedClassPtr c)
{
	class_addmethod(c->maxClass, (method)appmg_assist,						"assist",						A_CANT, 0L);

	class_addmethod(c->maxClass, (method)appmg_return_value,				"return_value",					A_CANT, 0);

	class_addmethod(c->maxClass, (method)appmg_application_plugins,			"application/plugins",			A_SYM, 0);
	class_addmethod(c->maxClass, (method)appmg_plugin_parameters,			"plugin/parameters",			A_SYM, 0);
	class_addmethod(c->maxClass, (method)appmg_configuration,				"configuration",				A_GIMME, 0);

	class_addmethod(c->maxClass, (method)appmg_read,						"read",							A_GIMME, 0);
	class_addmethod(c->maxClass, (method)appmg_write,						"write",						A_GIMME, 0);

	class_addmethod(c->maxClass, (method)appmg_read_again,					"read/again",					0);
	class_addmethod(c->maxClass, (method)appmg_write_again,					"write/again",					0);
}

void WrappedApplicationManagerClass_new(TTPtr self, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	SymbolPtr					localApplicationName = NULL;
	TTXmlHandlerPtr				aXmlHandler;
	TTValue						v, args;
 	long						attrstart = attr_args_offset(argc, argv);			// support normal arguments

	// optionnaly change the local application name (default : Jamoma)
	if (attrstart && argv)
		localApplicationName = atom_getsym(argv);

	// our wrapped object is the application manager
	x->wrappedObject = (TTObjectPtr)TTModularApplications;

	// change the local application name
	if (localApplicationName)
		x->wrappedObject->setAttributeValue(TT("applicationLocalName"), TT(localApplicationName->s_name));

	// Make two outlets
	x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 2);
	x->outlets[config_out] = outlet_new(x, NULL);					// anything outlet to output configuration
	x->outlets[activity_out] = outlet_new(x, NULL);					// anything outlet to output activity

	// Prepare Internals hash to store XmlHanler and TextHandler object
	x->internals = new TTHash();

	// create internal TTXmlHandler
	aXmlHandler = NULL;
	TTObjectInstantiate(TT("XmlHandler"), TTObjectHandle(&aXmlHandler), args);
	v = TTValue(TTPtr(aXmlHandler));
	x->internals->append(TT("XmlHandler"), v);
	v = TTValue(TTPtr(x->wrappedObject));
	aXmlHandler->setAttributeValue(kTTSym_object, v);

	attr_args_process(x, argc, argv);
}

// Method for Assistance Messages
void appmg_assist(TTPtr self, void *b, long msg, long arg, char *dst)
{
	if (msg==1) 						// Inlet
		strcpy(dst, "input");
	else {								// Outlets
		switch(arg) {
			case activity_out:
				strcpy(dst, "activity");
				break;
			case config_out:
				strcpy(dst, "configuration");
				break;
			case dump_out:
				strcpy(dst, "dumpout");
				break;
		}
 	}
}

void appmg_application_plugins(TTPtr self, SymbolPtr msg)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTSymbolPtr			applicationName;
	TTApplicationPtr	anApplication;
	TTValue				v;
	AtomCount			ac = 0;
	AtomPtr				av = NULL;

	applicationName = TT(msg->s_name);
	anApplication = TTApplicationManagerGetApplication(applicationName);

	if (anApplication) {
		anApplication->getAttributeValue(TT("pluginNames"), v);

		v.prepend(applicationName);
		jamoma_ttvalue_to_Atom(v, &ac, &av);
		outlet_anything(x->outlets[config_out], msg, ac, av);
	}
	else
		object_post((ObjectPtr)x, "%s is not an application", applicationName->getCString());
}

void appmg_plugin_parameters(TTPtr self, SymbolPtr msg)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTSymbolPtr			pluginName;
	TTPluginHandlerPtr	aPlugin;
	TTValue				v;
	AtomCount			ac = 0;
	AtomPtr				av = NULL;

	pluginName = TT(msg->s_name);
	aPlugin = TTApplicationManagerGetPlugin(pluginName);

	if (aPlugin) {
		aPlugin->getAttributeValue(TT("parameterNames"), v);

		v.prepend(pluginName);
		jamoma_ttvalue_to_Atom(v, &ac, &av);
		outlet_anything(x->outlets[config_out], msg, ac, av);
	}
	else
		object_post((ObjectPtr)x, "%s is not a plugin", pluginName->getCString());
}

void appmg_configuration(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTSymbolPtr			applicationName, pluginName, parameterName;
	TTApplicationPtr	anApplication;
	TTHashPtr			pluginParameters, parameters;
	TTValue				v;
	AtomCount			ac = 0;
	AtomPtr				av = NULL;
	TTErr				err;

	if (argc && argv) {

		if (atom_gettype(argv) == A_SYM) {
			applicationName = TT(atom_getsym(argv)->s_name);
			anApplication = TTApplicationManagerGetApplication(applicationName);

			if (anApplication) {
				anApplication->getAttributeValue(TT("pluginParameters"), v);
				v.get(0, (TTPtr*)&pluginParameters);

				if (atom_gettype(argv+1) == A_SYM) {
					pluginName = TT(atom_getsym(argv+1)->s_name);
					err = pluginParameters->lookup(pluginName, v);
					v.get(0, (TTPtr*)&parameters);

					if (!err && atom_gettype(argv+2) == A_SYM) {
						parameterName = TT(atom_getsym(argv+2)->s_name);
						err = parameters->lookup(parameterName, v);

						if (!err) {
							v.prepend(parameterName);
							v.prepend(pluginName);
							v.prepend(applicationName);
							jamoma_ttvalue_to_Atom(v, &ac, &av);
							outlet_anything(x->outlets[config_out], msg, ac, av);
						}
						else
							object_post((ObjectPtr)x, "%s is not a parameter of %s plugin", parameterName->getCString(), pluginName->getCString());
					}
					else
						object_post((ObjectPtr)x, "%s is not a plugin of %s application", pluginName->getCString(), applicationName->getCString());
				}
			}
			else
				object_post((ObjectPtr)x, "%s is not an application", applicationName->getCString());
		}
	}
}

void appmg_read(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	defer(self, (method)appmg_doread, msg, argc, argv);
}

void appmg_doread(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTValue			o, v;
	TTSymbolPtr		fullpath;
	TTXmlHandlerPtr	aXmlHandler = NULL;
	TTErr			tterr;

	if (x->wrappedObject) {

		fullpath = jamoma_file_read((ObjectPtr)x, argc, argv);
		v.append(fullpath);

		tterr = x->internals->lookup(TT("XmlHandler"), o);

		if (!tterr) {

			o.get(0, (TTPtr*)&aXmlHandler);

			critical_enter(0);
			aXmlHandler->sendMessage(TT("Read"), v);
			critical_exit(0);
		}
	}
}

void appmg_read_again(TTPtr self)
{
	defer(self, (method)appmg_doread_again, NULL, 0, NULL);
}

void appmg_doread_again(TTPtr self)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTXmlHandlerPtr	aXmlHandler = NULL;
	TTValue			o;
	TTErr			tterr;

	tterr = x->internals->lookup(TT("XmlHandler"), o);

	if (!tterr) {

		o.get(0, (TTPtr*)&aXmlHandler);

		critical_enter(0);
		aXmlHandler->sendMessage(TT("ReadAgain"));
		critical_exit(0);
	}
}

void appmg_write(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	defer(self, (method)appmg_dowrite, msg, argc, argv);
}

void appmg_dowrite(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	char 			filename[MAX_FILENAME_CHARS];
	TTSymbolPtr		fullpath;
	TTValue			o, v;
	TTXmlHandlerPtr	aXmlHandler;
	TTErr			tterr;

	if (x->wrappedObject) {

		// TODO : find a default XML File Name using the name of the patch
		snprintf(filename, MAX_FILENAME_CHARS, "ApplicationConfig.xml");
		fullpath = jamoma_file_write((ObjectPtr)x, argc, argv, filename);
		v.append(fullpath);

		tterr = x->internals->lookup(TT("XmlHandler"), o);

		if (!tterr) {
			o.get(0, (TTPtr*)&aXmlHandler);

			critical_enter(0);
			aXmlHandler->sendMessage(TT("Write"), v);
			critical_exit(0);
		}
	}
}

void appmg_write_again(TTPtr self)
{
	defer(self, (method)appmg_dowrite_again, NULL, 0, NULL);
}

void appmg_dowrite_again(TTPtr self)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	TTXmlHandlerPtr	aXmlHandler = NULL;
	TTValue			o;
	TTErr			tterr;

	tterr = x->internals->lookup(TT("XmlHandler"), o);

	if (!tterr) {

		o.get(0, (TTPtr*)&aXmlHandler);

		critical_enter(0);
		aXmlHandler->sendMessage(TT("WriteAgain"));
		critical_exit(0);
	}
}

void appmg_return_value(TTPtr self, SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
	WrappedModularInstancePtr	x = (WrappedModularInstancePtr)self;
	outlet_anything(x->outlets[activity_out], msg, argc, argv);
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: canvasbitmaphelper.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-10 11:57:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _VCLCANVAS_CANVASBITMAPHELPER_HXX_
#define _VCLCANVAS_CANVASBITMAPHELPER_HXX_

#include <canvashelper.hxx>

#ifndef _SV_BITMAPEX_HXX
#include <vcl/bitmapex.hxx>
#endif

#include <canvas/vclwrapper.hxx>

#include "bitmapbackbuffer.hxx"

namespace vclcanvas
{
    /** Helper class for basic canvasbitmap functionality. Extends
        CanvasHelper with some CanvasBitmap specialities, such as alpha
        support.

        Note that a plain CanvasHelper, although it does support the
        XBitmap interface, has no provision for alpha channel on VCL
        (at least no efficient one. If the alpha VDev one day gets
        part of SAL, we might change that).
     */
    class CanvasBitmapHelper : public CanvasHelper
    {
    public:
        CanvasBitmapHelper();

        /** Set a new bitmap on this helper.

            This method force-sets a new bitmap. The internally stored
            bitmap representation is updated from the given bitmap,
            including any size changes.
         */
        void setBitmap( const BitmapEx&                     rBitmap,
                        const WindowGraphicDevice::ImplRef& rDevice );

        // Overridden CanvasHelper functionality
        // =====================================

        void disposing();

        ::com::sun::star::geometry::IntegerSize2D SAL_CALL getSize();

        ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > SAL_CALL queryBitmapCanvas();

        ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmap > SAL_CALL
            getScaledBitmap( const ::com::sun::star::geometry::RealSize2D&  newSize,
                             sal_Bool                                               beFast );

        ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
            getData( const ::com::sun::star::geometry::IntegerRectangle2D& rect );

        void SAL_CALL setData( const ::com::sun::star::uno::Sequence< sal_Int8 >&               data,
                               const ::com::sun::star::geometry::IntegerRectangle2D&    rect );

        void SAL_CALL setPixel( const ::com::sun::star::uno::Sequence< sal_Int8 >&          color,
                                const ::com::sun::star::geometry::IntegerPoint2D&   pos );

        ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
            getPixel( const ::com::sun::star::geometry::IntegerPoint2D& pos );

        ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapPalette > SAL_CALL getPalette();

        ::com::sun::star::rendering::IntegerBitmapLayout SAL_CALL getMemoryLayout();

        /// @internal
        BitmapEx getBitmap() const;

    private:
        // default: disabled copy/assignment
        CanvasBitmapHelper(const CanvasBitmapHelper&);
        CanvasBitmapHelper& operator=( const CanvasBitmapHelper& );

        BitmapBackBufferSharedPtr   mpBackBuffer;
    };
}

#endif /* _VCLCANVAS_CANVASBITMAPHELPER_HXX_ */
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.22); FILE MERGED 2005/09/05 17:27:11 rt 1.3.22.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: canvasbitmaphelper.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 23:18:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _VCLCANVAS_CANVASBITMAPHELPER_HXX_
#define _VCLCANVAS_CANVASBITMAPHELPER_HXX_

#include <canvashelper.hxx>

#ifndef _SV_BITMAPEX_HXX
#include <vcl/bitmapex.hxx>
#endif

#include <canvas/vclwrapper.hxx>

#include "bitmapbackbuffer.hxx"

namespace vclcanvas
{
    /** Helper class for basic canvasbitmap functionality. Extends
        CanvasHelper with some CanvasBitmap specialities, such as alpha
        support.

        Note that a plain CanvasHelper, although it does support the
        XBitmap interface, has no provision for alpha channel on VCL
        (at least no efficient one. If the alpha VDev one day gets
        part of SAL, we might change that).
     */
    class CanvasBitmapHelper : public CanvasHelper
    {
    public:
        CanvasBitmapHelper();

        /** Set a new bitmap on this helper.

            This method force-sets a new bitmap. The internally stored
            bitmap representation is updated from the given bitmap,
            including any size changes.
         */
        void setBitmap( const BitmapEx&                     rBitmap,
                        const WindowGraphicDevice::ImplRef& rDevice );

        // Overridden CanvasHelper functionality
        // =====================================

        void disposing();

        ::com::sun::star::geometry::IntegerSize2D SAL_CALL getSize();

        ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapCanvas > SAL_CALL queryBitmapCanvas();

        ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmap > SAL_CALL
            getScaledBitmap( const ::com::sun::star::geometry::RealSize2D&  newSize,
                             sal_Bool                                               beFast );

        ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
            getData( const ::com::sun::star::geometry::IntegerRectangle2D& rect );

        void SAL_CALL setData( const ::com::sun::star::uno::Sequence< sal_Int8 >&               data,
                               const ::com::sun::star::geometry::IntegerRectangle2D&    rect );

        void SAL_CALL setPixel( const ::com::sun::star::uno::Sequence< sal_Int8 >&          color,
                                const ::com::sun::star::geometry::IntegerPoint2D&   pos );

        ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL
            getPixel( const ::com::sun::star::geometry::IntegerPoint2D& pos );

        ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XBitmapPalette > SAL_CALL getPalette();

        ::com::sun::star::rendering::IntegerBitmapLayout SAL_CALL getMemoryLayout();

        /// @internal
        BitmapEx getBitmap() const;

    private:
        // default: disabled copy/assignment
        CanvasBitmapHelper(const CanvasBitmapHelper&);
        CanvasBitmapHelper& operator=( const CanvasBitmapHelper& );

        BitmapBackBufferSharedPtr   mpBackBuffer;
    };
}

#endif /* _VCLCANVAS_CANVASBITMAPHELPER_HXX_ */
<|endoftext|>


<commit_before>/* <x0/io/CompositeSource.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 * http://www.xzero.ws/
 *
 * (c) 2009-2010 Christian Parpart <trapni@gentoo.org>
 */

#include <x0/io/CompositeSource.h>
#include <deque>

namespace x0 {

ssize_t CompositeSource::sendto(Sink& sink)
{
	ssize_t result = 0;

	while (!empty()) {
		result = sources_.front()->sendto(sink);

		if (result == 0) // empty source
			sources_.pop_front();

		if (result < 0) // error in source
			return result;
	}

	return result;
}

} // namespace x0
<commit_msg>[io] CompositeSource: refactored a bit and fixed an invalid return code on fragmented transmissions<commit_after>/* <x0/io/CompositeSource.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 * http://www.xzero.ws/
 *
 * (c) 2009-2010 Christian Parpart <trapni@gentoo.org>
 */

#include <x0/io/CompositeSource.h>
#include <deque>

namespace x0 {

ssize_t CompositeSource::sendto(Sink& sink)
{
	ssize_t result = 0;

	while (!empty()) {
		ssize_t rv = sources_.front()->sendto(sink);

		if (rv < 0) // error in source
			return result ? result : rv;
		else if (rv == 0) // empty source
			sources_.pop_front();
		else
			result += rv;
	}

	return result;
}

} // namespace x0
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "catch.hpp"

#include "dll/conv_layer.hpp"
#include "dll/dense_layer.hpp"
#include "dll/conv_rbm.hpp"
#include "dll/dbn.hpp"
#include "dll/scale_layer.hpp"
#include "dll/mp_layer.hpp"
#include "dll/avgp_layer.hpp"
#include "dll/stochastic_gradient_descent.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("lenet_rbm", "[dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::scale_layer_desc<1, 256>::layer_t,
            dll::conv_rbm_desc_square<1, 28, 20, 24, dll::hidden<dll::unit_type::BINARY>, dll::momentum, dll::batch_size<10>, dll::weight_type<float>>::layer_t,
            dll::mp_layer_3d_desc<20, 24, 24, 1, 2, 2, dll::weight_type<float>>::layer_t,
            dll::conv_rbm_desc_square<20, 12, 50, 8, dll::hidden<dll::unit_type::BINARY>, dll::momentum, dll::batch_size<10>, dll::weight_type<float>>::layer_t,
            dll::mp_layer_3d_desc<50, 8, 8, 1, 2, 2, dll::weight_type<float>>::layer_t,
            dll::rbm_desc<50 * 4 * 4, 500, dll::hidden<dll::unit_type::BINARY>, dll::momentum, dll::batch_size<10>>::layer_t,
            dll::rbm_desc<500, 10, dll::momentum, dll::batch_size<10>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::weight_decay<>, dll::batch_size<25>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(1000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->l2_weight_cost   = 0.0005;
    dbn->initial_momentum = 0.9;
    dbn->final_momentum   = 0.9;
    dbn->learning_rate    = 0.1;

    dbn->pretrain(dataset.training_images, 20);

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 50);
    std::cout << "ft_error:" << ft_error << std::endl;
    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}
<commit_msg>Restore ReLU (still not working)<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "catch.hpp"

#include "dll/conv_layer.hpp"
#include "dll/dense_layer.hpp"
#include "dll/conv_rbm.hpp"
#include "dll/dbn.hpp"
#include "dll/scale_layer.hpp"
#include "dll/mp_layer.hpp"
#include "dll/avgp_layer.hpp"
#include "dll/stochastic_gradient_descent.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("lenet_rbm", "[dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::scale_layer_desc<1, 256>::layer_t,
            dll::conv_rbm_desc_square<1, 28, 20, 24, dll::hidden<dll::unit_type::RELU>, dll::momentum, dll::batch_size<10>, dll::weight_type<float>>::layer_t,
            dll::mp_layer_3d_desc<20, 24, 24, 1, 2, 2, dll::weight_type<float>>::layer_t,
            dll::conv_rbm_desc_square<20, 12, 50, 8, dll::hidden<dll::unit_type::RELU>, dll::momentum, dll::batch_size<10>, dll::weight_type<float>>::layer_t,
            dll::mp_layer_3d_desc<50, 8, 8, 1, 2, 2, dll::weight_type<float>>::layer_t,
            dll::rbm_desc<50 * 4 * 4, 500, dll::hidden<dll::unit_type::BINARY>, dll::momentum, dll::batch_size<10>>::layer_t,
            dll::rbm_desc<500, 10, dll::momentum, dll::batch_size<10>, dll::hidden<dll::unit_type::SOFTMAX>>::layer_t>,
        dll::trainer<dll::sgd_trainer>, dll::momentum, dll::weight_decay<>, dll::batch_size<25>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(1000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->l2_weight_cost   = 0.0005;
    dbn->initial_momentum = 0.9;
    dbn->final_momentum   = 0.9;
    dbn->learning_rate    = 0.1;

    dbn->pretrain(dataset.training_images, 20);

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 50);
    std::cout << "ft_error:" << ft_error << std::endl;
    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX
#define INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX

#include <drawinglayer/drawinglayerdllapi.h>

#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>

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

namespace drawinglayer
{
    namespace processor2d
    {
        /** BaseProcessor2D class

            Baseclass for all C++ implementations of instances which process
            primitives.

            Instances which process primitives can be renderers, but also stuff
            for HitTests, BoundRect calculations and/or animation processing. The
            main usage are renderers, but they are supposed to handle any primitive
            processing.

            The base implementation is constructed with a ViewInformation2D which
            is accessible throughout the processor implementations. The idea is
            to construct any processor with a given ViewInformation2D. To be able
            to handle primitives which need to change the current transformation
            (as e.g. TransformPrimitive2D) it is allowed for the processor implementation
            to change tis local value using updateViewInformation.

            The basic processing method is process(..) which gets handed over the
            sequence of primitives to process. For convenience of the C++ implementations,
            the default implementation of process(..) maps all accesses to primitives to
            single calls to processBasePrimitive2D(..) where the primitive in question is
            already casted to the C++ implementation class.

            The process(..) implementation makes a complete iteration over the given
            sequence of primitives. If the Primitive is not derived from BasePrimitive2D
            and thus not part of the C++ implementations, it converts ViewInformation2D
            to the corresponding API implementation (an uno::Sequence< beans::PropertyValue >)
            and recursively calls the method process(..) at the primitive with the decomposition
            derived from that primitive. This is the preparation to handle unknown implementations
            of the com::sun::star::graphic::XPrimitive2D interface in the future.

            So, to implement a basic processor, it is necessary to overload and implement the
            processBasePrimitive2D(..) method. A minimal renderer has to support the
            Basic Primitives (see baseprimitive2d.hxx) and the Grouping Primitives (see
            groupprimitive2d.hxx). These are (currently):

            Basic Primitives:

            - BitmapPrimitive2D (bitmap data, evtl. with transparence)
            - PointArrayPrimitive2D (single points)
            - PolygonHairlinePrimitive2D (hairline curves/polygons)
            - PolyPolygonColorPrimitive2D (colored polygons)

            Grouping Primitives:

            - TransparencePrimitive2D (objects with freely defined transparence)
            - InvertPrimitive2D (for XOR)
            - MaskPrimitive2D (for masking)
            - ModifiedColorPrimitive2D (for a stack of color modifications)
            - TransformPrimitive2D (for a transformation stack)

            A processor doing so is a minimal processor. Of course a processor may
            handle any higher-level prmitive (that has a decomposition implementation)
            for more direct data access or performance reasons, too.

            The main part of a processBasePrimitive2D implementation is a switch..case
            construct, looking like the following:

            void foo::processBasePrimitive2D(const BasePrimitive2D& rCandidate)
            {
                switch(rCandidate.getPrimitive2DID())
                {
                    case PRIMITIVE2D_ID_??? :
                    {
                        // process PRIMITIVE2D_ID_??? here...

                        ...

                        break;
                    }

                    ...

                    default :
                    {
                        // process recursively
                        process(rCandidate.get2DDecomposition(getViewInformation2D()));
                        break;
                    }
                }
            }

            The default case makes the processor work with all complex primitives
            by recursively using their decomposition.

            You can also add a case for ignoring primitives by using:

                    case PRIMITIVE2D_ID_...IGNORE.A.. :
                    case PRIMITIVE2D_ID_...IGNORE.B.. :
                    case PRIMITIVE2D_ID_...IGNORE.C.. :
                    {
                        // ignore these primitives by neither processing nor
                        // recursively processing their decomposition
                        break;
                    }

            Another useful case is embedding the processing of a complex primitive by
            bracketing it with some actions:

                    case PRIMITIVE2D_ID_SOME_TEXT :
                    {
                        // encapsulate e.g. with changing local varibles, e.g.
                        // sometimes it's good to know if a basic primitive is
                        // part of a text, especially when not handling the text
                        // self but by purpose want to handle the decomposed
                        // geometries in the processor
                        startText();
                        process(rCandidate.get2DDecomposition(getViewInformation2D()));
                        endText();
                        break;
                    }

            As an example a processor collecting the outlines of a sequence of primitives
            only needs to handle some Basic Primitives and create outline and collect
            outline polygons e.g. for primitives with area like BitmapPrimitive2D (a
            rectangle) and PolyPolygonColorPrimitive2D. When also handling the Grouping
            Primitives MaskPrimitive2D (e.g. ignoring it's content, using the mask polyPolygon)
            and TransformPrimitive2D (to have the correct local transformation), a processor
            creating the outline can be written using just four (4) primitives. As a tipp, it can
            be helpful to add many for the purpose not interesting higher level primitives
            to not force their decomposition to be created and/or parsed.
         */
        class DRAWINGLAYER_DLLPUBLIC BaseProcessor2D
        {
        private:
            /// The ViewInformation2D itself. It's private to isolate accesses to it
            geometry::ViewInformation2D                     maViewInformation2D;

        protected:
            /*  access method to allow the implementations to change the current
                ViewInformation2D if needed. This allows isolating these accesses
                later if needed
             */
            void updateViewInformation(const geometry::ViewInformation2D& rViewInformation2D)
            {
                maViewInformation2D = rViewInformation2D;
            }

            /*  as tooling, the process() implementation takes over API handling and calls this
                virtual render method when the primitive implementation is BasePrimitive2D-based.
                Default implementation does nothing
             */
            virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);

        public:
            /// constructor/destructor
            explicit BaseProcessor2D(const geometry::ViewInformation2D& rViewInformation);
            virtual ~BaseProcessor2D();

            /// the central processing method
            virtual void process(const primitive2d::Primitive2DSequence& rSource);

            /// data read access
            const geometry::ViewInformation2D& getViewInformation2D() const { return maViewInformation2D; }
        };
    } // end of namespace processor2d
} // end of namespace drawinglayer

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

#endif //INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Typos etc.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX
#define INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX

#include <drawinglayer/drawinglayerdllapi.h>

#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>

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

namespace drawinglayer
{
    namespace processor2d
    {
        /** BaseProcessor2D class

            Base class for all C++ implementations of instances which process
            primitives.

            Instances which process primitives can be renderers, but also stuff
            for HitTests, BoundRect calculations and/or animation processing. The
            main usage are renderers, but they are supposed to handle any primitive
            processing.

            The base implementation is constructed with a ViewInformation2D which
            is accessible throughout the processor implementations. The idea is
            to construct any processor with a given ViewInformation2D. To be able
            to handle primitives which need to change the current transformation
            (as e.g. TransformPrimitive2D) it is allowed for the processor implementation
            to change tis local value using updateViewInformation.

            The basic processing method is process(..) which gets handed over the
            sequence of primitives to process. For convenience of the C++ implementations,
            the default implementation of process(..) maps all accesses to primitives to
            single calls to processBasePrimitive2D(..) where the primitive in question is
            already casted to the C++ implementation class.

            The process(..) implementation makes a complete iteration over the given
            sequence of primitives. If the Primitive is not derived from BasePrimitive2D
            and thus not part of the C++ implementations, it converts ViewInformation2D
            to the corresponding API implementation (an uno::Sequence< beans::PropertyValue >)
            and recursively calls the method process(..) at the primitive with the decomposition
            derived from that primitive. This is the preparation to handle unknown implementations
            of the com::sun::star::graphic::XPrimitive2D interface in the future.

            So, to implement a basic processor, it is necessary to overload and implement the
            processBasePrimitive2D(..) method. A minimal renderer has to support the
            Basic Primitives (see baseprimitive2d.hxx) and the Grouping Primitives (see
            groupprimitive2d.hxx). These are (currently):

            Basic Primitives:

            - BitmapPrimitive2D (bitmap data, eventually with transparency)
            - PointArrayPrimitive2D (single points)
            - PolygonHairlinePrimitive2D (hairline curves/polygons)
            - PolyPolygonColorPrimitive2D (colored polygons)

            Grouping Primitives:

            - TransparencePrimitive2D (objects with freely defined transparence)
            - InvertPrimitive2D (for XOR)
            - MaskPrimitive2D (for masking)
            - ModifiedColorPrimitive2D (for a stack of color modifications)
            - TransformPrimitive2D (for a transformation stack)

            A processor doing so is a minimal processor. Of course a processor may
            handle any higher-level primitive (that has a decomposition implementation)
            for more direct data access or performance reasons, too.

            The main part of a processBasePrimitive2D implementation is a switch..case
            construct, looking like the following:

            void foo::processBasePrimitive2D(const BasePrimitive2D& rCandidate)
            {
                switch(rCandidate.getPrimitive2DID())
                {
                    case PRIMITIVE2D_ID_??? :
                    {
                        // process PRIMITIVE2D_ID_??? here...

                        ...

                        break;
                    }

                    ...

                    default :
                    {
                        // process recursively
                        process(rCandidate.get2DDecomposition(getViewInformation2D()));
                        break;
                    }
                }
            }

            The default case makes the processor work with all complex primitives
            by recursively using their decomposition.

            You can also add a case for ignoring primitives by using:

                    case PRIMITIVE2D_ID_...IGNORE.A.. :
                    case PRIMITIVE2D_ID_...IGNORE.B.. :
                    case PRIMITIVE2D_ID_...IGNORE.C.. :
                    {
                        // ignore these primitives by neither processing nor
                        // recursively processing their decomposition
                        break;
                    }

            Another useful case is embedding the processing of a complex primitive by
            bracketing it with some actions:

                    case PRIMITIVE2D_ID_SOME_TEXT :
                    {
                        // encapsulate e.g. with changing local varibles, e.g.
                        // sometimes it's good to know if a basic primitive is
                        // part of a text, especially when not handling the text
                        // self but by purpose want to handle the decomposed
                        // geometries in the processor
                        startText();
                        process(rCandidate.get2DDecomposition(getViewInformation2D()));
                        endText();
                        break;
                    }

            As an example a processor collecting the outlines of a sequence of primitives
            only needs to handle some Basic Primitives and create outline and collect
            outline polygons e.g. for primitives with area like BitmapPrimitive2D (a
            rectangle) and PolyPolygonColorPrimitive2D. When also handling the Grouping
            Primitives MaskPrimitive2D (e.g. ignoring it's content, using the mask polyPolygon)
            and TransformPrimitive2D (to have the correct local transformation), a processor
            creating the outline can be written using just four (4) primitives. As a tipp, it can
            be helpful to add many for the purpose not interesting higher level primitives
            to not force their decomposition to be created and/or parsed.
         */
        class DRAWINGLAYER_DLLPUBLIC BaseProcessor2D
        {
        private:
            /// The ViewInformation2D itself. It's private to isolate accesses to it
            geometry::ViewInformation2D                     maViewInformation2D;

        protected:
            /*  access method to allow the implementations to change the current
                ViewInformation2D if needed. This allows isolating these accesses
                later if needed
             */
            void updateViewInformation(const geometry::ViewInformation2D& rViewInformation2D)
            {
                maViewInformation2D = rViewInformation2D;
            }

            /*  as tooling, the process() implementation takes over API handling and calls this
                virtual render method when the primitive implementation is BasePrimitive2D-based.
                Default implementation does nothing
             */
            virtual void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate);

        public:
            /// constructor/destructor
            explicit BaseProcessor2D(const geometry::ViewInformation2D& rViewInformation);
            virtual ~BaseProcessor2D();

            /// the central processing method
            virtual void process(const primitive2d::Primitive2DSequence& rSource);

            /// data read access
            const geometry::ViewInformation2D& getViewInformation2D() const { return maViewInformation2D; }
        };
    } // end of namespace processor2d
} // end of namespace drawinglayer

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

#endif //INCLUDED_DRAWINGLAYER_PROCESSOR2D_BASEPROCESSOR2D_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#pragma once

#ifndef RXQT_SIGNAL_HPP
#define RXQT_SIGNAL_HPP

#include <rxcpp/rx.hpp>
#include <QObject>

namespace rxqt {

namespace signal {

namespace detail {

template <class R, class Q, class ...Args>
struct from_signal
{
    using signal_type = R(Q::*)(const Args&...);
    using value_type = std::tuple<Args...>;

    static rxcpp::observable<value_type> create(const Q* qobject, signal_type signal)
    {
        if(!qobject) return rxcpp::sources::never<value_type>();

        return rxcpp::observable<>::create<value_type>(
            [qobject, signal](const rxcpp::subscriber<value_type>& s){
                QObject::connect(qobject, signal,[s](const Args&... values){
                    s.on_next(std::make_tuple(values...));
                });
                QObject::connect(qobject, &QObject::destroyed, [s](){
                    s.on_completed();
                });
            }
        );
    }
};

template <class R, class Q>
struct from_signal<R, Q>
{
    using signal_type = R(Q::*)();
    using value_type = long;

    static rxcpp::observable<long> create(const Q* qobject, signal_type signal)
    {
        if(!qobject) return rxcpp::sources::never<value_type>();

        return rxcpp::observable<>::create<long>(
            [qobject, signal](const rxcpp::subscriber<long>& s){
                long counter = 0;
                QObject::connect(qobject, signal, [s, counter]() mutable {
                    s.on_next(counter++);
                });
                QObject::connect(qobject, &QObject::destroyed, [s](){
                    s.on_completed();
                });
            }
        );
    }
};

template <class R, class Q, class A0>
struct from_signal<R, Q, A0>
{
    using signal_type = R(Q::*)(const A0&);
    using value_type = A0;

    static rxcpp::observable<value_type> create(const Q* qobject, signal_type signal)
    {
        if(!qobject) return rxcpp::sources::never<value_type>();

        return rxcpp::observable<>::create<value_type>(
            [qobject, signal](const rxcpp::subscriber<value_type>& s){
                QObject::connect(qobject, signal, [s](const A0& v0){
                    s.on_next(v0);
                });
                QObject::connect(qobject, &QObject::destroyed, [s](){
                    s.on_completed();
                });
            }
        );
    }
};

} // detail

} // signal

template <class R, class Q, class ...Args>
rxcpp::observable<typename signal::detail::from_signal<R, Q, Args...>::value_type>
from_signal(const Q* qobject, R(Q::*signal)(const Args&...))
{
    return signal::detail::from_signal<R, Q, Args...>::create(qobject, signal);
}

} // qtrx

#endif // RXQT_SIGNAL_HPP
<commit_msg>Handle signal type correctly.<commit_after>#pragma once

#ifndef RXQT_SIGNAL_HPP
#define RXQT_SIGNAL_HPP

#include <rxcpp/rx.hpp>
#include <QObject>

namespace rxqt {

namespace signal {

namespace detail {

template <class R, class Q, class ...Args>
struct from_signal
{
    using signal_type = R(Q::*)(Args...);
    using value_type = std::tuple<typename std::remove_const<typename std::remove_reference<Args>::type>::type...>;

    static rxcpp::observable<value_type> create(const Q* qobject, signal_type signal)
    {
        if(!qobject) return rxcpp::sources::never<value_type>();

        return rxcpp::observable<>::create<value_type>(
            [qobject, signal](const rxcpp::subscriber<value_type>& s){
                QObject::connect(qobject, signal,[s](const Args&... values){
                    s.on_next(std::make_tuple(values...));
                });
                QObject::connect(qobject, &QObject::destroyed, [s](){
                    s.on_completed();
                });
            }
        );
    }
};

template <class R, class Q>
struct from_signal<R, Q>
{
    using signal_type = R(Q::*)();
    using value_type = long;

    static rxcpp::observable<long> create(const Q* qobject, signal_type signal)
    {
        if(!qobject) return rxcpp::sources::never<value_type>();

        return rxcpp::observable<>::create<long>(
            [qobject, signal](const rxcpp::subscriber<long>& s){
                long counter = 0;
                QObject::connect(qobject, signal, [s, counter]() mutable {
                    s.on_next(counter++);
                });
                QObject::connect(qobject, &QObject::destroyed, [s](){
                    s.on_completed();
                });
            }
        );
    }
};

template <class R, class Q, class A0>
struct from_signal<R, Q, A0>
{
    using signal_type = R(Q::*)(A0);
    using value_type = typename std::remove_const<typename std::remove_reference<A0>::type>::type;

    static rxcpp::observable<value_type> create(const Q* qobject, signal_type signal)
    {
        if(!qobject) return rxcpp::sources::never<value_type>();

        return rxcpp::observable<>::create<value_type>(
            [qobject, signal](const rxcpp::subscriber<value_type>& s){
                QObject::connect(qobject, signal, [s](const A0& v0){
                    s.on_next(v0);
                });
                QObject::connect(qobject, &QObject::destroyed, [s](){
                    s.on_completed();
                });
            }
        );
    }
};

} // detail

} // signal

template <class R, class Q, class ...Args>
rxcpp::observable<typename signal::detail::from_signal<R, Q, Args...>::value_type>
from_signal(const Q* qobject, R(Q::*signal)(Args...))
{
    return signal::detail::from_signal<R, Q, Args...>::create(qobject, signal);
}

} // qtrx

#endif // RXQT_SIGNAL_HPP
<|endoftext|>


<commit_before>#include <iostream>

#include <boost/lambda/lambda.hpp>
#include <boost/mem_fn.hpp>

#include <libport/compiler.hh>     // For ECHO
#include <libport/containers.hh>
#include <libport/foreach.hh>

#include <scheduler/job.hh>

namespace scheduler
{
  StopException::StopException(int depth, boost::any payload)
    : depth_(depth)
    , payload_(payload)
  {
  }

  void
  Job::run()
  {
    assert(state_ == to_start);
    ECHO("In Job::run for " << this);

    // We may get interrupted during our first run, in which case
    // we better not be in the to_start state while we are executing
    // or we would get removed abruptly from the scheduler pending_
    // list.
    state_ = running;
    try {
      if (pending_exception_ &&
	  dynamic_cast<SchedulerException*>(pending_exception_.get()))
	check_for_pending_exception();
      work();
    }
    catch (TerminateException&)
    {
      // Normal termination requested
    }
    catch (StopException&)
    {
      // Termination through "stop" or "block" on a top-level tag,
      // that is a tag inherited at the job creation time.
    }
    catch (const kernel::exception& e)
    {
      // Signal the exception to each linked job in turn.
      foreach (rJob job, links_)
      {
	job->links_.remove(this);
	job->async_throw(e);
      }
    }
    catch (...)
    {
      // Exception is lost and cannot be propagated properly
      std::cerr << "Exception caught in job " << this << ", loosing it\n";
    }

    terminate_cleanup();

    // We should never go there as the scheduler will have terminated us.
    assert(false);
  }

  void
  Job::terminate_now()
  {
    if (!terminated())
      async_throw(TerminateException());
  }

  void
  Job::terminate_cleanup()
  {
    // Remove pending links.
    foreach (rJob job, links_)
      job->links_.remove(this);
    links_.clear();
    // Wake-up waiting jobs.
    foreach (rJob job, to_wake_up_)
      if (!job->terminated())
	job->state_set(running);
    to_wake_up_.clear();
    state_ = zombie;
    scheduler_.resume_scheduler(this);
  }

  void
  Job::yield_until_terminated(Job& other)
  {
    if (non_interruptible_)
      throw object::SchedulingError
	("dependency on other task in non-interruptible code");

    if (!other.terminated())
    {
      // We allow enqueuing on ourselves, but without doing it for real.
      if (&other != this)
	other.to_wake_up_.push_back(this);
      state_ = joining;
      try
      {
	scheduler_.resume_scheduler(this);
      }
      catch (...)
      {
	// We have been awoken by an exception; in this case,
	// dequeue ourselves from the other thread queue if
	// we are still enqueued there.
	libport::erase_if(other.to_wake_up_, boost::lambda::_1 == this);
	throw;
      }
    }
  }

  void
  Job::yield_until_terminated(jobs_type jobs)
  {
    foreach (rJob job, jobs)
      yield_until_terminated(*job);
  }

  void
  Job::yield_until_things_changed()
  {
    if (non_interruptible_ && !frozen())
      throw object::SchedulingError
	("attempt to wait for condition changes in non-interruptible code");

    state_ = waiting;
    scheduler_.resume_scheduler(this);
  }

  bool
  Job::frozen() const
  {
    return libport::has_if(tags_, boost::mem_fn(&scheduler::Tag::frozen));
  }

  void
  Job::async_throw(const kernel::exception& e)
  {
    pending_exception_ = e.clone();
    // A job which has received an exception is no longer side effect
    // free or non-interruptible.
    side_effect_free_ = false;
    non_interruptible_ = false;
    // If this is the current job we are talking about, the exception
    // is synchronous.
    if (scheduler_.is_current_job(*this))
      check_for_pending_exception();
    // Now that we acquired an exception to raise, we are active again,
    // even if we were previously sleeping or waiting for something.
    if (state_ != to_start && state_ != zombie)
      state_ = running;
  }

  void
  Job::register_stopped_tag(const rTag& tag, boost::any payload)
  {
    int max_tag_check = tags_.size();
    if (pending_exception_)
    {
      // If we are going to terminate, do nothing
      if (dynamic_cast<TerminateException*>(pending_exception_.get()))
	return;
      // If we already have a StopException stored, do not go any
      // further.
      StopException* exc =
	dynamic_cast<StopException*>(pending_exception_.get());
      if (exc)
	max_tag_check = exc->depth_get();
    }

    // Check if we are affected by this tag, up-to max_tag_check from
    // the beginning of the tag list.
    for (int i = 0; i < max_tag_check; i++)
      if (tags_[i]->derives_from(*tag))
      {
	async_throw(StopException(i, payload));
	return;
      }
  }

  void
  Job::check_for_pending_exception()
  {
    // If an exception has been stored for further rethrow, now is
    // a good time to do so.
    if (pending_exception_)
    {
      current_exception_ = pending_exception_;
      pending_exception_ = 0;
      kernel::rethrow(current_exception_);
    }
  }

}
<commit_msg>A task can wait for a signal in non-interruptible mode.<commit_after>#include <iostream>

#include <boost/lambda/lambda.hpp>
#include <boost/mem_fn.hpp>

#include <libport/compiler.hh>     // For ECHO
#include <libport/containers.hh>
#include <libport/foreach.hh>

#include <scheduler/job.hh>

namespace scheduler
{
  StopException::StopException(int depth, boost::any payload)
    : depth_(depth)
    , payload_(payload)
  {
  }

  void
  Job::run()
  {
    assert(state_ == to_start);
    ECHO("In Job::run for " << this);

    // We may get interrupted during our first run, in which case
    // we better not be in the to_start state while we are executing
    // or we would get removed abruptly from the scheduler pending_
    // list.
    state_ = running;
    try {
      if (pending_exception_ &&
	  dynamic_cast<SchedulerException*>(pending_exception_.get()))
	check_for_pending_exception();
      work();
    }
    catch (TerminateException&)
    {
      // Normal termination requested
    }
    catch (StopException&)
    {
      // Termination through "stop" or "block" on a top-level tag,
      // that is a tag inherited at the job creation time.
    }
    catch (const kernel::exception& e)
    {
      // Signal the exception to each linked job in turn.
      foreach (rJob job, links_)
      {
	job->links_.remove(this);
	job->async_throw(e);
      }
    }
    catch (...)
    {
      // Exception is lost and cannot be propagated properly
      std::cerr << "Exception caught in job " << this << ", loosing it\n";
    }

    terminate_cleanup();

    // We should never go there as the scheduler will have terminated us.
    assert(false);
  }

  void
  Job::terminate_now()
  {
    if (!terminated())
      async_throw(TerminateException());
  }

  void
  Job::terminate_cleanup()
  {
    // Remove pending links.
    foreach (rJob job, links_)
      job->links_.remove(this);
    links_.clear();
    // Wake-up waiting jobs.
    foreach (rJob job, to_wake_up_)
      if (!job->terminated())
	job->state_set(running);
    to_wake_up_.clear();
    state_ = zombie;
    scheduler_.resume_scheduler(this);
  }

  void
  Job::yield_until_terminated(Job& other)
  {
    if (non_interruptible_ && this != &other)
      throw object::SchedulingError
	("dependency on other task in non-interruptible code");

    if (!other.terminated())
    {
      // We allow enqueuing on ourselves, but without doing it for real.
      if (&other != this)
	other.to_wake_up_.push_back(this);
      state_ = joining;
      try
      {
	scheduler_.resume_scheduler(this);
      }
      catch (...)
      {
	// We have been awoken by an exception; in this case,
	// dequeue ourselves from the other thread queue if
	// we are still enqueued there.
	libport::erase_if(other.to_wake_up_, boost::lambda::_1 == this);
	throw;
      }
    }
  }

  void
  Job::yield_until_terminated(jobs_type jobs)
  {
    foreach (rJob job, jobs)
      yield_until_terminated(*job);
  }

  void
  Job::yield_until_things_changed()
  {
    if (non_interruptible_ && !frozen())
      throw object::SchedulingError
	("attempt to wait for condition changes in non-interruptible code");

    state_ = waiting;
    scheduler_.resume_scheduler(this);
  }

  bool
  Job::frozen() const
  {
    return libport::has_if(tags_, boost::mem_fn(&scheduler::Tag::frozen));
  }

  void
  Job::async_throw(const kernel::exception& e)
  {
    pending_exception_ = e.clone();
    // A job which has received an exception is no longer side effect
    // free or non-interruptible.
    side_effect_free_ = false;
    non_interruptible_ = false;
    // If this is the current job we are talking about, the exception
    // is synchronous.
    if (scheduler_.is_current_job(*this))
      check_for_pending_exception();
    // Now that we acquired an exception to raise, we are active again,
    // even if we were previously sleeping or waiting for something.
    if (state_ != to_start && state_ != zombie)
      state_ = running;
  }

  void
  Job::register_stopped_tag(const rTag& tag, boost::any payload)
  {
    int max_tag_check = tags_.size();
    if (pending_exception_)
    {
      // If we are going to terminate, do nothing
      if (dynamic_cast<TerminateException*>(pending_exception_.get()))
	return;
      // If we already have a StopException stored, do not go any
      // further.
      StopException* exc =
	dynamic_cast<StopException*>(pending_exception_.get());
      if (exc)
	max_tag_check = exc->depth_get();
    }

    // Check if we are affected by this tag, up-to max_tag_check from
    // the beginning of the tag list.
    for (int i = 0; i < max_tag_check; i++)
      if (tags_[i]->derives_from(*tag))
      {
	async_throw(StopException(i, payload));
	return;
      }
  }

  void
  Job::check_for_pending_exception()
  {
    // If an exception has been stored for further rethrow, now is
    // a good time to do so.
    if (pending_exception_)
    {
      current_exception_ = pending_exception_;
      pending_exception_ = 0;
      kernel::rethrow(current_exception_);
    }
  }

}
<|endoftext|>