<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2011 New Dream Network
 *
 * This 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.  See file COPYING.
 *
 */

#include "common/errno.h"
#include "include/atomic.h"
#include "systest_runnable.h"
#include "systest_settings.h"

#include <errno.h>
#include <pthread.h>
#include <sstream>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <vector>

using std::ostringstream;
using std::string;

static pid_t do_gettid(void)
{
  return static_cast < pid_t >(syscall(SYS_gettid));
}

ceph::atomic_t m_highest_id(0);

SysTestRunnable::
SysTestRunnable(int argc, const char **argv)
  : m_argc(0),
    m_argv(NULL),
    m_argv_orig(NULL)
{
  m_started = false;
  m_id = m_highest_id.inc();
  memset(&m_pthread, 0, sizeof(m_pthread));
  m_pid = 0;
  update_id_str(false);
  set_argv(argc, argv);
}

SysTestRunnable::
~SysTestRunnable()
{
  set_argv(0, NULL);
}

const char* SysTestRunnable::
get_id_str(void) const
{
  return m_id_str;
}

int SysTestRunnable::
start()
{
  if (m_started) {
    return -EDOM;
  }
  bool use_threads = SysTestSettings::inst().use_threads();
  if (use_threads) {
    int ret = pthread_create(&m_pthread, NULL, systest_runnable_pthread_helper,
			     static_cast<void*>(this));
    if (ret)
      return ret;
    m_started = true;
    return 0;
  }
  else {
    pid_t pid = fork();
    if (pid == -1) {
      int err = errno;
      return -err;
    }
    else if (pid == 0) {
      m_started = true;
      m_pid = getpid();
      void *retptr = systest_runnable_pthread_helper(static_cast<void*>(this));
      exit((int)(uintptr_t)retptr);
    }
    else {
      m_started = true;
      m_pid = pid;
      return 0;
    }
  }
}

std::string SysTestRunnable::
join()
{
  if (!m_started) {
    return "SysTestRunnable was never started.";
  }
  bool use_threads = SysTestSettings::inst().use_threads();
  if (use_threads) {
    void *ptrretval;
    int ret = pthread_join(m_pthread, &ptrretval);
    if (ret) {
      ostringstream oss;
      oss << "pthread_join failed with error " << ret;
      return oss.str();
    }
    int retval = (int)(uintptr_t)ptrretval;
    if (retval != 0) {
      ostringstream oss;
      oss << "ERROR " << retval;
      return oss.str();
    }
    return "";
  }
  else {
    int status;
    printf("waitpid(%d)\n", m_pid);
    pid_t pid = waitpid(m_pid, &status, 0);
    if (pid == -1) {
      int err = errno;
      ostringstream oss;
      oss << get_id_str() << " waitpid error: " << cpp_strerror(err);
      return oss.str();
    }
    else if (WIFSIGNALED(status)) {
      ostringstream oss;
      oss << get_id_str() << " exited with a signal";
      return oss.str();
    }
    else if (!WIFEXITED(status)) {
      ostringstream oss;
      oss << get_id_str() << " did not exit normally";
      return oss.str();
    }
    else {
      int exit_status = WEXITSTATUS(status);
      if (exit_status != 0) {
	ostringstream oss;
	oss << get_id_str() << " returned exit_status " << exit_status;
	return oss.str();
      }
      return "";
    }
  }
}

std::string SysTestRunnable::
run_until_finished(std::vector < SysTestRunnable * > &runnables)
{
  int ret, index = 0;
  for (std::vector < SysTestRunnable * >::const_iterator r = runnables.begin();
      r != runnables.end(); ++r) {
    ret = (*r)->start();
    if (ret) {
      ostringstream oss;
      oss << "run_until_finished: got error " << ret
	  << " when starting runnable " << index;
      return oss.str();
    }
    ++index;
  }

  for (std::vector < SysTestRunnable * >::const_iterator r = runnables.begin();
      r != runnables.end(); ++r) {
    std::string rstr = (*r)->join();
    if (!rstr.empty()) {
      ostringstream oss;
      oss << "run_until_finished: runnable " << (*r)->get_id_str()
	  << ": got error: " << rstr;
      return oss.str();
    }
  }
  return "";
}

void *systest_runnable_pthread_helper(void *arg)
{
  SysTestRunnable *st = static_cast < SysTestRunnable * >(arg);
  st->update_id_str(true);
  int ret = st->run();
  return (void*)(uintptr_t)ret;
}

void SysTestRunnable::
update_id_str(bool started)
{
  bool use_threads = SysTestSettings::inst().use_threads();
  char extra[128];
  extra[0] = '\0';

  if (started) {
    if (use_threads)
      snprintf(extra, sizeof(extra), "_[%d]", do_gettid());
    else
      snprintf(extra, sizeof(extra), "_[%d]", getpid());
  }
  if (use_threads)
    snprintf(m_id_str, SysTestRunnable::ID_STR_SZ, "thread_%d%s", m_id, extra);
  else
    snprintf(m_id_str, SysTestRunnable::ID_STR_SZ, "process_%d%s", m_id, extra);
}

// Copy argv so that if some fiend decides to modify it, it's ok.
void SysTestRunnable::
set_argv(int argc, const char **argv)
{
  if (m_argv_orig != NULL) {
    for (int i = 0; i < m_argc; ++i)
      free((void*)(m_argv_orig[i]));
    delete m_argv_orig;
    m_argv_orig = NULL;
    delete m_argv;
    m_argv = NULL;
    m_argc = 0;
  }
  if (argv == NULL)
    return;
  m_argc = argc;
  m_argv_orig = new const char*[m_argc+1];
  for (int i = 0; i < m_argc; ++i)
    m_argv_orig[i] = strdup(argv[i]);
  m_argv_orig[argc] = NULL;
  m_argv = new const char*[m_argc+1];
  for (int i = 0; i <= m_argc; ++i)
    m_argv[i] = m_argv_orig[i];
}
<commit_msg>systest_runnable: print line when joining runnables<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2011 New Dream Network
 *
 * This 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.  See file COPYING.
 *
 */

#include "common/errno.h"
#include "include/atomic.h"
#include "systest_runnable.h"
#include "systest_settings.h"

#include <errno.h>
#include <pthread.h>
#include <sstream>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <vector>

using std::ostringstream;
using std::string;

static pid_t do_gettid(void)
{
  return static_cast < pid_t >(syscall(SYS_gettid));
}

ceph::atomic_t m_highest_id(0);

SysTestRunnable::
SysTestRunnable(int argc, const char **argv)
  : m_argc(0),
    m_argv(NULL),
    m_argv_orig(NULL)
{
  m_started = false;
  m_id = m_highest_id.inc();
  memset(&m_pthread, 0, sizeof(m_pthread));
  m_pid = 0;
  update_id_str(false);
  set_argv(argc, argv);
}

SysTestRunnable::
~SysTestRunnable()
{
  set_argv(0, NULL);
}

const char* SysTestRunnable::
get_id_str(void) const
{
  return m_id_str;
}

int SysTestRunnable::
start()
{
  if (m_started) {
    return -EDOM;
  }
  bool use_threads = SysTestSettings::inst().use_threads();
  if (use_threads) {
    int ret = pthread_create(&m_pthread, NULL, systest_runnable_pthread_helper,
			     static_cast<void*>(this));
    if (ret)
      return ret;
    m_started = true;
    return 0;
  }
  else {
    pid_t pid = fork();
    if (pid == -1) {
      int err = errno;
      return -err;
    }
    else if (pid == 0) {
      m_started = true;
      m_pid = getpid();
      void *retptr = systest_runnable_pthread_helper(static_cast<void*>(this));
      exit((int)(uintptr_t)retptr);
    }
    else {
      m_started = true;
      m_pid = pid;
      return 0;
    }
  }
}

std::string SysTestRunnable::
join()
{
  if (!m_started) {
    return "SysTestRunnable was never started.";
  }
  bool use_threads = SysTestSettings::inst().use_threads();
  if (use_threads) {
    void *ptrretval;
    int ret = pthread_join(m_pthread, &ptrretval);
    if (ret) {
      ostringstream oss;
      oss << "pthread_join failed with error " << ret;
      return oss.str();
    }
    int retval = (int)(uintptr_t)ptrretval;
    if (retval != 0) {
      ostringstream oss;
      oss << "ERROR " << retval;
      return oss.str();
    }
    return "";
  }
  else {
    int status;
    printf("waitpid(%d)\n", m_pid);
    pid_t pid = waitpid(m_pid, &status, 0);
    if (pid == -1) {
      int err = errno;
      ostringstream oss;
      oss << get_id_str() << " waitpid error: " << cpp_strerror(err);
      return oss.str();
    }
    else if (WIFSIGNALED(status)) {
      ostringstream oss;
      oss << get_id_str() << " exited with a signal";
      return oss.str();
    }
    else if (!WIFEXITED(status)) {
      ostringstream oss;
      oss << get_id_str() << " did not exit normally";
      return oss.str();
    }
    else {
      int exit_status = WEXITSTATUS(status);
      if (exit_status != 0) {
	ostringstream oss;
	oss << get_id_str() << " returned exit_status " << exit_status;
	return oss.str();
      }
      return "";
    }
  }
}

std::string SysTestRunnable::
run_until_finished(std::vector < SysTestRunnable * > &runnables)
{
  int ret, index = 0;
  for (std::vector < SysTestRunnable * >::const_iterator r = runnables.begin();
      r != runnables.end(); ++r) {
    ret = (*r)->start();
    if (ret) {
      ostringstream oss;
      oss << "run_until_finished: got error " << ret
	  << " when starting runnable " << index;
      return oss.str();
    }
    ++index;
  }

  for (std::vector < SysTestRunnable * >::const_iterator r = runnables.begin();
      r != runnables.end(); ++r) {
    std::string rstr = (*r)->join();
    if (!rstr.empty()) {
      ostringstream oss;
      oss << "run_until_finished: runnable " << (*r)->get_id_str()
	  << ": got error: " << rstr;
      return oss.str();
    }
  }
  printf("*******************************\n");
  return "";
}

void *systest_runnable_pthread_helper(void *arg)
{
  SysTestRunnable *st = static_cast < SysTestRunnable * >(arg);
  st->update_id_str(true);
  int ret = st->run();
  return (void*)(uintptr_t)ret;
}

void SysTestRunnable::
update_id_str(bool started)
{
  bool use_threads = SysTestSettings::inst().use_threads();
  char extra[128];
  extra[0] = '\0';

  if (started) {
    if (use_threads)
      snprintf(extra, sizeof(extra), "_[%d]", do_gettid());
    else
      snprintf(extra, sizeof(extra), "_[%d]", getpid());
  }
  if (use_threads)
    snprintf(m_id_str, SysTestRunnable::ID_STR_SZ, "thread_%d%s", m_id, extra);
  else
    snprintf(m_id_str, SysTestRunnable::ID_STR_SZ, "process_%d%s", m_id, extra);
}

// Copy argv so that if some fiend decides to modify it, it's ok.
void SysTestRunnable::
set_argv(int argc, const char **argv)
{
  if (m_argv_orig != NULL) {
    for (int i = 0; i < m_argc; ++i)
      free((void*)(m_argv_orig[i]));
    delete m_argv_orig;
    m_argv_orig = NULL;
    delete m_argv;
    m_argv = NULL;
    m_argc = 0;
  }
  if (argv == NULL)
    return;
  m_argc = argc;
  m_argv_orig = new const char*[m_argc+1];
  for (int i = 0; i < m_argc; ++i)
    m_argv_orig[i] = strdup(argv[i]);
  m_argv_orig[argc] = NULL;
  m_argv = new const char*[m_argc+1];
  for (int i = 0; i <= m_argc; ++i)
    m_argv[i] = m_argv_orig[i];
}
<|endoftext|>


<commit_before>#include "include/engine/SoundEngine.h"

SoundEngine::SoundEngine(int soundEffectsVolume, int musicVolume, QObject *parent) :
    QObject(parent), satCounter(0)
{
    Phonon::AudioOutput *shootOutput = new Phonon::AudioOutput(Phonon::GameCategory, this);
    shootOutput->setVolume(soundEffectsVolume / 100.0);
    Phonon::AudioOutput *satOutput = new Phonon::AudioOutput(Phonon::GameCategory, this);
    satOutput->setVolume(soundEffectsVolume / 100.0);

    Phonon::AudioOutput *musicOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
    musicOutput->setVolume(musicVolume / 100.0);

    shootMediaObject = new Phonon::MediaObject(this);
    shootMediaObject->setCurrentSource(Phonon::MediaSource(":/sounds/laser"));
    Phonon::createPath(shootMediaObject, shootOutput);

    satMediaObject = new Phonon::MediaObject(this);
    satMediaObject->setCurrentSource(Phonon::MediaSource(":/sounds/sat"));
    Phonon::createPath(satMediaObject, satOutput);

    musicMediaObject = new Phonon::MediaObject(this);
    musicMediaObject->setCurrentSource(Phonon::MediaSource(":/sounds/bgmusic"));
    Phonon::createPath(musicMediaObject, musicOutput);
    connect(musicMediaObject, SIGNAL(aboutToFinish()), this, SLOT(musicFinished()));
    musicMediaObject->play();
}

void SoundEngine::playSound(Sounds toPlay)
{
    if(toPlay == SatelliteSound)
    {
        if(++satCounter <= 1)
        {
            playSat();
            QTimer::singleShot(SAT_INTERVAL, this, SLOT(playSat()));
        }
    }
    else if(toPlay == ShootSound)
    {
        shootMediaObject->seek(0);
        shootMediaObject->play();
    }
}

void SoundEngine::stopSound(Sounds toStop)
{
    if(toStop == SatelliteSound)
        --satCounter;
}

void SoundEngine::playSat()
{
    if(satCounter > 0)
    {
        qDebug() << "Counter : " << satCounter;

        satMediaObject->seek(0);
        satMediaObject->play();

        QTimer::singleShot(SAT_INTERVAL, this, SLOT(playSat()));
    }
}

void SoundEngine::musicFinished()
{
    musicMediaObject->enqueue(Phonon::MediaSource(":/sounds/bgmusic"));
}
<commit_msg>Remove annoying qDebug()<commit_after>#include "include/engine/SoundEngine.h"

SoundEngine::SoundEngine(int soundEffectsVolume, int musicVolume, QObject *parent) :
    QObject(parent), satCounter(0)
{
    Phonon::AudioOutput *shootOutput = new Phonon::AudioOutput(Phonon::GameCategory, this);
    shootOutput->setVolume(soundEffectsVolume / 100.0);
    Phonon::AudioOutput *satOutput = new Phonon::AudioOutput(Phonon::GameCategory, this);
    satOutput->setVolume(soundEffectsVolume / 100.0);

    Phonon::AudioOutput *musicOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
    musicOutput->setVolume(musicVolume / 100.0);

    shootMediaObject = new Phonon::MediaObject(this);
    shootMediaObject->setCurrentSource(Phonon::MediaSource(":/sounds/laser"));
    Phonon::createPath(shootMediaObject, shootOutput);

    satMediaObject = new Phonon::MediaObject(this);
    satMediaObject->setCurrentSource(Phonon::MediaSource(":/sounds/sat"));
    Phonon::createPath(satMediaObject, satOutput);

    musicMediaObject = new Phonon::MediaObject(this);
    musicMediaObject->setCurrentSource(Phonon::MediaSource(":/sounds/bgmusic"));
    Phonon::createPath(musicMediaObject, musicOutput);
    connect(musicMediaObject, SIGNAL(aboutToFinish()), this, SLOT(musicFinished()));
    musicMediaObject->play();
}

void SoundEngine::playSound(Sounds toPlay)
{
    if(toPlay == SatelliteSound)
    {
        if(++satCounter <= 1)
        {
            playSat();
            QTimer::singleShot(SAT_INTERVAL, this, SLOT(playSat()));
        }
    }
    else if(toPlay == ShootSound)
    {
        shootMediaObject->seek(0);
        shootMediaObject->play();
    }
}

void SoundEngine::stopSound(Sounds toStop)
{
    if(toStop == SatelliteSound)
        --satCounter;
}

void SoundEngine::playSat()
{
    if(satCounter > 0)
    {
        satMediaObject->seek(0);
        satMediaObject->play();

        QTimer::singleShot(SAT_INTERVAL, this, SLOT(playSat()));
    }
}

void SoundEngine::musicFinished()
{
    musicMediaObject->enqueue(Phonon::MediaSource(":/sounds/bgmusic"));
}
<|endoftext|>


<commit_before>#include "nano.h"
#include "class.h"
#include "measure.h"
#include "text/table.h"
#include "accumulator.h"
#include "text/cmdline.h"
#include "math/random.h"
#include "tensor/numeric.h"
#include "measure_and_log.h"
#include "layers/make_layers.h"
#include "tasks/task_charset.h"
#include "text/table_row_mark.h"
#include <iostream>

int main(int argc, const char *argv[])
{
        using namespace nano;

        // parse the command line
        cmdline_t cmdline("benchmark models");
        cmdline.add("s", "samples",     "number of samples to use [100, 10000]", "1000");
        cmdline.add("c", "conn",        "plane connectivity for convolution networks [1, 16]", "8");
        cmdline.add("", "mlps",         "benchmark MLP models");
        cmdline.add("", "convnets",     "benchmark convolution networks");
        cmdline.add("", "forward",      "evaluate the \'forward\' pass (output)");
        cmdline.add("", "backward",     "evaluate the \'backward' pass (gradient)");
        cmdline.add("", "activation",   "activation layer", "act-snorm");
        cmdline.add("", "detailed",     "print detailed measurements (e.g. per-layer)");

        cmdline.process(argc, argv);

        // check arguments and options
        const auto cmd_samples = clamp(cmdline.get<size_t>("samples"), 100, 100 * 1000);
        const auto conn = clamp(cmdline.get<int>("conn"), 1, 16);
        const auto cmd_forward = cmdline.has("forward");
        const auto cmd_backward = cmdline.has("backward");
        const auto cmd_mlps = cmdline.has("mlps");
        const auto cmd_convnets = cmdline.has("convnets");
        const auto activation = cmdline.get("activation");
        const auto cmd_detailed = cmdline.has("detailed");

        if (!cmd_forward && !cmd_backward)
        {
                cmdline.usage();
        }

        if (!cmd_mlps && !cmd_convnets)
        {
                cmdline.usage();
        }

        const auto cmd_rows = 28;
        const auto cmd_cols = 28;
        const auto cmd_color = color_mode::luma;

        const size_t cmd_min_nthreads = 1;
        const size_t cmd_max_nthreads = logical_cpus();

        // generate synthetic task
        charset_task_t task(to_params(
                "type", charset_mode::digit, "color", cmd_color, "irows", cmd_rows, "icols", cmd_cols, "count", cmd_samples));
        task.load();

        // construct models
        const string_t mlp0;
        const string_t mlp1 = mlp0 + make_affine_layer(128, activation);
        const string_t mlp2 = mlp1 + make_affine_layer(512, activation);
        const string_t mlp3 = mlp2 + make_affine_layer(128, activation);
        const string_t mlp4 = mlp3 + make_affine_layer(512, activation);
        const string_t mlp5 = mlp4 + make_affine_layer(128, activation);
        const string_t mlp6 = mlp5 + make_affine_layer(512, activation);
        const string_t mlp7 = mlp6 + make_affine_layer(128, activation);

        const string_t convnet0;
        const string_t convnet1 = convnet0 + make_conv_layer(128, 7, 7, 1, activation);
        const string_t convnet2 = convnet1 + make_conv_layer(128, 7, 7, conn, activation);
        const string_t convnet3 = convnet2 + make_conv_layer(128, 5, 5, conn, activation);
        const string_t convnet4 = convnet3 + make_conv_layer(128, 5, 5, conn, activation);
        const string_t convnet5 = convnet4 + make_conv_layer(128, 3, 3, conn, activation);
        const string_t convnet6 = convnet5 + make_conv_layer(128, 3, 3, conn, activation);
        const string_t convnet7 = convnet6 + make_conv_layer(128, 3, 3, conn, activation);

        const string_t outlayer = make_output_layer(task.odims());

        std::vector<std::pair<string_t, string_t>> networks;
        #define DEFINE(config) networks.emplace_back(config + outlayer, NANO_STRINGIFY(config))
        if (cmd_mlps)
        {
                DEFINE(mlp0);
                DEFINE(mlp1);
                DEFINE(mlp2);
                DEFINE(mlp3);
                DEFINE(mlp4);
                DEFINE(mlp5);
                DEFINE(mlp6);
                DEFINE(mlp7);
        }
        if (cmd_convnets)
        {
                DEFINE(convnet1);
                DEFINE(convnet2);
                DEFINE(convnet3);
                DEFINE(convnet4);
                DEFINE(convnet5);
                DEFINE(convnet6);
                DEFINE(convnet7);
        }
        #undef DEFINE

        const auto loss = get_losses().get("logistic");
        const auto criterion = get_criteria().get("avg");

        // construct tables to compare models
        table_t ftable; ftable.header() << "model-forward [us] / sample";
        table_t btable; btable.header() << "model-backward [us] / sample";

        for (size_t nthreads = cmd_min_nthreads; nthreads <= cmd_max_nthreads; ++ nthreads)
        {
                ftable.header() << (to_string(nthreads) + "xCPU");
                btable.header() << (to_string(nthreads) + "xCPU");
        }

        // evaluate models
        for (const auto& config : networks)
        {
                const string_t cmd_network = config.first;
                const string_t cmd_name = config.second;

                // create feed-forward network
                const auto model = get_models().get("forward-network", cmd_network);
                model->configure(task);
                model->random();
                model->describe();

                auto& frow = ftable.append() << (cmd_name + " (" + to_string(model->psize()) + ")");
                auto& brow = btable.append() << (cmd_name + " (" + to_string(model->psize()) + ")");

                const auto fold = fold_t{0, protocol::train};

                std::vector<timings_t> ftimings(cmd_max_nthreads + 1);
                std::vector<timings_t> btimings(cmd_max_nthreads + 1);

                // process the samples
                for (size_t nthreads = cmd_min_nthreads; nthreads <= cmd_max_nthreads; ++ nthreads)
                {
                        accumulator_t acc(*model, *loss, *criterion);
                        acc.lambda(scalar_t(0.1));
                        acc.threads(nthreads);

                        if (cmd_forward)
                        {
                                const auto duration = measure_robustly_usec([&] ()
                                {
                                        acc.mode(criterion_t::type::value);
                                        acc.update(task, fold);
                                }, 1);

                                log_info() << "<<< processed [" << acc.count()
                                           << "] forward samples in " << duration.count() << " us.";

                                frow << idiv(static_cast<size_t>(duration.count()), acc.count());

                                ftimings[nthreads] = acc.timings();
                        }

                        if (cmd_backward)
                        {
                                const auto duration = measure_robustly_usec([&] ()
                                {
                                        acc.mode(criterion_t::type::vgrad);
                                        acc.update(task, fold);
                                }, 1);

                                log_info() << "<<< processed [" << acc.count()
                                           << "] backward samples in " << duration.count() << " us.";

                                brow << idiv(static_cast<size_t>(duration.count()), acc.count());

                                btimings[nthreads] = acc.timings();
                        }
                }

                // detailed per-component (e.g. per-layer) timing information
                const auto print_timings = [&] (table_t& table, const string_t& basename,
                        const std::vector<timings_t>& timings)
                {
                        for (const auto& timing0 : timings[cmd_min_nthreads])
                        {
                                auto& row = table.append();
                                row << (basename + timing0.first);

                                for (size_t nthreads = cmd_min_nthreads; nthreads <= cmd_max_nthreads; ++ nthreads)
                                {
                                        const auto& timingT = timings[nthreads];
                                        assert(timingT.find(timing0.first) != timingT.end());
                                        row << timingT.find(timing0.first)->second.avg();
                                }
                        }
                };

                if (cmd_forward && cmd_detailed)
                {
                        print_timings(ftable, ">", ftimings);
                }

                if (cmd_backward && cmd_detailed)
                {
                        print_timings(btable, ">", btimings);
                }
        }

        // print results
        if (cmd_forward)
        {
                ftable.mark(make_table_mark_minimum_percentage_cols<size_t>(5));
                std::cout << ftable;
        }
        if (cmd_backward)
        {
                btable.mark(make_table_mark_minimum_percentage_cols<size_t>(5));
                std::cout << btable;
        }

        // OK
        return EXIT_SUCCESS;
}
<commit_msg>more compact benchmark table<commit_after>#include "nano.h"
#include "class.h"
#include "measure.h"
#include "text/table.h"
#include "accumulator.h"
#include "text/cmdline.h"
#include "math/random.h"
#include "tensor/numeric.h"
#include "measure_and_log.h"
#include "layers/make_layers.h"
#include "tasks/task_charset.h"
#include "text/table_row_mark.h"
#include <iostream>

int main(int argc, const char *argv[])
{
        using namespace nano;

        // parse the command line
        cmdline_t cmdline("benchmark models");
        cmdline.add("s", "samples",     "number of samples to use [100, 10000]", "1000");
        cmdline.add("c", "conn",        "plane connectivity for convolution networks [1, 16]", "8");
        cmdline.add("", "mlps",         "benchmark MLP models");
        cmdline.add("", "convnets",     "benchmark convolution networks");
        cmdline.add("", "forward",      "evaluate the \'forward\' pass (output)");
        cmdline.add("", "backward",     "evaluate the \'backward' pass (gradient)");
        cmdline.add("", "activation",   "activation layer", "act-snorm");
        cmdline.add("", "detailed",     "print detailed measurements (e.g. per-layer)");

        cmdline.process(argc, argv);

        // check arguments and options
        const auto cmd_samples = clamp(cmdline.get<size_t>("samples"), 100, 100 * 1000);
        const auto conn = clamp(cmdline.get<int>("conn"), 1, 16);
        const auto cmd_forward = cmdline.has("forward");
        const auto cmd_backward = cmdline.has("backward");
        const auto cmd_mlps = cmdline.has("mlps");
        const auto cmd_convnets = cmdline.has("convnets");
        const auto activation = cmdline.get("activation");
        const auto cmd_detailed = cmdline.has("detailed");

        if (!cmd_forward && !cmd_backward)
        {
                cmdline.usage();
        }

        if (!cmd_mlps && !cmd_convnets)
        {
                cmdline.usage();
        }

        const auto cmd_rows = 28;
        const auto cmd_cols = 28;
        const auto cmd_color = color_mode::luma;

        const size_t cmd_min_nthreads = 1;
        const size_t cmd_max_nthreads = logical_cpus();

        // generate synthetic task
        charset_task_t task(to_params(
                "type", charset_mode::digit, "color", cmd_color, "irows", cmd_rows, "icols", cmd_cols, "count", cmd_samples));
        task.load();

        // construct models
        const string_t mlp0;
        const string_t mlp1 = mlp0 + make_affine_layer(128, activation);
        const string_t mlp2 = mlp1 + make_affine_layer(512, activation);
        const string_t mlp3 = mlp2 + make_affine_layer(128, activation);
        const string_t mlp4 = mlp3 + make_affine_layer(512, activation);
        const string_t mlp5 = mlp4 + make_affine_layer(128, activation);
        const string_t mlp6 = mlp5 + make_affine_layer(512, activation);
        const string_t mlp7 = mlp6 + make_affine_layer(128, activation);

        const string_t convnet0;
        const string_t convnet1 = convnet0 + make_conv_layer(128, 7, 7, 1, activation);
        const string_t convnet2 = convnet1 + make_conv_layer(128, 7, 7, conn, activation);
        const string_t convnet3 = convnet2 + make_conv_layer(128, 5, 5, conn, activation);
        const string_t convnet4 = convnet3 + make_conv_layer(128, 5, 5, conn, activation);
        const string_t convnet5 = convnet4 + make_conv_layer(128, 3, 3, conn, activation);
        const string_t convnet6 = convnet5 + make_conv_layer(128, 3, 3, conn, activation);
        const string_t convnet7 = convnet6 + make_conv_layer(128, 3, 3, conn, activation);

        const string_t outlayer = make_output_layer(task.odims());

        std::vector<std::pair<string_t, string_t>> networks;
        #define DEFINE(config) networks.emplace_back(config + outlayer, NANO_STRINGIFY(config))
        if (cmd_mlps)
        {
                DEFINE(mlp0);
                DEFINE(mlp1);
                DEFINE(mlp2);
                DEFINE(mlp3);
                DEFINE(mlp4);
                DEFINE(mlp5);
                DEFINE(mlp6);
                DEFINE(mlp7);
        }
        if (cmd_convnets)
        {
                DEFINE(convnet1);
                DEFINE(convnet2);
                DEFINE(convnet3);
                DEFINE(convnet4);
                DEFINE(convnet5);
                DEFINE(convnet6);
                DEFINE(convnet7);
        }
        #undef DEFINE

        const auto loss = get_losses().get("logistic");
        const auto criterion = get_criteria().get("avg");

        // construct tables to compare models
        table_t ftable; ftable.header() << "forward [us/sample]";
        table_t btable; btable.header() << "backward [us/sample]";

        for (size_t nthreads = cmd_min_nthreads; nthreads <= cmd_max_nthreads; ++ nthreads)
        {
                ftable.header() << (to_string(nthreads) + "xCPU");
                btable.header() << (to_string(nthreads) + "xCPU");
        }

        // evaluate models
        for (const auto& config : networks)
        {
                const string_t cmd_network = config.first;
                const string_t cmd_name = config.second;

                // create feed-forward network
                const auto model = get_models().get("forward-network", cmd_network);
                model->configure(task);
                model->random();
                model->describe();

                auto& frow = ftable.append() << (cmd_name + " (" + to_string(model->psize()) + ")");
                auto& brow = btable.append() << (cmd_name + " (" + to_string(model->psize()) + ")");

                const auto fold = fold_t{0, protocol::train};

                std::vector<timings_t> ftimings(cmd_max_nthreads + 1);
                std::vector<timings_t> btimings(cmd_max_nthreads + 1);

                // process the samples
                for (size_t nthreads = cmd_min_nthreads; nthreads <= cmd_max_nthreads; ++ nthreads)
                {
                        accumulator_t acc(*model, *loss, *criterion);
                        acc.lambda(scalar_t(0.1));
                        acc.threads(nthreads);

                        if (cmd_forward)
                        {
                                const auto duration = measure_robustly_usec([&] ()
                                {
                                        acc.mode(criterion_t::type::value);
                                        acc.update(task, fold);
                                }, 1);

                                log_info() << "<<< processed [" << acc.count()
                                           << "] forward samples in " << duration.count() << " us.";

                                frow << idiv(static_cast<size_t>(duration.count()), acc.count());

                                ftimings[nthreads] = acc.timings();
                        }

                        if (cmd_backward)
                        {
                                const auto duration = measure_robustly_usec([&] ()
                                {
                                        acc.mode(criterion_t::type::vgrad);
                                        acc.update(task, fold);
                                }, 1);

                                log_info() << "<<< processed [" << acc.count()
                                           << "] backward samples in " << duration.count() << " us.";

                                brow << idiv(static_cast<size_t>(duration.count()), acc.count());

                                btimings[nthreads] = acc.timings();
                        }
                }

                // detailed per-component (e.g. per-layer) timing information
                const auto print_timings = [&] (table_t& table, const string_t& basename,
                        const std::vector<timings_t>& timings)
                {
                        for (const auto& timing0 : timings[cmd_min_nthreads])
                        {
                                auto& row = table.append();
                                row << (basename + timing0.first);

                                for (size_t nthreads = cmd_min_nthreads; nthreads <= cmd_max_nthreads; ++ nthreads)
                                {
                                        const auto& timingT = timings[nthreads];
                                        assert(timingT.find(timing0.first) != timingT.end());
                                        row << timingT.find(timing0.first)->second.avg();
                                }
                        }
                };

                if (cmd_forward && cmd_detailed)
                {
                        print_timings(ftable, ">", ftimings);
                }

                if (cmd_backward && cmd_detailed)
                {
                        print_timings(btable, ">", btimings);
                }
        }

        // print results
        if (cmd_forward)
        {
                ftable.mark(make_table_mark_minimum_percentage_cols<size_t>(5));
                std::cout << ftable;
        }
        if (cmd_backward)
        {
                btable.mark(make_table_mark_minimum_percentage_cols<size_t>(5));
                std::cout << btable;
        }

        // OK
        return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * LinearTransferFunction.cpp
 *
 * Copyright (C) 2008 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "vislib/graphics/gl/IncludeAllGL.h"
#include "mmcore/view/LinearTransferFunction.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include "mmcore/param/BoolParam.h"
#include "mmcore/param/FloatParam.h"
#include "mmcore/param/IntParam.h"
#include "mmcore/param/StringParam.h"
#include "mmcore/param/FilePathParam.h"
#include "mmcore/param/ButtonParam.h"
#include "mmcore/utility/ColourParser.h"
#include "vislib/Array.h"
#include "vislib/assert.h"
#include "vislib/math/Vector.h"
#include "vislib/sys/sysfunctions.h"
#include "vislib/sys/Log.h"

namespace megamol {
namespace core {
namespace view {

    static int InterColourComparer(const vislib::math::Vector<float, 5>& lhs,
            const vislib::math::Vector<float, 5>& rhs) {
        if (lhs[4] >= rhs[4]) {
            if (rhs[4] + vislib::math::FLOAT_EPSILON >= lhs[4]) {
                return 0;
            } else {
                return 1;
            }
        } else {
            if (lhs[4] + vislib::math::FLOAT_EPSILON >= rhs[4]) {
                return 0;
            } else {
                return -1;
            }
        }
    }

} /* end namespace view */
} /* end namespace core */
} /* end namespace megamol */

using namespace megamol::core;

/*
 * view::LinearTransferFunction::LinearTransferFunction
 */
view::LinearTransferFunction::LinearTransferFunction(void) : Module(),
        getTFSlot("gettransferfunction", "Provides the transfer function"),
        minColSlot("mincolour", "The colour for the minimum value"),
        maxColSlot("maxcolour", "The colour for the maximum value"),
        texSizeSlot("texsize", "The size of the texture to generate"),
        pathSlot("filepath", "path for serializing the TF"),
        loadTFSlot("loadTF", "trigger loading from file"),
        storeTFSlot("storeTF", "trigger saving to file"),
        texID(0), texSize(1),
        texFormat(CallGetTransferFunction::TEXTURE_FORMAT_RGB),
        firstRequest(true) {

    view::CallGetTransferFunctionDescription cgtfd;
    this->getTFSlot.SetCallback(cgtfd.ClassName(), cgtfd.FunctionName(0),
        &LinearTransferFunction::requestTF);
    this->MakeSlotAvailable(&this->getTFSlot);

    this->minColSlot << new param::StringParam("blue");
    this->MakeSlotAvailable(&this->minColSlot);

    vislib::StringA t1, t2;
    for (SIZE_T i = 0; i < INTER_COLOUR_COUNT; i++) {
        t1.Format("enable%.2d", i + 1);
        t2.Format("Enables the intermediate colour %d", i + 1);
        this->interCols[i].enableSlot = new param::ParamSlot(t1, t2);
        this->interCols[i].enableSlot->SetParameter(new param::BoolParam(false));
        this->MakeSlotAvailable(this->interCols[i].enableSlot);

        t1.Format("colour%.2d", i + 1);
        t2.Format("The colour for the intermediate value no. %d", i + 1);
        this->interCols[i].colSlot = new param::ParamSlot(t1, t2);
        this->interCols[i].colSlot->SetParameter(new param::StringParam("Gray"));
        this->MakeSlotAvailable(this->interCols[i].colSlot);

        t1.Format("value%.2d", i + 1);
        t2.Format("The intermediate value no. %d", i + 1);
        this->interCols[i].valSlot = new param::ParamSlot(t1, t2);
        this->interCols[i].valSlot->SetParameter(new param::FloatParam(
            static_cast<float>(i + 1) / static_cast<float>(INTER_COLOUR_COUNT + 1),
            0.0f, 1.0f));
        this->MakeSlotAvailable(this->interCols[i].valSlot);
    }

    this->maxColSlot << new param::StringParam("red");
    this->MakeSlotAvailable(&this->maxColSlot);
    this->maxColSlot.ForceSetDirty();

    this->texSizeSlot << new param::IntParam(128, 2, 1024);
    this->MakeSlotAvailable(&this->texSizeSlot);

    this->pathSlot << new param::FilePathParam("");
    this->MakeSlotAvailable(&this->pathSlot);

    this->loadTFSlot << new param::ButtonParam();
    this->loadTFSlot.SetUpdateCallback(&LinearTransferFunction::loadTFPressed);
    this->MakeSlotAvailable(&this->loadTFSlot);

    this->storeTFSlot << new param::ButtonParam();
    this->storeTFSlot.SetUpdateCallback(&LinearTransferFunction::storeTFPressed);
    this->MakeSlotAvailable(&this->storeTFSlot);
}

/*
 * view::LinearTransferFunction::~LinearTransferFunction
 */
view::LinearTransferFunction::~LinearTransferFunction(void) {
    this->Release();
}

/*
 * view::LinearTransferFunction::create
 */
bool view::LinearTransferFunction::create(void) {
    firstRequest = true;
    return true;
}

/*
 * view::LinearTransferFunction::release
 */
void view::LinearTransferFunction::release(void) {
    ::glDeleteTextures(1, &this->texID);
    this->texID = 0;
}

/*
 * view::LinearTransferFunction::loadTFPressed
 */
bool view::LinearTransferFunction::loadTFPressed(param::ParamSlot& param) {
    try {
        vislib::sys::BufferedFile inFile;
        if (!inFile.Open(pathSlot.Param<param::FilePathParam>()->Value(),
            vislib::sys::File::AccessMode::READ_ONLY,
            vislib::sys::File::ShareMode::SHARE_READ,
            vislib::sys::File::CreationMode::OPEN_ONLY)) {
            vislib::sys::Log::DefaultLog.WriteMsg(
                vislib::sys::Log::LEVEL_WARN,
                "Unable to open TF file.");
            // failed, but does not matter here
            return true;
        }

        while (!inFile.IsEOF()) {
            vislib::StringA line = vislib::sys::ReadLineFromFileA(inFile);
            line.TrimSpaces();
            if (line.IsEmpty()) continue;
            if (line[0] == '#') continue;
            vislib::StringA::Size pos = line.Find('=');
            vislib::StringA name = line.Substring(0, pos);
            vislib::StringA value = line.Substring(pos + 1);
            Module::child_list_type::iterator ano_end = this->ChildList_End();
            for (Module::child_list_type::iterator ano_i = this->ChildList_Begin(); ano_i != ano_end; ++ano_i) {
                std::shared_ptr<param::ParamSlot> p = std::dynamic_pointer_cast<param::ParamSlot>(*ano_i);
                if (p && p->Name().Equals(name)) {
                    p->Parameter()->ParseValue(value);
                }
            }
        }
        inFile.Close();
    } catch (...) {

    }

    return true;
}

/*
 * view::LinearTransferFunction::requestTF
 */
bool view::LinearTransferFunction::requestTF(Call& call) {
    view::CallGetTransferFunction *cgtf = dynamic_cast<view::CallGetTransferFunction*>(&call);
    if (cgtf == NULL) return false;

    if (firstRequest) {
        loadTFPressed(loadTFSlot);
    }

    bool dirty = this->minColSlot.IsDirty() || this->maxColSlot.IsDirty() || this->texSizeSlot.IsDirty();
    for (SIZE_T i = 0; !dirty && (i < INTER_COLOUR_COUNT); i++) {
        dirty = this->interCols[i].enableSlot->IsDirty()
            || this->interCols[i].colSlot->IsDirty()
            || this->interCols[i].valSlot->IsDirty();
    }
    if ((this->texID == 0) || dirty) {
        this->minColSlot.ResetDirty();
        this->maxColSlot.ResetDirty();
        this->texSizeSlot.ResetDirty();
        for (SIZE_T i = 0; i < INTER_COLOUR_COUNT; i++) {
            this->interCols[i].enableSlot->ResetDirty();
            this->interCols[i].colSlot->ResetDirty();
            this->interCols[i].valSlot->ResetDirty();
        }

        bool t1de = (glIsEnabled(GL_TEXTURE_1D) == GL_TRUE);
        if (!t1de) glEnable(GL_TEXTURE_1D);
        if (this->texID == 0) glGenTextures(1, &this->texID);

        vislib::Array<vislib::math::Vector<float, 5> > cols;
        vislib::math::Vector<float, 5> cx1, cx2;
        bool validAlpha = false;
        if (utility::ColourParser::FromString(
                this->minColSlot.Param<param::StringParam>()->Value(),
                cx1[0], cx1[1], cx1[2], cx1[3])) {
            cx1[4] = 0.0f;
        } else {
            cx1[0] = cx1[1] = cx1[2] = cx1[3] = 0.0f;
            cx1[4] = 0.0f;
        }
        if (cx1[3] < 0.99f) validAlpha = true;
        cols.Add(cx1);
        if (utility::ColourParser::FromString(
                this->maxColSlot.Param<param::StringParam>()->Value(),
                cx1[0], cx1[1], cx1[2], cx1[3])) {
            cx1[4] = 1.0f;
        } else {
            cx1[0] = cx1[1] = cx1[2] = cx1[3] = 0.0f;
            cx1[4] = 1.0f;
        }
        if (cx1[3] < 0.99f) validAlpha = true;
        cols.Add(cx1);
        for (SIZE_T i = 0; i < INTER_COLOUR_COUNT; i++) {
            if (this->interCols[i].enableSlot->Param<param::BoolParam>()->Value()) {
                float val = this->interCols[i].valSlot->Param<param::FloatParam>()->Value();
                if (utility::ColourParser::FromString(
                        this->interCols[i].colSlot->Param<param::StringParam>()->Value(),
                        cx1[0], cx1[1], cx1[2], cx1[3])) {
                    cx1[4] = val;
                } else {
                    cx1[0] = cx1[1] = cx1[2] = cx1[3] = 0.0f;
                    cx1[4] = val;
                }
                if (cx1[3] < 0.99f) validAlpha = true;
                cols.Add(cx1);
            }
        }

        cols.Sort(&InterColourComparer);

        this->texSize = this->texSizeSlot.Param<param::IntParam>()->Value();
        float *tex = new float[4 * this->texSize];
        int p1, p2;

        cx2 = cols[0];
        p2 = 0;
        for (SIZE_T i = 1; i < cols.Count(); i++) {
            cx1 = cx2;
            p1 = p2;
            cx2 = cols[i];
            ASSERT(cx2[4] <= 1.0f + vislib::math::FLOAT_EPSILON);
            p2 = static_cast<int>(cx2[4] * static_cast<float>(this->texSize - 1));
            ASSERT(p2 < static_cast<int>(this->texSize));
            ASSERT(p2 >= p1);

            for (int p = p1; p <= p2; p++) {
                float al = static_cast<float>(p - p1) / static_cast<float>(p2 - p1);
                float be = 1.0f - al;

                tex[p * 4] = cx1[0] * be + cx2[0] * al;
                tex[p * 4 + 1] = cx1[1] * be + cx2[1] * al;
                tex[p * 4 + 2] = cx1[2] * be + cx2[2] * al;
                tex[p * 4 + 3] = cx1[3] * be + cx2[3] * al;
            }
        }

        GLint otid = 0;
        glGetIntegerv(GL_TEXTURE_BINDING_1D, &otid);
        glBindTexture(GL_TEXTURE_1D, this->texID);

        glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, this->texSize, 0, GL_RGBA, GL_FLOAT, tex);

        delete[] tex;

        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);

        glBindTexture(GL_TEXTURE_1D, otid);

        if (!t1de) glDisable(GL_TEXTURE_1D);

        this->texFormat = validAlpha
            ? CallGetTransferFunction::TEXTURE_FORMAT_RGBA
            : CallGetTransferFunction::TEXTURE_FORMAT_RGB;

    }

    cgtf->SetTexture(this->texID, this->texSize, this->texFormat);

    return true;
}

/*
* view::LinearTransferFunction::storeTFPressed
*/
bool view::LinearTransferFunction::storeTFPressed(param::ParamSlot& param) {

    try {
        vislib::sys::BufferedFile outFile;
        if (!outFile.Open(pathSlot.Param<param::FilePathParam>()->Value(),
            vislib::sys::File::AccessMode::WRITE_ONLY,
            vislib::sys::File::ShareMode::SHARE_EXCLUSIVE,
            vislib::sys::File::CreationMode::CREATE_OVERWRITE)) {
            vislib::sys::Log::DefaultLog.WriteMsg(
                vislib::sys::Log::LEVEL_WARN,
                "Unable to create TF file.");
        }

        Module::child_list_type::iterator ano_end = this->ChildList_End();
        for (Module::child_list_type::iterator ano_i = this->ChildList_Begin(); ano_i != ano_end; ++ano_i) {
            std::shared_ptr<param::ParamSlot> p = std::dynamic_pointer_cast<param::ParamSlot>(*ano_i);
            if (p && !p->Name().Equals("filepath")) {
                writeParameterFileParameter(*p, outFile);
            }
        }
        outFile.Close();
    } catch (...) {

    }

    return true;
}

/*
* view::LinearTransferFunction::writeParameterFileParameter
*/
void view::LinearTransferFunction::writeParameterFileParameter(
    param::ParamSlot& param,
    vislib::sys::BufferedFile &outFile) {

    unsigned int len = 0;
    vislib::RawStorage store;
    param.Parameter()->Definition(store);

    if (::memcmp(store, "MMBUTN", 6) == 0) {
        outFile.Write("# ", 2);
    }

    vislib::sys::WriteFormattedLineToFile(outFile,
        "%s=%s\n", param.Name().PeekBuffer(), vislib::StringA(param.Parameter()->ValueString()).PeekBuffer());
}
<commit_msg>Arg. Forgot to reset a flag<commit_after>/*
 * LinearTransferFunction.cpp
 *
 * Copyright (C) 2008 by Universitaet Stuttgart (VIS).
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "vislib/graphics/gl/IncludeAllGL.h"
#include "mmcore/view/LinearTransferFunction.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include "mmcore/param/BoolParam.h"
#include "mmcore/param/FloatParam.h"
#include "mmcore/param/IntParam.h"
#include "mmcore/param/StringParam.h"
#include "mmcore/param/FilePathParam.h"
#include "mmcore/param/ButtonParam.h"
#include "mmcore/utility/ColourParser.h"
#include "vislib/Array.h"
#include "vislib/assert.h"
#include "vislib/math/Vector.h"
#include "vislib/sys/sysfunctions.h"
#include "vislib/sys/Log.h"

namespace megamol {
namespace core {
namespace view {

    static int InterColourComparer(const vislib::math::Vector<float, 5>& lhs,
            const vislib::math::Vector<float, 5>& rhs) {
        if (lhs[4] >= rhs[4]) {
            if (rhs[4] + vislib::math::FLOAT_EPSILON >= lhs[4]) {
                return 0;
            } else {
                return 1;
            }
        } else {
            if (lhs[4] + vislib::math::FLOAT_EPSILON >= rhs[4]) {
                return 0;
            } else {
                return -1;
            }
        }
    }

} /* end namespace view */
} /* end namespace core */
} /* end namespace megamol */

using namespace megamol::core;

/*
 * view::LinearTransferFunction::LinearTransferFunction
 */
view::LinearTransferFunction::LinearTransferFunction(void) : Module(),
        getTFSlot("gettransferfunction", "Provides the transfer function"),
        minColSlot("mincolour", "The colour for the minimum value"),
        maxColSlot("maxcolour", "The colour for the maximum value"),
        texSizeSlot("texsize", "The size of the texture to generate"),
        pathSlot("filepath", "path for serializing the TF"),
        loadTFSlot("loadTF", "trigger loading from file"),
        storeTFSlot("storeTF", "trigger saving to file"),
        texID(0), texSize(1),
        texFormat(CallGetTransferFunction::TEXTURE_FORMAT_RGB),
        firstRequest(true) {

    view::CallGetTransferFunctionDescription cgtfd;
    this->getTFSlot.SetCallback(cgtfd.ClassName(), cgtfd.FunctionName(0),
        &LinearTransferFunction::requestTF);
    this->MakeSlotAvailable(&this->getTFSlot);

    this->minColSlot << new param::StringParam("blue");
    this->MakeSlotAvailable(&this->minColSlot);

    vislib::StringA t1, t2;
    for (SIZE_T i = 0; i < INTER_COLOUR_COUNT; i++) {
        t1.Format("enable%.2d", i + 1);
        t2.Format("Enables the intermediate colour %d", i + 1);
        this->interCols[i].enableSlot = new param::ParamSlot(t1, t2);
        this->interCols[i].enableSlot->SetParameter(new param::BoolParam(false));
        this->MakeSlotAvailable(this->interCols[i].enableSlot);

        t1.Format("colour%.2d", i + 1);
        t2.Format("The colour for the intermediate value no. %d", i + 1);
        this->interCols[i].colSlot = new param::ParamSlot(t1, t2);
        this->interCols[i].colSlot->SetParameter(new param::StringParam("Gray"));
        this->MakeSlotAvailable(this->interCols[i].colSlot);

        t1.Format("value%.2d", i + 1);
        t2.Format("The intermediate value no. %d", i + 1);
        this->interCols[i].valSlot = new param::ParamSlot(t1, t2);
        this->interCols[i].valSlot->SetParameter(new param::FloatParam(
            static_cast<float>(i + 1) / static_cast<float>(INTER_COLOUR_COUNT + 1),
            0.0f, 1.0f));
        this->MakeSlotAvailable(this->interCols[i].valSlot);
    }

    this->maxColSlot << new param::StringParam("red");
    this->MakeSlotAvailable(&this->maxColSlot);
    this->maxColSlot.ForceSetDirty();

    this->texSizeSlot << new param::IntParam(128, 2, 1024);
    this->MakeSlotAvailable(&this->texSizeSlot);

    this->pathSlot << new param::FilePathParam("");
    this->MakeSlotAvailable(&this->pathSlot);

    this->loadTFSlot << new param::ButtonParam();
    this->loadTFSlot.SetUpdateCallback(&LinearTransferFunction::loadTFPressed);
    this->MakeSlotAvailable(&this->loadTFSlot);

    this->storeTFSlot << new param::ButtonParam();
    this->storeTFSlot.SetUpdateCallback(&LinearTransferFunction::storeTFPressed);
    this->MakeSlotAvailable(&this->storeTFSlot);
}

/*
 * view::LinearTransferFunction::~LinearTransferFunction
 */
view::LinearTransferFunction::~LinearTransferFunction(void) {
    this->Release();
}

/*
 * view::LinearTransferFunction::create
 */
bool view::LinearTransferFunction::create(void) {
    firstRequest = true;
    return true;
}

/*
 * view::LinearTransferFunction::release
 */
void view::LinearTransferFunction::release(void) {
    ::glDeleteTextures(1, &this->texID);
    this->texID = 0;
}

/*
 * view::LinearTransferFunction::loadTFPressed
 */
bool view::LinearTransferFunction::loadTFPressed(param::ParamSlot& param) {
    try {
        vislib::sys::BufferedFile inFile;
        if (!inFile.Open(pathSlot.Param<param::FilePathParam>()->Value(),
            vislib::sys::File::AccessMode::READ_ONLY,
            vislib::sys::File::ShareMode::SHARE_READ,
            vislib::sys::File::CreationMode::OPEN_ONLY)) {
            vislib::sys::Log::DefaultLog.WriteMsg(
                vislib::sys::Log::LEVEL_WARN,
                "Unable to open TF file.");
            // failed, but does not matter here
            return true;
        }

        while (!inFile.IsEOF()) {
            vislib::StringA line = vislib::sys::ReadLineFromFileA(inFile);
            line.TrimSpaces();
            if (line.IsEmpty()) continue;
            if (line[0] == '#') continue;
            vislib::StringA::Size pos = line.Find('=');
            vislib::StringA name = line.Substring(0, pos);
            vislib::StringA value = line.Substring(pos + 1);
            Module::child_list_type::iterator ano_end = this->ChildList_End();
            for (Module::child_list_type::iterator ano_i = this->ChildList_Begin(); ano_i != ano_end; ++ano_i) {
                std::shared_ptr<param::ParamSlot> p = std::dynamic_pointer_cast<param::ParamSlot>(*ano_i);
                if (p && p->Name().Equals(name)) {
                    p->Parameter()->ParseValue(value);
                }
            }
        }
        inFile.Close();
    } catch (...) {

    }

    return true;
}

/*
 * view::LinearTransferFunction::requestTF
 */
bool view::LinearTransferFunction::requestTF(Call& call) {
    view::CallGetTransferFunction *cgtf = dynamic_cast<view::CallGetTransferFunction*>(&call);
    if (cgtf == NULL) return false;

    if (firstRequest) {
        loadTFPressed(loadTFSlot);
        firstRequest = false;
    }

    bool dirty = this->minColSlot.IsDirty() || this->maxColSlot.IsDirty() || this->texSizeSlot.IsDirty();
    for (SIZE_T i = 0; !dirty && (i < INTER_COLOUR_COUNT); i++) {
        dirty = this->interCols[i].enableSlot->IsDirty()
            || this->interCols[i].colSlot->IsDirty()
            || this->interCols[i].valSlot->IsDirty();
    }
    if ((this->texID == 0) || dirty) {
        this->minColSlot.ResetDirty();
        this->maxColSlot.ResetDirty();
        this->texSizeSlot.ResetDirty();
        for (SIZE_T i = 0; i < INTER_COLOUR_COUNT; i++) {
            this->interCols[i].enableSlot->ResetDirty();
            this->interCols[i].colSlot->ResetDirty();
            this->interCols[i].valSlot->ResetDirty();
        }

        bool t1de = (glIsEnabled(GL_TEXTURE_1D) == GL_TRUE);
        if (!t1de) glEnable(GL_TEXTURE_1D);
        if (this->texID == 0) glGenTextures(1, &this->texID);

        vislib::Array<vislib::math::Vector<float, 5> > cols;
        vislib::math::Vector<float, 5> cx1, cx2;
        bool validAlpha = false;
        if (utility::ColourParser::FromString(
                this->minColSlot.Param<param::StringParam>()->Value(),
                cx1[0], cx1[1], cx1[2], cx1[3])) {
            cx1[4] = 0.0f;
        } else {
            cx1[0] = cx1[1] = cx1[2] = cx1[3] = 0.0f;
            cx1[4] = 0.0f;
        }
        if (cx1[3] < 0.99f) validAlpha = true;
        cols.Add(cx1);
        if (utility::ColourParser::FromString(
                this->maxColSlot.Param<param::StringParam>()->Value(),
                cx1[0], cx1[1], cx1[2], cx1[3])) {
            cx1[4] = 1.0f;
        } else {
            cx1[0] = cx1[1] = cx1[2] = cx1[3] = 0.0f;
            cx1[4] = 1.0f;
        }
        if (cx1[3] < 0.99f) validAlpha = true;
        cols.Add(cx1);
        for (SIZE_T i = 0; i < INTER_COLOUR_COUNT; i++) {
            if (this->interCols[i].enableSlot->Param<param::BoolParam>()->Value()) {
                float val = this->interCols[i].valSlot->Param<param::FloatParam>()->Value();
                if (utility::ColourParser::FromString(
                        this->interCols[i].colSlot->Param<param::StringParam>()->Value(),
                        cx1[0], cx1[1], cx1[2], cx1[3])) {
                    cx1[4] = val;
                } else {
                    cx1[0] = cx1[1] = cx1[2] = cx1[3] = 0.0f;
                    cx1[4] = val;
                }
                if (cx1[3] < 0.99f) validAlpha = true;
                cols.Add(cx1);
            }
        }

        cols.Sort(&InterColourComparer);

        this->texSize = this->texSizeSlot.Param<param::IntParam>()->Value();
        float *tex = new float[4 * this->texSize];
        int p1, p2;

        cx2 = cols[0];
        p2 = 0;
        for (SIZE_T i = 1; i < cols.Count(); i++) {
            cx1 = cx2;
            p1 = p2;
            cx2 = cols[i];
            ASSERT(cx2[4] <= 1.0f + vislib::math::FLOAT_EPSILON);
            p2 = static_cast<int>(cx2[4] * static_cast<float>(this->texSize - 1));
            ASSERT(p2 < static_cast<int>(this->texSize));
            ASSERT(p2 >= p1);

            for (int p = p1; p <= p2; p++) {
                float al = static_cast<float>(p - p1) / static_cast<float>(p2 - p1);
                float be = 1.0f - al;

                tex[p * 4] = cx1[0] * be + cx2[0] * al;
                tex[p * 4 + 1] = cx1[1] * be + cx2[1] * al;
                tex[p * 4 + 2] = cx1[2] * be + cx2[2] * al;
                tex[p * 4 + 3] = cx1[3] * be + cx2[3] * al;
            }
        }

        GLint otid = 0;
        glGetIntegerv(GL_TEXTURE_BINDING_1D, &otid);
        glBindTexture(GL_TEXTURE_1D, this->texID);

        glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, this->texSize, 0, GL_RGBA, GL_FLOAT, tex);

        delete[] tex;

        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);

        glBindTexture(GL_TEXTURE_1D, otid);

        if (!t1de) glDisable(GL_TEXTURE_1D);

        this->texFormat = validAlpha
            ? CallGetTransferFunction::TEXTURE_FORMAT_RGBA
            : CallGetTransferFunction::TEXTURE_FORMAT_RGB;

    }

    cgtf->SetTexture(this->texID, this->texSize, this->texFormat);

    return true;
}

/*
* view::LinearTransferFunction::storeTFPressed
*/
bool view::LinearTransferFunction::storeTFPressed(param::ParamSlot& param) {

    try {
        vislib::sys::BufferedFile outFile;
        if (!outFile.Open(pathSlot.Param<param::FilePathParam>()->Value(),
            vislib::sys::File::AccessMode::WRITE_ONLY,
            vislib::sys::File::ShareMode::SHARE_EXCLUSIVE,
            vislib::sys::File::CreationMode::CREATE_OVERWRITE)) {
            vislib::sys::Log::DefaultLog.WriteMsg(
                vislib::sys::Log::LEVEL_WARN,
                "Unable to create TF file.");
        }

        Module::child_list_type::iterator ano_end = this->ChildList_End();
        for (Module::child_list_type::iterator ano_i = this->ChildList_Begin(); ano_i != ano_end; ++ano_i) {
            std::shared_ptr<param::ParamSlot> p = std::dynamic_pointer_cast<param::ParamSlot>(*ano_i);
            if (p && !p->Name().Equals("filepath")) {
                writeParameterFileParameter(*p, outFile);
            }
        }
        outFile.Close();
    } catch (...) {

    }

    return true;
}

/*
* view::LinearTransferFunction::writeParameterFileParameter
*/
void view::LinearTransferFunction::writeParameterFileParameter(
    param::ParamSlot& param,
    vislib::sys::BufferedFile &outFile) {

    unsigned int len = 0;
    vislib::RawStorage store;
    param.Parameter()->Definition(store);

    if (::memcmp(store, "MMBUTN", 6) == 0) {
        outFile.Write("# ", 2);
    }

    vislib::sys::WriteFormattedLineToFile(outFile,
        "%s=%s\n", param.Name().PeekBuffer(), vislib::StringA(param.Parameter()->ValueString()).PeekBuffer());
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2008 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "colcopy.h"

#include "akonadiconnection.h"
#include "handlerhelper.h"
#include "storage/datastore.h"
#include "storage/transaction.h"
#include "storage/itemretriever.h"
#include "imapstreamparser.h"

using namespace Akonadi;

bool ColCopy::copyCollection(const Collection & source, const Collection & target)
{
  // copy the source collection
  Collection col = source;
  col.setParentId( target.id() );
  col.setResourceId( target.resourceId() );
  // clear remote id and revision on inter-resource copies
  if ( source.resourceId() != target.resourceId() ) {
    col.setRemoteId( QString() );
    col.setRemoteRevision( QString() );
  }

  DataStore *db = connection()->storageBackend();
  if ( !db->appendCollection( col ) )
    return false;

  foreach ( const MimeType &mt, source.mimeTypes() ) {
    if ( !col.addMimeType( mt ) )
      return false;
  }

  foreach ( const CollectionAttribute &attr, source.attributes() ) {
    CollectionAttribute newAttr = attr;
    newAttr.setId( -1 );
    newAttr.setCollectionId( col.id() );
    if ( !newAttr.insert() )
      return false;
  }

  // copy sub-collections
  foreach ( const Collection &child, source.children() ) {
    if ( !copyCollection( child, col ) )
      return false;
  }

  // copy items
  foreach ( const PimItem &item, source.items() ) {
    if ( !copyItem( item, col ) )
      return false;
  }

  return true;
}

bool ColCopy::parseStream()
{
  QByteArray tmp =  m_streamParser->readString();
  const Collection source = HandlerHelper::collectionFromIdOrName( tmp );
  if ( !source.isValid() )
    return failureResponse( "No valid source specified" );

  tmp =  m_streamParser->readString();
  const Collection target = HandlerHelper::collectionFromIdOrName( tmp );
  if ( !target.isValid() )
    return failureResponse( "No valid target specified" );

  // retrieve all not yet cached items of the source
  ItemRetriever retriever( connection() );
  retriever.setCollection( source, true );
  retriever.setRetrieveFullPayload( true );
  retriever.exec();

  DataStore *store = connection()->storageBackend();
  Transaction transaction( store );

  if ( !copyCollection( source, target ) )
    return failureResponse( "Failed to copy collection" );

  if ( !transaction.commit() )
    return failureResponse( "Cannot commit transaction." );

  return successResponse( "COLCOPY complete" );
}

#include "colcopy.moc"
<commit_msg>Don't crash when copying a folder into itself.<commit_after>/*
    Copyright (c) 2008 Volker Krause <vkrause@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "colcopy.h"

#include "akonadiconnection.h"
#include "handlerhelper.h"
#include "storage/datastore.h"
#include "storage/transaction.h"
#include "storage/itemretriever.h"
#include "storage/collectionqueryhelper.h"
#include "imapstreamparser.h"

using namespace Akonadi;

bool ColCopy::copyCollection(const Collection & source, const Collection & target)
{
  if ( !CollectionQueryHelper::canBeMovedTo( source, target ) ) {
    // We don't accept source==target, or source being an ancestor of target.
    return false;
  }

  // copy the source collection
  Collection col = source;
  col.setParentId( target.id() );
  col.setResourceId( target.resourceId() );
  // clear remote id and revision on inter-resource copies
  if ( source.resourceId() != target.resourceId() ) {
    col.setRemoteId( QString() );
    col.setRemoteRevision( QString() );
  }

  DataStore *db = connection()->storageBackend();
  if ( !db->appendCollection( col ) )
    return false;

  foreach ( const MimeType &mt, source.mimeTypes() ) {
    if ( !col.addMimeType( mt ) )
      return false;
  }

  foreach ( const CollectionAttribute &attr, source.attributes() ) {
    CollectionAttribute newAttr = attr;
    newAttr.setId( -1 );
    newAttr.setCollectionId( col.id() );
    if ( !newAttr.insert() )
      return false;
  }

  // copy sub-collections
  foreach ( const Collection &child, source.children() ) {
    if ( !copyCollection( child, col ) )
      return false;
  }

  // copy items
  foreach ( const PimItem &item, source.items() ) {
    if ( !copyItem( item, col ) )
      return false;
  }

  return true;
}

bool ColCopy::parseStream()
{
  QByteArray tmp =  m_streamParser->readString();
  const Collection source = HandlerHelper::collectionFromIdOrName( tmp );
  if ( !source.isValid() )
    return failureResponse( "No valid source specified" );

  tmp =  m_streamParser->readString();
  const Collection target = HandlerHelper::collectionFromIdOrName( tmp );
  if ( !target.isValid() )
    return failureResponse( "No valid target specified" );

  // retrieve all not yet cached items of the source
  ItemRetriever retriever( connection() );
  retriever.setCollection( source, true );
  retriever.setRetrieveFullPayload( true );
  retriever.exec();

  DataStore *store = connection()->storageBackend();
  Transaction transaction( store );

  if ( !copyCollection( source, target ) )
    return failureResponse( "Failed to copy collection" );

  if ( !transaction.commit() )
    return failureResponse( "Cannot commit transaction." );

  return successResponse( "COLCOPY complete" );
}

#include "colcopy.moc"
<|endoftext|>


<commit_before><commit_msg>Add solution of prob 1<commit_after>#include <stdio.h>
#include <stdlib.h>

#define EMPTY   0
#define BLOCK   1
#define VISITED 2

struct board
{
    int size;
    int x, y;
    int **board;
};

struct board game;
int x, y;

void make_board(const char *filename)
{
    FILE *fp = fopen(filename, "r");
    fscanf(fp, "%d %d %d %d %d", &game.size, &x, &y, &game.x, &game.y);
    game.board = (int **)malloc(sizeof(int *) * game.size);

    for(int row = 0; row < game.size; row++)
    {
        game.board[row] = (int *)malloc(sizeof(int) * game.size);
        for(int col = 0; col < game.size; col++)
        {
            int in;
            fscanf(fp, "%d", &in);
            game.board[row][col] = ((in == 0) ? EMPTY : BLOCK);
        }
    }
}

void free_board(void)
{
    for(int row = 0; row < game.size; row++)
        free(game.board[row]);
    free(game.board);
}

bool is_empty(const int x, const int y, const bool flag = false)
{
    if(x < 0 || x >= game.size || y < 0 || y >= game.size) return false;
    if(game.board[x][y] == EMPTY || flag && game.board[x][y] == VISITED) return true;
    return false;
}

bool is_horse_able_to_move(const int x, const int y)
{
    /* base case */
    if(x == game.x && y == game.y) return true;
    if(! is_empty(x, y)) return false;

    /* recursive case */
    game.board[x][y] = VISITED;
    if(is_empty(x - 1, y    , true) && (is_horse_able_to_move(x - 2, y - 1) || is_horse_able_to_move(x - 2, y + 1))) return true;
    if(is_empty(x    , y + 1, true) && (is_horse_able_to_move(x - 1, y + 2) || is_horse_able_to_move(x + 1, y + 2))) return true;
    if(is_empty(x + 1, y    , true) && (is_horse_able_to_move(x + 2, y + 1) || is_horse_able_to_move(x + 2, y - 1))) return true;
    if(is_empty(x    , y - 1, true) && (is_horse_able_to_move(x + 1, y - 2) || is_horse_able_to_move(x - 1, y - 2))) return true;

    return false;
}

int main(void)
{
    make_board("resources/01input.txt");
    printf("%d\n", is_horse_able_to_move(0, 0));
    free_board();
    return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define DIR_SE  3
#define DIR_S   4
#define DIR_SW  5

bool is_able_to_set(const int x, const int y, const int dir = -1);
int count_n_queens(const int x, const int y);

int n;
int *board;

int main(void)
{
    for(n = 1; n <= 15; n++)
    {
        board = (int *)malloc(sizeof(int) * n);
        memset(board, 0, sizeof(int) * n);

        printf("N(%d) Result=%d\n", n, count_n_queens(n, n));
        free(board);
    }

    return 0;
}

bool is_able_to_set(const int x, const int y, const int dir)
{
    /* base case */
    if(x < 1 || x > n || y < 1 || y > n) return true;
    if(board[x - 1] == y) return false; /* queen is exist */

    /* recursive case */
    switch(dir)
    {
    case DIR_SE: return is_able_to_set(x + 1, y + 1, DIR_SE);
    case DIR_S : return is_able_to_set(x + 1, y    , DIR_S );
    case DIR_SW: return is_able_to_set(x + 1, y - 1, DIR_SW);
    default: /* re-call with a direction */
        if(
            is_able_to_set(x, y, DIR_SE) &&
            is_able_to_set(x, y, DIR_S ) &&
            is_able_to_set(x, y, DIR_SW)
        ) return true;
        return false;
    }
}

int b_add(const int x, const int y)
{
    board[x - 1] = y; /* 0 MEANS EMPTY */
    return 0;
}

int b_rm(const int x)
{
    board[x - 1] = 0; /* 0 MEANS EMPTY */
    return 0;
}

int count_n_queens(const int x, const int y)
{
    /* base case */
    if(y < 1) return 0;

    /* recursive case */
    if(is_able_to_set(x, y))
    {
        if(x - 1 >= 1)                  return count_n_queens(x, y - 1) + b_add(x, y) + count_n_queens(x - 1, ::n) + b_rm(x);
        if(is_able_to_set(x - 1, ::n))  return count_n_queens(x, y - 1) + 1;
    }
    return count_n_queens(x, y - 1);
}
<commit_msg>Add some comments<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define DIR_SE  3
#define DIR_S   4
#define DIR_SW  5

bool is_able_to_set(const int x, const int y, const int dir = -1);
int count_n_queens(const int x, const int y);

int n;
int *board; /* 0 MEANS EMPTY */

int main(void)
{
    for(n = 1; n <= 15; n++)
    {
        board = (int *)malloc(sizeof(int) * n);
        memset(board, 0, sizeof(int) * n); /* 0 MEANS EMPTY */

        printf("N(%d) Result=%d\n", n, count_n_queens(n, n));
        free(board);
    }

    return 0;
}

bool is_able_to_set(const int x, const int y, const int dir)
{
    /* base case */
    if(x < 1 || x > n || y < 1 || y > n) return true;
    if(board[x - 1] == y) return false; /* queen is exist */

    /* recursive case */
    switch(dir)
    {
    case DIR_SE: return is_able_to_set(x + 1, y + 1, DIR_SE);
    case DIR_S : return is_able_to_set(x + 1, y    , DIR_S );
    case DIR_SW: return is_able_to_set(x + 1, y - 1, DIR_SW);
    default: /* re-call with a direction */
        if(
            is_able_to_set(x, y, DIR_SE) &&
            is_able_to_set(x, y, DIR_S ) &&
            is_able_to_set(x, y, DIR_SW)
        ) return true;
        return false;
    }
}

int b_add(const int x, const int y)
{
    board[x - 1] = y; /* 0 MEANS EMPTY */
    return 0;
}

int b_rm(const int x)
{
    board[x - 1] = 0; /* 0 MEANS EMPTY */
    return 0;
}

int count_n_queens(const int x, const int y)
{
    /* base case */
    if(y < 1) return 0;

    /* recursive case */
    if(is_able_to_set(x, y))
    {
        if(x - 1 >= 1)                  return count_n_queens(x, y - 1) + b_add(x, y) + count_n_queens(x - 1, ::n) + b_rm(x);
        if(is_able_to_set(x - 1, ::n))  return count_n_queens(x, y - 1) + 1;
    }
    return count_n_queens(x, y - 1);
}
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * 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.
 *
 */

#include "MediaSinkImpl.hpp"
#include "MediaSourceImpl.hpp"

#define GST_CAT_DEFAULT kurento_media_sink_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaSinkImpl"

namespace kurento
{

MediaSinkImpl::MediaSinkImpl (std::shared_ptr< MediaType > mediaType,
                              const std::string &mediaDescription,
                              std::shared_ptr< MediaObjectImpl > parent) :
  MediaPadImpl (mediaType, mediaDescription, parent)
{
}

MediaSinkImpl::~MediaSinkImpl()
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if (connectedSrcLocked != NULL) {
    disconnect (connectedSrcLocked);
  }
}

void
MediaSinkImpl::disconnect (std::shared_ptr<MediaSource> mediaSource)
{
  std::shared_ptr<MediaSourceImpl> mediaSourceImpl;

  mediaSourceImpl = std::dynamic_pointer_cast<MediaSourceImpl> (mediaSource);

  mediaSourceImpl->disconnect (this);
}

std::string
MediaSinkImpl::getPadName ()
{
  if (getMediaType()->getValue() == MediaType::AUDIO) {
    return "audio_sink";
  } else {
    return "video_sink";
  }
}

static void
remove_from_parent (GstElement *element)
{
  GstBin *parent = GST_BIN (GST_OBJECT_PARENT (element) );

  if (parent == NULL) {
    return;
  }

  gst_object_ref (element);
  gst_bin_remove (parent, element);
  gst_element_set_state (element, GST_STATE_NULL);

  gst_object_unref (element);
}

static void
sink_unlinked (GstPad *pad, GstPad *peer, GstElement *filter)
{
  GstPad *src;
  GstPad *src_peer;

  src = gst_element_get_static_pad (filter, "src");
  src_peer = gst_pad_get_peer (src);

  if (src_peer != NULL) {
    gst_pad_unlink (src, src_peer);
    gst_object_unref (src_peer);
  } else {
    remove_from_parent (filter);
  }

  gst_object_unref (src);
}

static void
src_unlinked (GstPad *pad, GstPad *peer, GstElement *filter)
{
  GstPad *sink;
  GstPad *sink_peer;

  sink = gst_element_get_static_pad (filter, "sink");
  sink_peer = gst_pad_get_peer (sink);

  if (sink_peer != NULL) {
    gst_pad_unlink (sink_peer, sink);
    gst_object_unref (sink_peer);
  } else {
    remove_from_parent (filter);
  }

  gst_object_unref (sink);
}

bool
MediaSinkImpl::linkPad (std::shared_ptr<MediaSourceImpl> mediaSrc, GstPad *src)
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;
  GstPad *sink;
  bool ret = false;

  mutex.lock();

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if ( (sink = gst_element_get_static_pad (getGstreamerElement(),
               getPadName().c_str() ) ) == NULL) {
    sink = gst_element_get_request_pad (getGstreamerElement(),
                                        getPadName().c_str() );
  }

  if (gst_pad_is_linked (sink) ) {
    unlink (connectedSrcLocked, sink);
  }

  if (std::dynamic_pointer_cast<MediaObjectImpl> (mediaSrc)->getParent() ==
      getParent() ) {
    GstBin *container;
    GstElement *filter, *parent;
    GstPad *aux_sink, *aux_src;

    GST_DEBUG ("Connecting loopback, adding a capsfilter to allow connection");
    parent = GST_ELEMENT (GST_OBJECT_PARENT (sink) );

    if (parent == NULL) {
      goto end;
    }

    container = GST_BIN (GST_OBJECT_PARENT (parent) );

    if (container == NULL) {
      goto end;
    }

    filter = gst_element_factory_make ("capsfilter", NULL);

    aux_sink = gst_element_get_static_pad (filter, "sink");
    aux_src = gst_element_get_static_pad (filter, "src");

    g_signal_connect (G_OBJECT (aux_sink), "unlinked", G_CALLBACK (sink_unlinked),
                      filter );
    g_signal_connect (G_OBJECT (aux_src), "unlinked", G_CALLBACK (src_unlinked),
                      filter );

    gst_bin_add (container, filter);
    gst_element_sync_state_with_parent (filter);

    if (gst_pad_link (aux_src, sink) == GST_PAD_LINK_OK) {
      if (gst_pad_link (src, aux_sink) == GST_PAD_LINK_OK) {
        ret = true;
      } else {
        gst_pad_unlink (aux_src, sink);
      }

    }

    g_object_unref (aux_sink);
    g_object_unref (aux_src);

    gst_debug_bin_to_dot_file_with_ts (GST_BIN (container),
                                       GST_DEBUG_GRAPH_SHOW_ALL, "loopback");

  } else {
    if (gst_pad_link (src, sink) == GST_PAD_LINK_OK) {
      ret = true;
    }
  }

  if (ret == true) {
    connectedSrc = std::weak_ptr<MediaSourceImpl> (mediaSrc);
  } else {
    gst_element_release_request_pad (getGstreamerElement(), sink);
  }

end:

  g_object_unref (sink);

  mutex.unlock();

  return ret;
}

void
MediaSinkImpl::unlink (std::shared_ptr<MediaSourceImpl> mediaSrc, GstPad *sink)
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;

  mutex.lock();

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if (connectedSrcLocked != NULL && mediaSrc == connectedSrcLocked) {
    unlinkUnchecked (sink);
    connectedSrcLocked->removeSink (this);
  }

  mutex.unlock();
}

void
MediaSinkImpl::unlinkUnchecked (GstPad *sink)
{
  GstPad *peer;
  GstPad *sinkPad;

  if (sink == NULL) {
    sinkPad = gst_element_get_static_pad (getGstreamerElement(),
                                          getPadName().c_str() );
  } else {
    sinkPad = sink;
  }

  if (sinkPad == NULL) {
    return;
  }

  peer = gst_pad_get_peer (sinkPad);

  if (peer != NULL) {
    gst_pad_unlink (peer, sinkPad);

    g_object_unref (peer);
  }

  if (sink == NULL) {
    GstElement *elem;

    elem = gst_pad_get_parent_element (sinkPad);
    gst_element_release_request_pad (elem, sinkPad);
    g_object_unref (elem);
    g_object_unref (sinkPad);
  }
}

std::shared_ptr<MediaSource>
MediaSinkImpl::getConnectedSrc ()
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  return std::dynamic_pointer_cast<MediaSource> (connectedSrcLocked);
}

MediaSinkImpl::StaticConstructor MediaSinkImpl::staticConstructor;

MediaSinkImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* kurento */

<commit_msg>MediaSinkImpl: block peer pad before unlinking<commit_after>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * 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.
 *
 */

#include "MediaSinkImpl.hpp"
#include "MediaSourceImpl.hpp"

#define GST_CAT_DEFAULT kurento_media_sink_impl
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoMediaSinkImpl"

namespace kurento
{

MediaSinkImpl::MediaSinkImpl (std::shared_ptr< MediaType > mediaType,
                              const std::string &mediaDescription,
                              std::shared_ptr< MediaObjectImpl > parent) :
  MediaPadImpl (mediaType, mediaDescription, parent)
{
}

MediaSinkImpl::~MediaSinkImpl()
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if (connectedSrcLocked != NULL) {
    disconnect (connectedSrcLocked);
  }
}

void
MediaSinkImpl::disconnect (std::shared_ptr<MediaSource> mediaSource)
{
  std::shared_ptr<MediaSourceImpl> mediaSourceImpl;

  mediaSourceImpl = std::dynamic_pointer_cast<MediaSourceImpl> (mediaSource);

  mediaSourceImpl->disconnect (this);
}

std::string
MediaSinkImpl::getPadName ()
{
  if (getMediaType()->getValue() == MediaType::AUDIO) {
    return "audio_sink";
  } else {
    return "video_sink";
  }
}

static void
remove_from_parent (GstElement *element)
{
  GstBin *parent = GST_BIN (GST_OBJECT_PARENT (element) );

  if (parent == NULL) {
    return;
  }

  gst_object_ref (element);
  gst_bin_remove (parent, element);
  gst_element_set_state (element, GST_STATE_NULL);

  gst_object_unref (element);
}

static void
sink_unlinked (GstPad *pad, GstPad *peer, GstElement *filter)
{
  GstPad *src;
  GstPad *src_peer;

  src = gst_element_get_static_pad (filter, "src");
  src_peer = gst_pad_get_peer (src);

  if (src_peer != NULL) {
    gst_pad_unlink (src, src_peer);
    gst_object_unref (src_peer);
  } else {
    remove_from_parent (filter);
  }

  gst_object_unref (src);
}

static void
src_unlinked (GstPad *pad, GstPad *peer, GstElement *filter)
{
  GstPad *sink;
  GstPad *sink_peer;

  sink = gst_element_get_static_pad (filter, "sink");
  sink_peer = gst_pad_get_peer (sink);

  if (sink_peer != NULL) {
    gst_pad_unlink (sink_peer, sink);
    gst_object_unref (sink_peer);
  } else {
    remove_from_parent (filter);
  }

  gst_object_unref (sink);
}

bool
MediaSinkImpl::linkPad (std::shared_ptr<MediaSourceImpl> mediaSrc, GstPad *src)
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;
  GstPad *sink;
  bool ret = false;

  mutex.lock();

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if ( (sink = gst_element_get_static_pad (getGstreamerElement(),
               getPadName().c_str() ) ) == NULL) {
    sink = gst_element_get_request_pad (getGstreamerElement(),
                                        getPadName().c_str() );
  }

  if (gst_pad_is_linked (sink) ) {
    unlink (connectedSrcLocked, sink);
  }

  if (std::dynamic_pointer_cast<MediaObjectImpl> (mediaSrc)->getParent() ==
      getParent() ) {
    GstBin *container;
    GstElement *filter, *parent;
    GstPad *aux_sink, *aux_src;

    GST_DEBUG ("Connecting loopback, adding a capsfilter to allow connection");
    parent = GST_ELEMENT (GST_OBJECT_PARENT (sink) );

    if (parent == NULL) {
      goto end;
    }

    container = GST_BIN (GST_OBJECT_PARENT (parent) );

    if (container == NULL) {
      goto end;
    }

    filter = gst_element_factory_make ("capsfilter", NULL);

    aux_sink = gst_element_get_static_pad (filter, "sink");
    aux_src = gst_element_get_static_pad (filter, "src");

    g_signal_connect (G_OBJECT (aux_sink), "unlinked", G_CALLBACK (sink_unlinked),
                      filter );
    g_signal_connect (G_OBJECT (aux_src), "unlinked", G_CALLBACK (src_unlinked),
                      filter );

    gst_bin_add (container, filter);
    gst_element_sync_state_with_parent (filter);

    if (gst_pad_link (aux_src, sink) == GST_PAD_LINK_OK) {
      if (gst_pad_link (src, aux_sink) == GST_PAD_LINK_OK) {
        ret = true;
      } else {
        gst_pad_unlink (aux_src, sink);
      }

    }

    g_object_unref (aux_sink);
    g_object_unref (aux_src);

    gst_debug_bin_to_dot_file_with_ts (GST_BIN (container),
                                       GST_DEBUG_GRAPH_SHOW_ALL, "loopback");

  } else {
    if (gst_pad_link (src, sink) == GST_PAD_LINK_OK) {
      ret = true;
    }
  }

  if (ret == true) {
    connectedSrc = std::weak_ptr<MediaSourceImpl> (mediaSrc);
  } else {
    gst_element_release_request_pad (getGstreamerElement(), sink);
  }

end:

  g_object_unref (sink);

  mutex.unlock();

  return ret;
}

void
MediaSinkImpl::unlink (std::shared_ptr<MediaSourceImpl> mediaSrc, GstPad *sink)
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;

  mutex.lock();

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  if (connectedSrcLocked != NULL && mediaSrc == connectedSrcLocked) {
    unlinkUnchecked (sink);
    connectedSrcLocked->removeSink (this);
  }

  mutex.unlock();
}

static GstPadProbeReturn
pad_blocked_adaptor (GstPad *pad, GstPadProbeInfo *info, gpointer data)
{
  auto handler =
    reinterpret_cast < std::function < void (GstPad * pad,
        GstPadProbeInfo * info) > * > (data);

  (*handler) (pad, info);

  /* Drop everithing so as to avoid broken pipe errors on an unlinked pad */
  return GST_PAD_PROBE_DROP;
}

void
MediaSinkImpl::unlinkUnchecked (GstPad *sink)
{
  GstPad *peer;
  GstPad *sinkPad;

  if (sink == NULL) {
    sinkPad = gst_element_get_static_pad (getGstreamerElement(),
                                          getPadName().c_str() );
  } else {
    sinkPad = sink;
  }

  if (sinkPad == NULL) {
    return;
  }

  peer = gst_pad_get_peer (sinkPad);

  if (peer != NULL) {
    Glib::Cond cond;
    Glib::Mutex cmutex;
    bool blocked = FALSE;
    std::function <void (GstPad *pad, GstPadProbeInfo *info) >
    blockedLambda = [&] (GstPad * pad, GstPadProbeInfo * info) {
      GST_DEBUG ("Peer pad blocked %" GST_PTR_FORMAT, pad);

      cmutex.lock ();

      if (!blocked) {
        gst_pad_unlink (pad, sinkPad);
      }

      blocked = TRUE;
      cond.signal();
      cmutex.unlock ();
    };

    gst_pad_add_probe (peer, (GstPadProbeType) (GST_PAD_PROBE_TYPE_IDLE |
                       GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM), pad_blocked_adaptor, &blockedLambda,
                       NULL);

    cmutex.lock ();

    while (!blocked) {
      cond.wait (cmutex);
    }

    cmutex.unlock ();

    g_object_unref (peer);
  }

  if (sink == NULL) {
    GstElement *elem;

    elem = gst_pad_get_parent_element (sinkPad);
    gst_element_release_request_pad (elem, sinkPad);
    g_object_unref (elem);
    g_object_unref (sinkPad);
  }
}

std::shared_ptr<MediaSource>
MediaSinkImpl::getConnectedSrc ()
{
  std::shared_ptr<MediaSourceImpl> connectedSrcLocked;

  try {
    connectedSrcLocked = connectedSrc.lock();
  } catch (const std::bad_weak_ptr &e) {
  }

  return std::dynamic_pointer_cast<MediaSource> (connectedSrcLocked);
}

MediaSinkImpl::StaticConstructor MediaSinkImpl::staticConstructor;

MediaSinkImpl::StaticConstructor::StaticConstructor()
{
  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                           GST_DEFAULT_NAME);
}

} /* kurento */

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attributemap.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2005-11-02 14:02:09 $
 *
 *  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
 *
 ************************************************************************/

// must be first
#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>

#include "attributemap.hxx"
#include "tools.hxx"

namespace presentation
{
    namespace internal
    {
        typedef ::canvas::tools::ValueMap< AttributeType > AnimateAttributeMap;

        AttributeType mapAttributeName( const ::rtl::OUString& rAttrName )
        {
            /** Maps attribute name to AttributeType enum.

                String entries are all case-insensitive and MUST
                BE STORED lowercase.

                String entries MUST BE SORTED in ascending order!
            */
            static AnimateAttributeMap::MapEntry lcl_attributeMap[] =
                {
                    { "charcolor", ATTRIBUTE_CHAR_COLOR },

                    { "charfontname", ATTRIBUTE_CHAR_FONT_NAME },

                    { "charheight", ATTRIBUTE_CHAR_HEIGHT },

                    { "charposture", ATTRIBUTE_CHAR_POSTURE },

                    // TODO(Q1): This should prolly be changed in PPT import
                    // { "charrotation", ATTRIBUTE_CHAR_ROTATION },
                    { "charrotation", ATTRIBUTE_ROTATE },

                    { "charunderline", ATTRIBUTE_CHAR_UNDERLINE },

                    { "charweight", ATTRIBUTE_CHAR_WEIGHT },

                    { "color", ATTRIBUTE_COLOR },

                    { "dimcolor", ATTRIBUTE_DIMCOLOR },

                    { "fillcolor", ATTRIBUTE_FILL_COLOR },

                    { "fillstyle", ATTRIBUTE_FILL_STYLE },

                    { "height", ATTRIBUTE_HEIGHT },

                    { "linecolor", ATTRIBUTE_LINE_COLOR },

                    { "linestyle", ATTRIBUTE_LINE_STYLE },

                    { "opacity", ATTRIBUTE_OPACITY },

                    { "rotate", ATTRIBUTE_ROTATE },

                    { "skewx", ATTRIBUTE_SKEW_X },

                    { "skewy", ATTRIBUTE_SKEW_Y },

                    { "visibility", ATTRIBUTE_VISIBILITY },

                    { "width", ATTRIBUTE_WIDTH },

                    { "x", ATTRIBUTE_POS_X },

                    { "y", ATTRIBUTE_POS_Y }
                };

            static AnimateAttributeMap aMap( lcl_attributeMap,
                                             sizeof(lcl_attributeMap)/sizeof(AnimateAttributeMap::MapEntry),
                                             false );

            AttributeType eAttributeType;

            // determine the type from the attribute name
            if( !aMap.lookup( rAttrName,
                              eAttributeType ) )
            {
                OSL_TRACE( "mapAttributeName(): attribute name %s not found in map.",
                           ::rtl::OUStringToOString( rAttrName,
                                                     RTL_TEXTENCODING_ASCII_US ).getStr() );
                return ATTRIBUTE_INVALID;
            }

            return eAttributeType;
        }

    }
}
<commit_msg>INTEGRATION: CWS pchfix02 (1.4.42); FILE MERGED 2006/09/01 17:39:28 kaib 1.4.42.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attributemap.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 08:23:21 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include <canvas/debug.hxx>
#include <canvas/canvastools.hxx>

#include "attributemap.hxx"
#include "tools.hxx"

namespace presentation
{
    namespace internal
    {
        typedef ::canvas::tools::ValueMap< AttributeType > AnimateAttributeMap;

        AttributeType mapAttributeName( const ::rtl::OUString& rAttrName )
        {
            /** Maps attribute name to AttributeType enum.

                String entries are all case-insensitive and MUST
                BE STORED lowercase.

                String entries MUST BE SORTED in ascending order!
            */
            static AnimateAttributeMap::MapEntry lcl_attributeMap[] =
                {
                    { "charcolor", ATTRIBUTE_CHAR_COLOR },

                    { "charfontname", ATTRIBUTE_CHAR_FONT_NAME },

                    { "charheight", ATTRIBUTE_CHAR_HEIGHT },

                    { "charposture", ATTRIBUTE_CHAR_POSTURE },

                    // TODO(Q1): This should prolly be changed in PPT import
                    // { "charrotation", ATTRIBUTE_CHAR_ROTATION },
                    { "charrotation", ATTRIBUTE_ROTATE },

                    { "charunderline", ATTRIBUTE_CHAR_UNDERLINE },

                    { "charweight", ATTRIBUTE_CHAR_WEIGHT },

                    { "color", ATTRIBUTE_COLOR },

                    { "dimcolor", ATTRIBUTE_DIMCOLOR },

                    { "fillcolor", ATTRIBUTE_FILL_COLOR },

                    { "fillstyle", ATTRIBUTE_FILL_STYLE },

                    { "height", ATTRIBUTE_HEIGHT },

                    { "linecolor", ATTRIBUTE_LINE_COLOR },

                    { "linestyle", ATTRIBUTE_LINE_STYLE },

                    { "opacity", ATTRIBUTE_OPACITY },

                    { "rotate", ATTRIBUTE_ROTATE },

                    { "skewx", ATTRIBUTE_SKEW_X },

                    { "skewy", ATTRIBUTE_SKEW_Y },

                    { "visibility", ATTRIBUTE_VISIBILITY },

                    { "width", ATTRIBUTE_WIDTH },

                    { "x", ATTRIBUTE_POS_X },

                    { "y", ATTRIBUTE_POS_Y }
                };

            static AnimateAttributeMap aMap( lcl_attributeMap,
                                             sizeof(lcl_attributeMap)/sizeof(AnimateAttributeMap::MapEntry),
                                             false );

            AttributeType eAttributeType;

            // determine the type from the attribute name
            if( !aMap.lookup( rAttrName,
                              eAttributeType ) )
            {
                OSL_TRACE( "mapAttributeName(): attribute name %s not found in map.",
                           ::rtl::OUStringToOString( rAttrName,
                                                     RTL_TEXTENCODING_ASCII_US ).getStr() );
                return ATTRIBUTE_INVALID;
            }

            return eAttributeType;
        }

    }
}
<|endoftext|>