<commit_before>/*
 * COPYRIGHT:        See LICENSE in the top level directory
 * PROJECT:          HPCsim
 * FILE:             HPCsim/main.cpp
 * PURPOSE:          Main simulation file
 * PROGRAMMER:       Pierre Schweitzer (pierre@reactos.org)
 */

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <dlfcn.h>
#include <cassert>

#include "TThreadsFactory.h"
#include "RngStream.h"
#include "simulation.h"

#define PATH_MAX 0x1000

#define DEFAULT_NAME {'H', 'P', 'C', 's', 'i', 'm', '.', 'o', 'u', 't', '\0'}

struct TSimulationAddresses
{
    TSimulationInit fSimulationInit;
    TRunInit fRunInit;
    TEventInit fEventInit;
    TEventRun fEventRun;
    TEventClear fEventClear;
    TRunClear fRunClear;
    TSimulationUnload fSimulationUnload;
};

#ifdef USE_PILOT_THREAD
struct TPilotJobContext
{
    unsigned long fEvents;
    void * fSimulationContext;
};
#endif

static pthread_mutex_t gPipeLock;
static int gPipe[2];
static TResult gNullResult;
static TSimulationAddresses gSimulation;

#define LoadAndSetSimulationFunction(name)                      \
    gSimulation.f##name = (T##name)dlsym(simulationLib, #name); \
    if (gSimulation.f##name == 0) {                             \
        std::cerr << "Failed loading " << #name << std::endl;   \
        goto end;                                               \
    }

/* Exported */
double RandU01(void * context)
{
    RngStream * rand = reinterpret_cast<RngStream *>(context);

    return rand->RandU01();
}

/* Exported */
void QueueResult(TResult * result, void * context)
{
    RngStream * rand = reinterpret_cast<RngStream *>(context);

    /* Set our ID first, and send to write thread */
    memcpy(result->fId, rand->GetDigest(), sizeof(TResult::fId));
    pthread_mutex_lock(&gPipeLock);
    write(gPipe[1], result, sizeof(TResult));
    pthread_mutex_unlock(&gPipeLock);
}

static void * SimulationLoop(void * Arg)
{
#ifdef USE_PILOT_THREAD
    TPilotJobContext * context = reinterpret_cast<TPilotJobContext *>(Arg);
    void * simulationContext = context->fSimulationContext;

    for (unsigned long event = 0; event < context->fEvents; ++event)
#else
    void * simulationContext = reinterpret_cast<void *>(Arg);
#endif
    {
        void * eventContext;
        RngStream rand;

        /* Init the event */
        if (gSimulation.fEventInit(simulationContext, &rand, &eventContext) < 0)
        {
#ifdef USE_PILOT_THREAD
            continue;
#else
            sem_post(TThreadsFactory::GetInstance()->GetInitLock());
            return 0;
#endif
        }

        /* Release init lock */
        sem_post(TThreadsFactory::GetInstance()->GetInitLock());

        /* Call the simulation */
        gSimulation.fEventRun(simulationContext, eventContext);

#ifdef USE_PILOT_THREAD
        sem_wait(TThreadsFactory::GetInstance()->GetInitLock());
#endif

        /* Notify end of event */
        gSimulation.fEventClear(simulationContext, eventContext);
    }

#ifdef USE_PILOT_THREAD
    sem_post(TThreadsFactory::GetInstance()->GetInitLock());
#endif

    return 0;
}

static void * WriteResults(void * Arg)
{
    TResult result;
    char * outputFile = reinterpret_cast<char *>(Arg);
    int outFD;

    /* Open the output file */
    outFD = open(outputFile, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    assert(outFD != -1);

    /* Read the incoming event */
    while (read(gPipe[0], &result, sizeof(TResult)) > 0)
    {
        /* End signal => stop dealing with data */
        if (memcmp(&result, &gNullResult, sizeof(TResult)) == 0)
            break;

        /* Write the event to the output file */
        write(outFD, &result, sizeof(TResult));
    }

    close(outFD);

    return 0;
}

static void PrintUsage(char * name)
{
    std::cerr << "Usage: " << name << " --simulation|-s name.so [--threads|-t X --first|-f X --events|-e X --output|-o name]" << std::endl;
    std::cerr << "\t- Simulation: path of the shared library containing the simulation" << std::endl;
    std::cerr << "\t- Threads: amount of threads to use for computing (min 1). Beware an extra thread will be used for results writing" << std::endl;
    std::cerr << "\t- First: start the event loop at this event" << std::endl;
    std::cerr << "\t- Events: number of events to compute" << std::endl;
    std::cerr << "\t- Output: name of the output file to write" << std::endl;
}

int main(int argc, char * argv[])
{
    int option;
    unsigned int nThreads = 1;
    unsigned long nEvents = 100;
    unsigned long firstEvent = 0;
    char outputFile[PATH_MAX] = DEFAULT_NAME;
    char simulationFile[PATH_MAX] = "";
    pthread_t writingThread;
    void * ret;
    void * simulationLib;
    void * simulationContext;
#ifdef USE_PILOT_THREAD
    unsigned long eventsPerThread = 0;
    unsigned long padding = 0;
    TPilotJobContext * contexts = 0;
    TPilotJobContext * context = 0;
#endif

    /* Parse arguments */
    while (true)
    {
        static struct option long_options[] =
        {
            {"threads", required_argument, 0, 't'},
            {"events", required_argument, 0, 'e'},
            {"output", required_argument, 0, 'o'},
            {"first", required_argument, 0, 'f'},
            {"simulation", required_argument, 0, 's'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        option = getopt_long(argc, argv, "e:t:o:f:s:", long_options, &option_index);
        if (option == -1)
            break;

        switch (option)
        {
            static bool written = false;

            case 't':
                nThreads = strtoul(optarg, 0, 10);
                break;

            case 'e':
                nEvents = strtoul(optarg, 0, 10);
                break;

            case 'o':
                strncpy(outputFile, optarg, PATH_MAX - 1);
                outputFile[PATH_MAX - 1] = '\0';
                break;

            case 'f':
                firstEvent = strtoul(optarg, 0, 10);
                break;

            case 's':
                strncpy(simulationFile, optarg, PATH_MAX - 1);
                simulationFile[PATH_MAX - 1] = '\0';
                break;

            case '?':
                if (!written)
                {
                    PrintUsage(argv[0]);
                    written = true;
                }
                break;
        }
    }

    if (simulationFile[0] == '\0')
    {
        PrintUsage(argv[0]);
        return 0;
    }

    /* Open the simulation worker */
    simulationLib = dlopen(simulationFile, RTLD_NOW | RTLD_LOCAL);
    if (simulationLib == 0)
    {
        std::cerr << "Failed loading " << simulationLib << std::endl;
        return 0;
    }

    /* Load its functions */
    LoadAndSetSimulationFunction(SimulationInit);
    LoadAndSetSimulationFunction(RunInit);
    LoadAndSetSimulationFunction(EventInit);
    LoadAndSetSimulationFunction(EventRun);
    LoadAndSetSimulationFunction(EventClear);
    LoadAndSetSimulationFunction(RunClear);
    LoadAndSetSimulationFunction(SimulationUnload);

    /* Init the simulation */
    if (gSimulation.fSimulationInit(nThreads, nEvents, firstEvent, &simulationContext) < 0)
    {
        goto end;
    }

    /* Advance in the generator */
    for (unsigned long i = 0; i < firstEvent; ++i)
    {
        RngStream rand;
    }

    /* Initialize our pipe lock */
    pthread_mutex_init(&gPipeLock, 0);
    /* Start our threads factory */
    TThreadsFactory::GetInstance()->SetMaxThreads(nThreads);
    /* Init our null event */
    memset(&gNullResult, 0, sizeof(TResult));

    /* Open the communication pipe */
    if (pipe(gPipe) == -1)
    {
        goto end2;
    }

    /* Start our background writing thread */
    if (pthread_create(&writingThread, 0, WriteResults, outputFile) != 0)
    {
        goto end3;
    }

    /* Initialize the run */
    if (gSimulation.fRunInit(simulationContext) < 0)
    {
        goto end4;
    }

#ifndef USE_PILOT_THREAD
    /* Hot loop, the simulation happens here */
    for (unsigned long event = 0; event < nEvents; ++event)
    {
        TThreadsFactory::GetInstance()->CreateThread(SimulationLoop, simulationContext);
    }
#else
    /* Alloc once, use multipe times - reduce overhead */
    contexts = new TPilotJobContext[nThreads];

    /* Compute number of events required per thread */
    eventsPerThread = nEvents / nThreads;
    /* Compute number of threads where we have to +1 number of events to get exact amount */
    padding = nEvents % nThreads;
    /* Start at first event */
    context = contexts;

    for (unsigned long thread = 0; thread < nThreads; ++thread)
    {
        context->fSimulationContext = simulationContext;
        context->fEvents = eventsPerThread + ((thread < padding) ? 1 : 0);
        TThreadsFactory::GetInstance()->CreateThread(simulationContext, context);

        ++context;
    }
#endif

    /* Wait for all the propagations to finish */
    TThreadsFactory::GetInstance()->WaitForAllThreads();

#ifdef USE_PILOT_THREAD
    delete contexts;
#endif

    /* Signal end of run */
    gSimulation.fRunClear(simulationContext);

end4:
    /* Send the end signal to writer */
    write(gPipe[1], &gNullResult, sizeof(TResult));

    /* Wait for the end of the writer */
    pthread_join(writingThread, &ret);

end3:
    close(gPipe[0]);
    close(gPipe[1]);
end2:
    pthread_mutex_destroy(&gPipeLock);
    gSimulation.fSimulationUnload(simulationContext);
end:
    dlclose(simulationLib);
    return 0;
}
<commit_msg>Add some error messages<commit_after>/*
 * COPYRIGHT:        See LICENSE in the top level directory
 * PROJECT:          HPCsim
 * FILE:             HPCsim/main.cpp
 * PURPOSE:          Main simulation file
 * PROGRAMMER:       Pierre Schweitzer (pierre@reactos.org)
 */

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <getopt.h>
#include <fcntl.h>
#include <unistd.h>
#include <dlfcn.h>
#include <cassert>

#include "TThreadsFactory.h"
#include "RngStream.h"
#include "simulation.h"

#define PATH_MAX 0x1000

#define DEFAULT_NAME {'H', 'P', 'C', 's', 'i', 'm', '.', 'o', 'u', 't', '\0'}

struct TSimulationAddresses
{
    TSimulationInit fSimulationInit;
    TRunInit fRunInit;
    TEventInit fEventInit;
    TEventRun fEventRun;
    TEventClear fEventClear;
    TRunClear fRunClear;
    TSimulationUnload fSimulationUnload;
};

#ifdef USE_PILOT_THREAD
struct TPilotJobContext
{
    unsigned long fEvents;
    void * fSimulationContext;
};
#endif

static pthread_mutex_t gPipeLock;
static int gPipe[2];
static TResult gNullResult;
static TSimulationAddresses gSimulation;

#define LoadAndSetSimulationFunction(name)                      \
    gSimulation.f##name = (T##name)dlsym(simulationLib, #name); \
    if (gSimulation.f##name == 0) {                             \
        std::cerr << "Failed loading " << #name << std::endl;   \
        goto end;                                               \
    }

/* Exported */
double RandU01(void * context)
{
    RngStream * rand = reinterpret_cast<RngStream *>(context);

    return rand->RandU01();
}

/* Exported */
void QueueResult(TResult * result, void * context)
{
    RngStream * rand = reinterpret_cast<RngStream *>(context);

    /* Set our ID first, and send to write thread */
    memcpy(result->fId, rand->GetDigest(), sizeof(TResult::fId));
    pthread_mutex_lock(&gPipeLock);
    write(gPipe[1], result, sizeof(TResult));
    pthread_mutex_unlock(&gPipeLock);
}

static void * SimulationLoop(void * Arg)
{
#ifdef USE_PILOT_THREAD
    TPilotJobContext * context = reinterpret_cast<TPilotJobContext *>(Arg);
    void * simulationContext = context->fSimulationContext;

    for (unsigned long event = 0; event < context->fEvents; ++event)
#else
    void * simulationContext = reinterpret_cast<void *>(Arg);
#endif
    {
        void * eventContext;
        RngStream rand;

        /* Init the event */
        if (gSimulation.fEventInit(simulationContext, &rand, &eventContext) < 0)
        {
#ifdef USE_PILOT_THREAD
            continue;
#else
            sem_post(TThreadsFactory::GetInstance()->GetInitLock());
            return 0;
#endif
        }

        /* Release init lock */
        sem_post(TThreadsFactory::GetInstance()->GetInitLock());

        /* Call the simulation */
        gSimulation.fEventRun(simulationContext, eventContext);

#ifdef USE_PILOT_THREAD
        sem_wait(TThreadsFactory::GetInstance()->GetInitLock());
#endif

        /* Notify end of event */
        gSimulation.fEventClear(simulationContext, eventContext);
    }

#ifdef USE_PILOT_THREAD
    sem_post(TThreadsFactory::GetInstance()->GetInitLock());
#endif

    return 0;
}

static void * WriteResults(void * Arg)
{
    TResult result;
    char * outputFile = reinterpret_cast<char *>(Arg);
    int outFD;

    /* Open the output file */
    outFD = open(outputFile, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    assert(outFD != -1);

    /* Read the incoming event */
    while (read(gPipe[0], &result, sizeof(TResult)) > 0)
    {
        /* End signal => stop dealing with data */
        if (memcmp(&result, &gNullResult, sizeof(TResult)) == 0)
            break;

        /* Write the event to the output file */
        write(outFD, &result, sizeof(TResult));
    }

    close(outFD);

    return 0;
}

static void PrintUsage(char * name)
{
    std::cerr << "Usage: " << name << " --simulation|-s name.so [--threads|-t X --first|-f X --events|-e X --output|-o name]" << std::endl;
    std::cerr << "\t- Simulation: path of the shared library containing the simulation" << std::endl;
    std::cerr << "\t- Threads: amount of threads to use for computing (min 1). Beware an extra thread will be used for results writing" << std::endl;
    std::cerr << "\t- First: start the event loop at this event" << std::endl;
    std::cerr << "\t- Events: number of events to compute" << std::endl;
    std::cerr << "\t- Output: name of the output file to write" << std::endl;
}

int main(int argc, char * argv[])
{
    int option;
    unsigned int nThreads = 1;
    unsigned long nEvents = 100;
    unsigned long firstEvent = 0;
    char outputFile[PATH_MAX] = DEFAULT_NAME;
    char simulationFile[PATH_MAX] = "";
    pthread_t writingThread;
    void * ret;
    void * simulationLib;
    void * simulationContext;
#ifdef USE_PILOT_THREAD
    unsigned long eventsPerThread = 0;
    unsigned long padding = 0;
    TPilotJobContext * contexts = 0;
    TPilotJobContext * context = 0;
#endif

    /* Parse arguments */
    while (true)
    {
        static struct option long_options[] =
        {
            {"threads", required_argument, 0, 't'},
            {"events", required_argument, 0, 'e'},
            {"output", required_argument, 0, 'o'},
            {"first", required_argument, 0, 'f'},
            {"simulation", required_argument, 0, 's'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        option = getopt_long(argc, argv, "e:t:o:f:s:", long_options, &option_index);
        if (option == -1)
            break;

        switch (option)
        {
            static bool written = false;

            case 't':
                nThreads = strtoul(optarg, 0, 10);
                break;

            case 'e':
                nEvents = strtoul(optarg, 0, 10);
                break;

            case 'o':
                strncpy(outputFile, optarg, PATH_MAX - 1);
                outputFile[PATH_MAX - 1] = '\0';
                break;

            case 'f':
                firstEvent = strtoul(optarg, 0, 10);
                break;

            case 's':
                strncpy(simulationFile, optarg, PATH_MAX - 1);
                simulationFile[PATH_MAX - 1] = '\0';
                break;

            case '?':
                if (!written)
                {
                    PrintUsage(argv[0]);
                    written = true;
                }
                break;
        }
    }

    if (simulationFile[0] == '\0')
    {
        PrintUsage(argv[0]);
        return 0;
    }

    /* Open the simulation worker */
    simulationLib = dlopen(simulationFile, RTLD_NOW | RTLD_LOCAL);
    if (simulationLib == 0)
    {
        std::cerr << "Failed loading " << simulationLib << std::endl;
        return 0;
    }

    /* Load its functions */
    LoadAndSetSimulationFunction(SimulationInit);
    LoadAndSetSimulationFunction(RunInit);
    LoadAndSetSimulationFunction(EventInit);
    LoadAndSetSimulationFunction(EventRun);
    LoadAndSetSimulationFunction(EventClear);
    LoadAndSetSimulationFunction(RunClear);
    LoadAndSetSimulationFunction(SimulationUnload);

    /* Init the simulation */
    if (gSimulation.fSimulationInit(nThreads, nEvents, firstEvent, &simulationContext) < 0)
    {
        std::cerr << "Failed initializing library" << std::endl;
        goto end;
    }

    /* Advance in the generator */
    for (unsigned long i = 0; i < firstEvent; ++i)
    {
        RngStream rand;
    }

    /* Initialize our pipe lock */
    pthread_mutex_init(&gPipeLock, 0);
    /* Start our threads factory */
    TThreadsFactory::GetInstance()->SetMaxThreads(nThreads);
    /* Init our null event */
    memset(&gNullResult, 0, sizeof(TResult));

    /* Open the communication pipe */
    if (pipe(gPipe) == -1)
    {
        std::cerr << "Failed creating pipes" << std::endl;
        goto end2;
    }

    /* Start our background writing thread */
    if (pthread_create(&writingThread, 0, WriteResults, outputFile) != 0)
    {
        std::cerr << "Failed creating writing thread" << std::endl;
        goto end3;
    }

    /* Initialize the run */
    if (gSimulation.fRunInit(simulationContext) < 0)
    {
        std::cerr << "Failed initializing run" << std::endl;
        goto end4;
    }

#ifndef USE_PILOT_THREAD
    /* Hot loop, the simulation happens here */
    for (unsigned long event = 0; event < nEvents; ++event)
    {
        TThreadsFactory::GetInstance()->CreateThread(SimulationLoop, simulationContext);
    }
#else
    /* Alloc once, use multipe times - reduce overhead */
    contexts = new TPilotJobContext[nThreads];

    /* Compute number of events required per thread */
    eventsPerThread = nEvents / nThreads;
    /* Compute number of threads where we have to +1 number of events to get exact amount */
    padding = nEvents % nThreads;
    /* Start at first event */
    context = contexts;

    for (unsigned long thread = 0; thread < nThreads; ++thread)
    {
        context->fSimulationContext = simulationContext;
        context->fEvents = eventsPerThread + ((thread < padding) ? 1 : 0);
        TThreadsFactory::GetInstance()->CreateThread(simulationContext, context);

        ++context;
    }
#endif

    /* Wait for all the propagations to finish */
    TThreadsFactory::GetInstance()->WaitForAllThreads();

#ifdef USE_PILOT_THREAD
    delete contexts;
#endif

    /* Signal end of run */
    gSimulation.fRunClear(simulationContext);

end4:
    /* Send the end signal to writer */
    write(gPipe[1], &gNullResult, sizeof(TResult));

    /* Wait for the end of the writer */
    pthread_join(writingThread, &ret);

end3:
    close(gPipe[0]);
    close(gPipe[1]);
end2:
    pthread_mutex_destroy(&gPipeLock);
    gSimulation.fSimulationUnload(simulationContext);
end:
    dlclose(simulationLib);
    return 0;
}
<|endoftext|>


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

#include "remoting/host/pairing_registry_delegate_win.h"

#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "base/win/registry.h"

namespace remoting {

namespace {

// Duplicates a registry key handle (returned by RegCreateXxx/RegOpenXxx).
// The returned handle cannot be inherited and has the same permissions as
// the source one.
bool DuplicateKeyHandle(HKEY source, base::win::RegKey* dest) {
  HANDLE handle;
  if (!DuplicateHandle(GetCurrentProcess(),
                       source,
                       GetCurrentProcess(),
                       &handle,
                       0,
                       FALSE,
                       DUPLICATE_SAME_ACCESS)) {
    PLOG(ERROR) << "Failed to duplicate a registry key handle";
    return false;
  }

  dest->Set(reinterpret_cast<HKEY>(handle));
  return true;
}

// Reads value |value_name| from |key| as a JSON string and returns it as
// |base::Value|.
scoped_ptr<base::DictionaryValue> ReadValue(const base::win::RegKey& key,
                                            const wchar_t* value_name) {
  // presubmit: allow wstring
  std::wstring value_json;
  LONG result = key.ReadValue(value_name, &value_json);
  if (result != ERROR_SUCCESS) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot read value '" << value_name << "'";
    return scoped_ptr<base::DictionaryValue>();
  }

  // Parse the value.
  std::string value_json_utf8 = WideToUTF8(value_json);
  JSONStringValueSerializer serializer(&value_json_utf8);
  int error_code;
  std::string error_message;
  scoped_ptr<base::Value> value(serializer.Deserialize(&error_code,
                                                       &error_message));
  if (!value) {
    LOG(ERROR) << "Failed to parse '" << value_name << "': " << error_message
               << " (" << error_code << ").";
    return scoped_ptr<base::DictionaryValue>();
  }

  if (value->GetType() != base::Value::TYPE_DICTIONARY) {
    LOG(ERROR) << "Failed to parse '" << value_name << "': not a dictionary.";
    return scoped_ptr<base::DictionaryValue>();
  }

  return scoped_ptr<base::DictionaryValue>(
      static_cast<base::DictionaryValue*>(value.release()));
}

// Serializes |value| into a JSON string and writes it as value |value_name|
// under |key|.
bool WriteValue(base::win::RegKey& key,
                const wchar_t* value_name,
                scoped_ptr<base::DictionaryValue> value) {
  std::string value_json_utf8;
  JSONStringValueSerializer serializer(&value_json_utf8);
  if (!serializer.Serialize(*value)) {
    LOG(ERROR) << "Failed to serialize '" << value_name << "'";
    return false;
  }

  // presubmit: allow wstring
  std::wstring value_json = UTF8ToWide(value_json_utf8);
  LONG result = key.WriteValue(value_name,
                               UTF8ToWide(value_json_utf8).c_str());
  if (result != ERROR_SUCCESS) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot write value '" << value_name << "'";
    return false;
  }

  return true;
}

}  // namespace

using protocol::PairingRegistry;

PairingRegistryDelegateWin::PairingRegistryDelegateWin() {
}

PairingRegistryDelegateWin::~PairingRegistryDelegateWin() {
}

bool PairingRegistryDelegateWin::SetRootKeys(HKEY privileged,
                                             HKEY unprivileged) {
  DCHECK(!privileged_.Valid());
  DCHECK(!unprivileged_.Valid());
  DCHECK(unprivileged);

  if (!DuplicateKeyHandle(unprivileged, &unprivileged_))
    return false;

  if (privileged) {
    if (!DuplicateKeyHandle(privileged, &privileged_))
      return false;
  }

  return true;
}

scoped_ptr<base::ListValue> PairingRegistryDelegateWin::LoadAll() {
  scoped_ptr<base::ListValue> pairings(new base::ListValue());

  // Enumerate and parse all values under the unprivileged key.
  DWORD count = unprivileged_.GetValueCount();
  for (DWORD index = 0; index < count; ++index) {
    // presubmit: allow wstring
    std::wstring value_name;
    LONG result = unprivileged_.GetValueNameAt(index, &value_name);
    if (result != ERROR_SUCCESS) {
      SetLastError(result);
      PLOG(ERROR) << "Cannot get the name of value " << index;
      continue;
    }

    PairingRegistry::Pairing pairing = Load(WideToUTF8(value_name));
    if (pairing.is_valid())
      pairings->Append(pairing.ToValue().release());
  }

  return pairings.Pass();
}

bool PairingRegistryDelegateWin::DeleteAll() {
  if (!privileged_.Valid()) {
    LOG(ERROR) << "Cannot delete pairings: the delegate is read-only.";
    return false;
  }

  bool success = true;
  DWORD count = unprivileged_.GetValueCount();
  while (count > 0) {
    // presubmit: allow wstring
    std::wstring value_name;
    LONG result = unprivileged_.GetValueNameAt(0, &value_name);
    if (result == ERROR_SUCCESS)
      result = unprivileged_.DeleteValue(value_name.c_str());

    success = success && (result == ERROR_SUCCESS);
    count = unprivileged_.GetValueCount();
  }

  return success;
}

PairingRegistry::Pairing PairingRegistryDelegateWin::Load(
    const std::string& client_id) {
  // presubmit: allow wstring
  std::wstring value_name = UTF8ToWide(client_id);

  // Read unprivileged fields first.
  scoped_ptr<base::DictionaryValue> pairing = ReadValue(unprivileged_,
                                                        value_name.c_str());
  if (!pairing)
    return PairingRegistry::Pairing();

  // Read the shared secret.
  if (privileged_.Valid()) {
    scoped_ptr<base::DictionaryValue> secret = ReadValue(privileged_,
                                                         value_name.c_str());
    if (!secret)
      return PairingRegistry::Pairing();

    // Merge the two dictionaries.
    pairing->MergeDictionary(secret.get());
  }

  return PairingRegistry::Pairing::CreateFromValue(*pairing);
}

bool PairingRegistryDelegateWin::Save(const PairingRegistry::Pairing& pairing) {
  if (!privileged_.Valid()) {
    LOG(ERROR) << "Cannot save pairing entry '" << pairing.client_id()
                << "': the delegate is read-only.";
    return false;
  }

  // Convert pairing to JSON.
  scoped_ptr<base::DictionaryValue> pairing_json = pairing.ToValue();

  // Extract the shared secret to a separate dictionary.
  scoped_ptr<base::Value> secret_key;
  CHECK(pairing_json->Remove(PairingRegistry::kSharedSecretKey, &secret_key));
  scoped_ptr<base::DictionaryValue> secret_json(new base::DictionaryValue());
  secret_json->Set(PairingRegistry::kSharedSecretKey, secret_key.release());

  // presubmit: allow wstring
  std::wstring value_name = UTF8ToWide(pairing.client_id());

  // Write pairing to the registry.
  if (!WriteValue(privileged_, value_name.c_str(), secret_json.Pass()) ||
      !WriteValue(unprivileged_, value_name.c_str(), pairing_json.Pass())) {
    return false;
  }

  return true;
}

bool PairingRegistryDelegateWin::Delete(const std::string& client_id) {
  if (!privileged_.Valid()) {
    LOG(ERROR) << "Cannot delete pairing entry '" << client_id
                << "': the delegate is read-only.";
    return false;
  }

  // presubmit: allow wstring
  std::wstring value_name = UTF8ToWide(client_id);
  LONG result = privileged_.DeleteValue(value_name.c_str());
  if (result != ERROR_SUCCESS &&
      result != ERROR_FILE_NOT_FOUND &&
      result != ERROR_PATH_NOT_FOUND) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot delete pairing entry '" << client_id << "'";
    return false;
  }

  result = unprivileged_.DeleteValue(value_name.c_str());
  if (result != ERROR_SUCCESS &&
      result != ERROR_FILE_NOT_FOUND &&
      result != ERROR_PATH_NOT_FOUND) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot delete pairing entry '" << client_id << "'";
    return false;
  }

  return true;
}

scoped_ptr<PairingRegistry::Delegate> CreatePairingRegistryDelegate() {
  return scoped_ptr<PairingRegistry::Delegate>();
}

}  // namespace remoting
<commit_msg>Fix unused variable declaration.<commit_after>// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/host/pairing_registry_delegate_win.h"

#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "base/win/registry.h"

namespace remoting {

namespace {

// Duplicates a registry key handle (returned by RegCreateXxx/RegOpenXxx).
// The returned handle cannot be inherited and has the same permissions as
// the source one.
bool DuplicateKeyHandle(HKEY source, base::win::RegKey* dest) {
  HANDLE handle;
  if (!DuplicateHandle(GetCurrentProcess(),
                       source,
                       GetCurrentProcess(),
                       &handle,
                       0,
                       FALSE,
                       DUPLICATE_SAME_ACCESS)) {
    PLOG(ERROR) << "Failed to duplicate a registry key handle";
    return false;
  }

  dest->Set(reinterpret_cast<HKEY>(handle));
  return true;
}

// Reads value |value_name| from |key| as a JSON string and returns it as
// |base::Value|.
scoped_ptr<base::DictionaryValue> ReadValue(const base::win::RegKey& key,
                                            const wchar_t* value_name) {
  // presubmit: allow wstring
  std::wstring value_json;
  LONG result = key.ReadValue(value_name, &value_json);
  if (result != ERROR_SUCCESS) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot read value '" << value_name << "'";
    return scoped_ptr<base::DictionaryValue>();
  }

  // Parse the value.
  std::string value_json_utf8 = WideToUTF8(value_json);
  JSONStringValueSerializer serializer(&value_json_utf8);
  int error_code;
  std::string error_message;
  scoped_ptr<base::Value> value(serializer.Deserialize(&error_code,
                                                       &error_message));
  if (!value) {
    LOG(ERROR) << "Failed to parse '" << value_name << "': " << error_message
               << " (" << error_code << ").";
    return scoped_ptr<base::DictionaryValue>();
  }

  if (value->GetType() != base::Value::TYPE_DICTIONARY) {
    LOG(ERROR) << "Failed to parse '" << value_name << "': not a dictionary.";
    return scoped_ptr<base::DictionaryValue>();
  }

  return scoped_ptr<base::DictionaryValue>(
      static_cast<base::DictionaryValue*>(value.release()));
}

// Serializes |value| into a JSON string and writes it as value |value_name|
// under |key|.
bool WriteValue(base::win::RegKey& key,
                const wchar_t* value_name,
                scoped_ptr<base::DictionaryValue> value) {
  std::string value_json_utf8;
  JSONStringValueSerializer serializer(&value_json_utf8);
  if (!serializer.Serialize(*value)) {
    LOG(ERROR) << "Failed to serialize '" << value_name << "'";
    return false;
  }

  // presubmit: allow wstring
  std::wstring value_json = UTF8ToWide(value_json_utf8);
  LONG result = key.WriteValue(value_name, value_json.c_str());
  if (result != ERROR_SUCCESS) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot write value '" << value_name << "'";
    return false;
  }

  return true;
}

}  // namespace

using protocol::PairingRegistry;

PairingRegistryDelegateWin::PairingRegistryDelegateWin() {
}

PairingRegistryDelegateWin::~PairingRegistryDelegateWin() {
}

bool PairingRegistryDelegateWin::SetRootKeys(HKEY privileged,
                                             HKEY unprivileged) {
  DCHECK(!privileged_.Valid());
  DCHECK(!unprivileged_.Valid());
  DCHECK(unprivileged);

  if (!DuplicateKeyHandle(unprivileged, &unprivileged_))
    return false;

  if (privileged) {
    if (!DuplicateKeyHandle(privileged, &privileged_))
      return false;
  }

  return true;
}

scoped_ptr<base::ListValue> PairingRegistryDelegateWin::LoadAll() {
  scoped_ptr<base::ListValue> pairings(new base::ListValue());

  // Enumerate and parse all values under the unprivileged key.
  DWORD count = unprivileged_.GetValueCount();
  for (DWORD index = 0; index < count; ++index) {
    // presubmit: allow wstring
    std::wstring value_name;
    LONG result = unprivileged_.GetValueNameAt(index, &value_name);
    if (result != ERROR_SUCCESS) {
      SetLastError(result);
      PLOG(ERROR) << "Cannot get the name of value " << index;
      continue;
    }

    PairingRegistry::Pairing pairing = Load(WideToUTF8(value_name));
    if (pairing.is_valid())
      pairings->Append(pairing.ToValue().release());
  }

  return pairings.Pass();
}

bool PairingRegistryDelegateWin::DeleteAll() {
  if (!privileged_.Valid()) {
    LOG(ERROR) << "Cannot delete pairings: the delegate is read-only.";
    return false;
  }

  bool success = true;
  DWORD count = unprivileged_.GetValueCount();
  while (count > 0) {
    // presubmit: allow wstring
    std::wstring value_name;
    LONG result = unprivileged_.GetValueNameAt(0, &value_name);
    if (result == ERROR_SUCCESS)
      result = unprivileged_.DeleteValue(value_name.c_str());

    success = success && (result == ERROR_SUCCESS);
    count = unprivileged_.GetValueCount();
  }

  return success;
}

PairingRegistry::Pairing PairingRegistryDelegateWin::Load(
    const std::string& client_id) {
  // presubmit: allow wstring
  std::wstring value_name = UTF8ToWide(client_id);

  // Read unprivileged fields first.
  scoped_ptr<base::DictionaryValue> pairing = ReadValue(unprivileged_,
                                                        value_name.c_str());
  if (!pairing)
    return PairingRegistry::Pairing();

  // Read the shared secret.
  if (privileged_.Valid()) {
    scoped_ptr<base::DictionaryValue> secret = ReadValue(privileged_,
                                                         value_name.c_str());
    if (!secret)
      return PairingRegistry::Pairing();

    // Merge the two dictionaries.
    pairing->MergeDictionary(secret.get());
  }

  return PairingRegistry::Pairing::CreateFromValue(*pairing);
}

bool PairingRegistryDelegateWin::Save(const PairingRegistry::Pairing& pairing) {
  if (!privileged_.Valid()) {
    LOG(ERROR) << "Cannot save pairing entry '" << pairing.client_id()
                << "': the delegate is read-only.";
    return false;
  }

  // Convert pairing to JSON.
  scoped_ptr<base::DictionaryValue> pairing_json = pairing.ToValue();

  // Extract the shared secret to a separate dictionary.
  scoped_ptr<base::Value> secret_key;
  CHECK(pairing_json->Remove(PairingRegistry::kSharedSecretKey, &secret_key));
  scoped_ptr<base::DictionaryValue> secret_json(new base::DictionaryValue());
  secret_json->Set(PairingRegistry::kSharedSecretKey, secret_key.release());

  // presubmit: allow wstring
  std::wstring value_name = UTF8ToWide(pairing.client_id());

  // Write pairing to the registry.
  if (!WriteValue(privileged_, value_name.c_str(), secret_json.Pass()) ||
      !WriteValue(unprivileged_, value_name.c_str(), pairing_json.Pass())) {
    return false;
  }

  return true;
}

bool PairingRegistryDelegateWin::Delete(const std::string& client_id) {
  if (!privileged_.Valid()) {
    LOG(ERROR) << "Cannot delete pairing entry '" << client_id
                << "': the delegate is read-only.";
    return false;
  }

  // presubmit: allow wstring
  std::wstring value_name = UTF8ToWide(client_id);
  LONG result = privileged_.DeleteValue(value_name.c_str());
  if (result != ERROR_SUCCESS &&
      result != ERROR_FILE_NOT_FOUND &&
      result != ERROR_PATH_NOT_FOUND) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot delete pairing entry '" << client_id << "'";
    return false;
  }

  result = unprivileged_.DeleteValue(value_name.c_str());
  if (result != ERROR_SUCCESS &&
      result != ERROR_FILE_NOT_FOUND &&
      result != ERROR_PATH_NOT_FOUND) {
    SetLastError(result);
    PLOG(ERROR) << "Cannot delete pairing entry '" << client_id << "'";
    return false;
  }

  return true;
}

scoped_ptr<PairingRegistry::Delegate> CreatePairingRegistryDelegate() {
  return scoped_ptr<PairingRegistry::Delegate>();
}

}  // namespace remoting
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "Level.h"
#include "GameSystem.h"
#include <fstream>
#include <sstream>
#include <mmsystem.h>

Level::Level() {
}

void Level::load(string fileName, Player &player) {

	_fileName = fileName;

	//loads the level
	ifstream file;

	file.open(fileName);
	if (file.fail()) {
		perror(fileName.c_str());
		system("pause");
		exit(1);
	}

	string line;

	while (getline(file, line)) {
		_levelData.push_back(line);
	}

	file.close();

	//process the level

	char tile;

	for (int i = 0; i < _levelData.size(); i++) {
		for (int j = 0; j < _levelData[i].size(); j++) {
			tile = _levelData[i][j];

			switch (tile) {

			case '@': //player
				player.setPosition(j, i);
				break;
			case 'g': //goblin
				_enemies.push_back(Enemy("Goblin", tile, 1, 3, 1, 100, 10, 5));
				_enemies.back().setPosition(j, i);
				break;
			case 'O': //ogre
				_enemies.push_back(Enemy("Ogre", tile, 5, 20, 50, 50, 100, 10));
				_enemies.back().setPosition(j, i);
				break;
			case 'D': //dragon
				_enemies.push_back(Enemy("Dragon", tile, 100, 500, 1000, 1000, 1000, 20));
				_enemies.back().setPosition(j, i);
				break;
			}

		}
	}

}

void Level::print() {

	cls();

	for (int i = 0; i < _levelData.size(); i++) {
		for (int j = 0; j < _levelData[i].size(); j++) {

			switch (_levelData[i][j]) {
			case '&': //flame
				setColor(consoleColor(0, 6));
				break;
			case '0': //door
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				setColor(consoleColor(0, 3));
				break;
			case '@': //player
				setColor(consoleColor(0, 9));
				break;
			case 'g': //goblin
				setColor(consoleColor(0, 12));
				break;
			case 'O': //ogre
				setColor(consoleColor(0, 14));
				break;
			case 'D': //dragon
				setColor(consoleColor(0, 4));
				break;
			default:
				setColor(consoleColor(0, 7));
				break;
			}
			printf("%c", _levelData[i][j]);

		}

		printf("\n");

	}

	printf("\n");

	//cls();

}

void Level::movePlayer(char input, Player &player) {

	int playerX;
	int playerY;
	player.getPosition(playerX, playerY);

	switch (input) {

	case 'w': //up
	case 'W':
		processPlayerMove(player, playerX, playerY - 1);
		break;
	case 's': //down
	case 'S':
		processPlayerMove(player, playerX, playerY + 1);
		break;
	case 'a': //left
	case 'A':
		processPlayerMove(player, playerX - 1, playerY);
		break;
	case 'd': //right
	case 'D':
		processPlayerMove(player, playerX + 1, playerY);
		break;
	default:
		printf("Invalid input.\n");
		system("pause");
		break;
	}

}

void Level::updateEnemies(Player & player) {

	char aiMove;
	int playerX;
	int playerY;
	int enemyX;
	int enemyY;
	player.getPosition(playerX, playerY);

	for (int i = 0; i < _enemies.size(); i++) {
		char aiMove = _enemies[i].getMove(playerX, playerY);

		_enemies[i].getPosition(enemyX, enemyY);

		switch (aiMove) {

		case 'w': //up

			processEnemyMove(player, i, enemyX, enemyY - 1);
			break;
		case 's': //down

			processEnemyMove(player, i, enemyX, enemyY + 1);
			break;
		case 'a': //left

			processEnemyMove(player, i, enemyX - 1, enemyY);
			break;
		case 'd': //right

			processEnemyMove(player, i, enemyX + 1, enemyY);
			break;

		}
	}

}

void Level::processPlayerMove(Player &player, int targetX, int targetY) {

	int playerX, playerY;
	player.getPosition(playerX, playerY);

	char moveTile = getTile(targetX, targetY);

	switch (moveTile) {
	case ' ':
		player.setPosition(targetX, targetY);
		setTile(playerX, playerY, ' ');
		setTile(targetX, targetY, '@');
		break;
	case '&':
	case '|':
	case '+':
	case '-':
	case '#':
		break;
	case '0': //door
	case '1':
	case '2':
	case '3':
	case '4': {
	//case '5':
	//case '6':
	//case '7':
	//case '8':
	//case '9': {

		_levelData.clear();
		_enemies.clear();
		stringstream ss;
		ss << "level" << moveTile << ".map";

		load(ss.str(), player);
		break;
	}
	default:
		battleEnemy(player, targetX, targetY);
		break;
	}

}

void Level::processEnemyMove(Player &player, int enemyIndex, int targetX, int targetY) {

	int playerX, playerY;
	int enemyX, enemyY;
	player.getPosition(playerX, playerY);
	_enemies[enemyIndex].getPosition(enemyX, enemyY);

	char moveTile = getTile(targetX, targetY);

	switch (moveTile) {
	case ' ':
		_enemies[enemyIndex].setPosition(targetX, targetY);
		setTile(enemyX, enemyY, ' ');
		setTile(targetX, targetY, _enemies[enemyIndex].getTile());
		break;
	case '&':
	case '|':
	case '+':
	case '-':
	case '#':
		break;
	case '0': //door
	case '1':
	case '2':
	case '3':
	case '4':
	//case '5':
	//case '6':
	//case '7':
	//case '8':
	//case '9':
		break;
	case '@':
		battleEnemy(player, enemyX, enemyY);
		break;
	default:
		break;
	}

}

void Level::battleEnemy(Player & player, int targetX, int targetY) {

	int enemyX;
	int enemyY;
	int playerX;
	int playerY;
	int attackRoll;
	int attackResult;

	player.getPosition(playerX, playerY);

	for (int i = 0; i < _enemies.size(); i++) {
		_enemies[i].getPosition(enemyX, enemyY);
		if (targetX == enemyX && targetY == enemyY) {
			//battle
			attackRoll = player.attack();
			//printf("\nPlayer attacked %s with a roll of %d\n", _enemies[i].getName().c_str(), attackRoll);
			attackResult = _enemies[i].takeDamage(attackRoll);

			if (attackResult != 0) {

				setTile(targetX, targetY, ' ');
				print();
				PlaySound(TEXT("beep.wav"), NULL, SND_FILENAME);
				//printf("\n%s died\n", _enemies[i].getName().c_str());

				//remove enemy
				_enemies[i] = _enemies.back();
				_enemies.pop_back();
				i--;

				player.addExperience(attackResult);
				system("pause");

				return;
			}

			attackRoll = _enemies[i].attack();
			//printf("\n%s attacked player with a roll of %d\n", _enemies[i].getName().c_str(), attackRoll);
			attackResult = player.takeDamage(attackRoll);

			if (attackResult != 0) {
				setTile(playerX, playerY, 'x');
				print();
				printf("You died\n");
				system("pause");
				player.addExperience(attackResult);
				exit(0);
			}
			system("pause");
			return;
		}
	}

}

char Level::getTile(int x, int y) {

	return _levelData[y][x];

}

void Level::setTile(int x, int y, char tile) {

	_levelData[y][x] = tile;

}

Level::~Level() {
}
<commit_msg>Fixed some visual bugs<commit_after>#include "stdafx.h"
#include "Level.h"
#include "GameSystem.h"
#include <fstream>
#include <sstream>
#include <mmsystem.h>

Level::Level() {
}

void Level::load(string fileName, Player &player) {

	_fileName = fileName;

	//loads the level
	ifstream file;

	file.open(fileName);
	if (file.fail()) {
		perror(fileName.c_str());
		system("pause");
		exit(1);
	}

	string line;

	while (getline(file, line)) {
		_levelData.push_back(line);
	}

	file.close();

	//process the level

	char tile;

	for (int i = 0; i < _levelData.size(); i++) {
		for (int j = 0; j < _levelData[i].size(); j++) {
			tile = _levelData[i][j];

			switch (tile) {

			case '@': //player
				player.setPosition(j, i);
				break;
			case 'g': //goblin
				_enemies.push_back(Enemy("Goblin", tile, 1, 3, 1, 100, 10, 5));
				_enemies.back().setPosition(j, i);
				break;
			case 'O': //ogre
				_enemies.push_back(Enemy("Ogre", tile, 5, 20, 50, 50, 100, 10));
				_enemies.back().setPosition(j, i);
				break;
			case 'D': //dragon
				_enemies.push_back(Enemy("Dragon", tile, 100, 500, 1000, 1000, 1000, 20));
				_enemies.back().setPosition(j, i);
				break;
			}

		}
	}

}

void Level::print() {

	cls();

	for (int i = 0; i < _levelData.size(); i++) {
		for (int j = 0; j < _levelData[i].size(); j++) {

			switch (_levelData[i][j]) {
			case '&': //flame
				setColor(consoleColor(0, 6));
				break;
			case '0': //door
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				setColor(consoleColor(0, 3));
				break;
			case '@': //player
				setColor(consoleColor(0, 9));
				break;
			case 'g': //goblin
				setColor(consoleColor(0, 12));
				break;
			case 'O': //ogre
				setColor(consoleColor(0, 14));
				break;
			case 'D': //dragon
				setColor(consoleColor(0, 4));
				break;
			default:
				setColor(consoleColor(0, 7));
				break;
			}
			printf("%c", _levelData[i][j]);

		}

		printf("\n");

	}

	printf("\n");

	//cls();

}

void Level::movePlayer(char input, Player &player) {

	int playerX;
	int playerY;
	player.getPosition(playerX, playerY);

	switch (input) {

	case 'w': //up
	case 'W':
		processPlayerMove(player, playerX, playerY - 1);
		break;
	case 's': //down
	case 'S':
		processPlayerMove(player, playerX, playerY + 1);
		break;
	case 'a': //left
	case 'A':
		processPlayerMove(player, playerX - 1, playerY);
		break;
	case 'd': //right
	case 'D':
		processPlayerMove(player, playerX + 1, playerY);
		break;
	default:
		//printf("Invalid input.\n");
		//system("pause");
		break;
	}

}

void Level::updateEnemies(Player & player) {

	char aiMove;
	int playerX;
	int playerY;
	int enemyX;
	int enemyY;
	player.getPosition(playerX, playerY);

	for (int i = 0; i < _enemies.size(); i++) {
		char aiMove = _enemies[i].getMove(playerX, playerY);

		_enemies[i].getPosition(enemyX, enemyY);

		switch (aiMove) {

		case 'w': //up

			processEnemyMove(player, i, enemyX, enemyY - 1);
			break;
		case 's': //down

			processEnemyMove(player, i, enemyX, enemyY + 1);
			break;
		case 'a': //left

			processEnemyMove(player, i, enemyX - 1, enemyY);
			break;
		case 'd': //right

			processEnemyMove(player, i, enemyX + 1, enemyY);
			break;

		}
	}

}

void Level::processPlayerMove(Player &player, int targetX, int targetY) {

	int playerX, playerY;
	player.getPosition(playerX, playerY);

	char moveTile = getTile(targetX, targetY);

	switch (moveTile) {
	case ' ':
		player.setPosition(targetX, targetY);
		setTile(playerX, playerY, ' ');
		setTile(targetX, targetY, '@');
		break;
	case '&':
	case '|':
	case '+':
	case '-':
	case '#':
		break;
	case '0': //door
	case '1':
	case '2':
	case '3':
	case '4': {
	//case '5':
	//case '6':
	//case '7':
	//case '8':
	//case '9': {

		_levelData.clear();
		_enemies.clear();
		stringstream ss;
		ss << "Maps\\level" << moveTile << ".map";

		load(ss.str(), player);
		break;
	}
	default:
		battleEnemy(player, targetX, targetY);
		break;
	}

}

void Level::processEnemyMove(Player &player, int enemyIndex, int targetX, int targetY) {

	int playerX, playerY;
	int enemyX, enemyY;
	player.getPosition(playerX, playerY);
	_enemies[enemyIndex].getPosition(enemyX, enemyY);

	char moveTile = getTile(targetX, targetY);

	switch (moveTile) {
	case ' ':
		_enemies[enemyIndex].setPosition(targetX, targetY);
		setTile(enemyX, enemyY, ' ');
		setTile(targetX, targetY, _enemies[enemyIndex].getTile());
		break;
	case '&':
	case '|':
	case '+':
	case '-':
	case '#':
		break;
	case '0': //door
	case '1':
	case '2':
	case '3':
	case '4':
	//case '5':
	//case '6':
	//case '7':
	//case '8':
	//case '9':
		break;
	case '@':
		battleEnemy(player, enemyX, enemyY);
		break;
	default:
		break;
	}

}

void Level::battleEnemy(Player & player, int targetX, int targetY) {

	int enemyX;
	int enemyY;
	int playerX;
	int playerY;
	int attackRoll;
	int attackResult;

	player.getPosition(playerX, playerY);

	for (int i = 0; i < _enemies.size(); i++) {
		_enemies[i].getPosition(enemyX, enemyY);
		if (targetX == enemyX && targetY == enemyY) {
			//battle
			attackRoll = player.attack();
			//printf("\nPlayer attacked %s with a roll of %d\n", _enemies[i].getName().c_str(), attackRoll);
			attackResult = _enemies[i].takeDamage(attackRoll);

			if (attackResult != 0) {

				setTile(targetX, targetY, ' ');
				print();

				#ifdef WIN32
					PlaySound(TEXT("Sounds\\beep.wav"), NULL, SND_FILENAME);
				#endif
				//printf("\n%s died\n", _enemies[i].getName().c_str());

				//remove enemy
				_enemies[i] = _enemies.back();
				_enemies.pop_back();
				i--;

				player.addExperience(attackResult);
				//system("pause");

				return;
			}

			attackRoll = _enemies[i].attack();
			//printf("\n%s attacked player with a roll of %d\n", _enemies[i].getName().c_str(), attackRoll);
			attackResult = player.takeDamage(attackRoll);

			if (attackResult != 0) {
				setTile(playerX, playerY, 'x');
				print();
				//printf("You died\n");
				//system("pause");
				player.addExperience(attackResult);
				exit(0);
			}
			//system("pause");
			return;
		}
	}

}

char Level::getTile(int x, int y) {

	return _levelData[y][x];

}

void Level::setTile(int x, int y, char tile) {

	_levelData[y][x] = tile;

}

Level::~Level() {
}
<|endoftext|>


<commit_before>#include "../element.h"
#include "gtest/gtest.h"
#include "../document.h"
#include <sstream>
#include <string>
#include <iostream>
#include <array>
#include <vector>
#include <set>
#include "../json/jsonscanner.h"

TEST(JSONConvert, FromString)
{
  std::string key="asdf", value="asdf2";
  bson::Document d("{\"" + key + "\":\"" + value + "\"}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(value, d[key].data<std::string>());
}

TEST(JSONConvert, FromInt)
{
  std::string key="asdf", value="42";
  int ival = 42;
  bson::Document d("{\"" + key + "\":" + value + "}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(ival, d[key].data<long>());
}

TEST(JSONConvert, FromDouble)
{
  std::string key="asdf", value="3.14000";
  double dval = 3.14000;
  bson::Document d("{\"" + key + "\":" + value + "}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(dval, d[key].data<double>());
}

TEST(JSONConvert, FromNull)
{
  std::string key = "asdf";
  bson::Document d("{\"" + key + "\": null }");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(bson::NIL, d[key].get_type());
}

TEST(JSONConvert, FromArr)
{
  std::string key = "asdf";
  bson::Document d("{\"" + key + "\": [0, 1, 2, 3, 4, 5, 6.2] }");
  ASSERT_EQ(1, d.field_names().size());
  for (int i=0; i<6; i++)
    ASSERT_EQ(i, d[key].data<bson::array>()[i].data<long>());
  ASSERT_EQ(6.2, d[key].data<bson::array>()[6].data<double>());
}

TEST(JSONConvert, FromBool)
{
  std::string key = "asdf";
  bson::Document d("{\"" + key + "\": true }");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_TRUE(d[key].data<bool>());
  d.from_json("{\"" + key + "\": false }");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_FALSE(d[key].data<bool>());
}

TEST(JSONConvert, InvalidJSON)
{
  const std::string MESG ("Invalid json token: a");
  bson::Document d;
  ASSERT_THROW(d.from_json("asdf"), bson::invalid_token);
  try
  {
    d.from_json("asdf");
  }
  catch (bson::invalid_token e)
  {
    std::string emesg(e.what());
    ASSERT_EQ(MESG, emesg);
  }
}

TEST(JSONConvert, EmptyObject)
{
  bson::Document d("{}");
  ASSERT_EQ(0, d.field_names().size());
}

TEST(JSONConvert, EmptyArray)
{
  bson::Document d("{\"asdf\": []}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(0, d["asdf"].data<bson::array>().size());
}

TEST(JSONConvert, NestedObject)
{
  bson::Document d("{\"asdf\": {}}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(0, d["asdf"].data<bson::Document>().field_names().size());
}

TEST(JSONConvert, MultiField)
{
  bson::Document d("{\"a\": 1, \"b\": 3.14000}");
  ASSERT_EQ(2, d.field_names().size());
  ASSERT_EQ(1, d["a"].data<long>());
  ASSERT_EQ(3.14000, d["b"].data<double>());
}

TEST(JSONConvert, MalformedJSONErrorTextCleanup)
{
  ASSERT_THROW(bson::Document d("\"asdf\""), bson::malformed_json);
}

TEST(JSONConvert, MalformedJSONErrorVectorCleanup)
{
  ASSERT_THROW(bson::Document d("{\"a\": [123, 3.14, \"asdf\"}]}"), bson::malformed_json);
}

TEST(JSONConvert, MalformedJSONErrorObjectCleanup)
{
  ASSERT_THROW(bson::Document d("{\"a\": {}"), bson::malformed_json);
}<commit_msg>change the test to avoid valgrind memory errors on ubuntu (hopefully)<commit_after>#include "../element.h"
#include "gtest/gtest.h"
#include "../document.h"
#include <sstream>
#include <string>
#include <iostream>
#include <array>
#include <vector>
#include <set>
#include "../json/jsonscanner.h"

TEST(JSONConvert, FromString)
{
  std::string key="asdf", value="asdf2";
  bson::Document d("{\"" + key + "\":\"" + value + "\"}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(value, d[key].data<std::string>());
}

TEST(JSONConvert, FromInt)
{
  std::string key="asdf", value="42";
  int ival = 42;
  bson::Document d("{\"" + key + "\":" + value + "}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(ival, d[key].data<long>());
}

TEST(JSONConvert, FromDouble)
{
  std::string key="asdf", value="3.14000";
  double dval = 3.14000;
  bson::Document d("{\"" + key + "\":" + value + "}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(dval, d[key].data<double>());
}

TEST(JSONConvert, FromNull)
{
  std::string key = "asdf";
  bson::Document d("{\"" + key + "\": null }");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(bson::NIL, d[key].get_type());
}

TEST(JSONConvert, FromArr)
{
  std::string key = "asdf";
  bson::Document d("{\"" + key + "\": [0, 1, 2, 3, 4, 5, 6.2] }");
  ASSERT_EQ(1, d.field_names().size());
  for (int i=0; i<6; i++)
    ASSERT_EQ(i, d[key].data<bson::array>()[i].data<long>());
  ASSERT_EQ(6.2, d[key].data<bson::array>()[6].data<double>());
}

TEST(JSONConvert, FromBool)
{
  std::string key = "asdf";
  bson::Document d("{\"" + key + "\": true }");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_TRUE(d[key].data<bool>());
  d.from_json("{\"" + key + "\": false }");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_FALSE(d[key].data<bool>());
}

TEST(JSONConvert, InvalidJSON)
{
  const char MESG[]= "Invalid json token: a";
  bson::Document d;
  ASSERT_THROW(d.from_json("asdf"), bson::invalid_token);
  try
  {
    d.from_json("asdf");
  }
  catch (bson::invalid_token e)
  {
    ASSERT_STREQ(MESG, e.what());
  }
}

TEST(JSONConvert, EmptyObject)
{
  bson::Document d("{}");
  ASSERT_EQ(0, d.field_names().size());
}

TEST(JSONConvert, EmptyArray)
{
  bson::Document d("{\"asdf\": []}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(0, d["asdf"].data<bson::array>().size());
}

TEST(JSONConvert, NestedObject)
{
  bson::Document d("{\"asdf\": {}}");
  ASSERT_EQ(1, d.field_names().size());
  ASSERT_EQ(0, d["asdf"].data<bson::Document>().field_names().size());
}

TEST(JSONConvert, MultiField)
{
  bson::Document d("{\"a\": 1, \"b\": 3.14000}");
  ASSERT_EQ(2, d.field_names().size());
  ASSERT_EQ(1, d["a"].data<long>());
  ASSERT_EQ(3.14000, d["b"].data<double>());
}

TEST(JSONConvert, MalformedJSONErrorTextCleanup)
{
  ASSERT_THROW(bson::Document d("\"asdf\""), bson::malformed_json);
}

TEST(JSONConvert, MalformedJSONErrorVectorCleanup)
{
  ASSERT_THROW(bson::Document d("{\"a\": [123, 3.14, \"asdf\"}]}"), bson::malformed_json);
}

TEST(JSONConvert, MalformedJSONErrorObjectCleanup)
{
  ASSERT_THROW(bson::Document d("{\"a\": {}"), bson::malformed_json);
}<|endoftext|>


<commit_before>#include "ovpCBoxAlgorithmCSPSpatialFilterTrainer.h"

#include <system/Memory.h>

#include <complex>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <math.h>
#include <iostream>

#include <itpp/base/algebra/eigen.h>
#include <itpp/base/algebra/inv.h>
#include <itpp/base/converters.h>
#include <itpp/stat/misc_stat.h>

using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Plugins;

using namespace OpenViBEPlugins;
using namespace OpenViBEPlugins::SignalProcessingGpl;

using namespace itpp;

// Taken from http://techlogbook.wordpress.com/2009/08/12/adding-generalized-eigenvalue-functions-to-it
//            http://techlogbook.wordpress.com/2009/08/12/calling-lapack-functions-from-c-codes
//            http://sourceforge.net/projects/itpp/forums/forum/115656/topic/3363490?message=7557038
//
// http://icl.cs.utk.edu/projectsfiles/f2j/javadoc/org/netlib/lapack/DSYGV.html
// http://www.lassp.cornell.edu/sethna/GeneDynamics/NetworkCodeDocumentation/lapack_8h.html#a17

namespace
{
	extern "C"
	{
		// This symbol comes from LAPACK
/*
		void zggev_(char *jobvl, char *jobvr, int *n, std::complex<double> *a,
			int *lda, std::complex<double> *b, int *ldb, std::complex<double> *alpha,
			std::complex<double> *beta, std::complex<double> *vl,
			int *ldvl, std::complex<double> *vr, int *ldvr,
			std::complex<double> *work, int *lwork, double *rwork, int *info);
*/
		int dsygv_(int* itype, char* jobz, char* uplo, int* n, double* a,
			int* lda, double* b, int* ldb, double* w, double* work, int* lwork, int* info);
	}
};

namespace itppextcsp
{
	itpp::mat convert(const IMatrix& rMatrix)
	{
		itpp::mat l_oResult(
			rMatrix.getDimensionSize(1),
			rMatrix.getDimensionSize(0));
		System::Memory::copy(l_oResult._data(), rMatrix.getBuffer(), rMatrix.getBufferElementCount()*sizeof(float64));
		return l_oResult.transpose();
	}

	itpp::mat cov(const itpp::mat inputMat)
	{
		itpp::mat l_oResult(inputMat.rows(),inputMat.rows());
		itpp::mat centeredMat(inputMat.rows(),inputMat.rows());
		centeredMat = itpp::repmat(itpp::sum(inputMat,2), 1, inputMat.cols(), false);
		centeredMat = centeredMat / ((double)inputMat.cols());
		centeredMat = inputMat-centeredMat;
		l_oResult = centeredMat*centeredMat.transpose();
		l_oResult = l_oResult / ((double)(inputMat.cols()-1));
		l_oResult = l_oResult / itpp::trace(l_oResult);
		return l_oResult;
	}
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::initialize(void)
{
	m_pStimulationDecoder=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationStreamDecoder));
	m_pStimulationDecoder->initialize();

	m_pSignalDecoderCondition1=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalStreamDecoder));
	m_pSignalDecoderCondition1->initialize();

	m_pSignalDecoderCondition2=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalStreamDecoder));
	m_pSignalDecoderCondition2->initialize();

	m_ui64StimulationIdentifier=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
	m_sSpatialFilterConfigurationFilename=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
	m_ui64FilterDimension=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);

	return true;
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::uninitialize(void)
{
	m_pSignalDecoderCondition1->uninitialize();
	m_pSignalDecoderCondition2->uninitialize();
	m_pStimulationDecoder->uninitialize();

	this->getAlgorithmManager().releaseAlgorithm(*m_pSignalDecoderCondition1);
	this->getAlgorithmManager().releaseAlgorithm(*m_pSignalDecoderCondition2);
	this->getAlgorithmManager().releaseAlgorithm(*m_pStimulationDecoder);

	m_pSignalDecoderCondition1=NULL;
	m_pSignalDecoderCondition2=NULL;
	m_pStimulationDecoder=NULL;

	return true;
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::processInput(uint32 ui32InputIndex)
{
	getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
	return true;
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::process(void)
{
	IBoxIO& l_rDynamicBoxContext=this->getDynamicBoxContext();

	boolean l_bShouldTrain=false;
	uint32 i, j, k;

	for(i=0; i<l_rDynamicBoxContext.getInputChunkCount(0); i++)
	{
		TParameterHandler < const IMemoryBuffer* > ip_pMemoryBuffer(m_pStimulationDecoder->getInputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_InputParameterId_MemoryBufferToDecode));
		ip_pMemoryBuffer=l_rDynamicBoxContext.getInputChunk(0, i);
		m_pStimulationDecoder->process();
		if(m_pStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedHeader))
		{
		}
		if(m_pStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedBuffer))
		{
			TParameterHandler < IStimulationSet* > op_pStimulationSet(m_pStimulationDecoder->getOutputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_OutputParameterId_StimulationSet));
			for(j=0; j<op_pStimulationSet->getStimulationCount(); j++)
			{
				l_bShouldTrain |= (op_pStimulationSet->getStimulationIdentifier(j)==m_ui64StimulationIdentifier);
			}
		}
		if(m_pStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedEnd))
		{
		}
		l_rDynamicBoxContext.markInputAsDeprecated(0, i);
	}

	if(l_bShouldTrain)
	{
		this->getLogManager() << LogLevel_Info << "Received train stimulation - be patient\n";

		this->getLogManager() << LogLevel_Trace << "Decoding motor signal 1...\n";

		itpp::mat l_oCovarianceMatrixCondition1;
		int l_iNumberOfCondition1Trials = 0;
		for(i=0; i<l_rDynamicBoxContext.getInputChunkCount(1); i++)
		{
			TParameterHandler<const IMemoryBuffer*> ip_pMemoryBuffer(m_pSignalDecoderCondition1->getInputParameter(OVP_GD_Algorithm_SignalStreamDecoder_InputParameterId_MemoryBufferToDecode));
			ip_pMemoryBuffer=l_rDynamicBoxContext.getInputChunk(1, i);
			m_pSignalDecoderCondition1->process();
			if(m_pSignalDecoderCondition1->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedHeader))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition1->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				l_oCovarianceMatrixCondition1(ip_pMatrix->getDimensionSize(0),ip_pMatrix->getDimensionSize(0));
			}
			if(m_pSignalDecoderCondition1->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedBuffer))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition1->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				itpp::mat l_oMatrix=itppextcsp::convert(*ip_pMatrix);
				l_oCovarianceMatrixCondition1 += itppextcsp::cov(l_oMatrix);
				l_iNumberOfCondition1Trials++;
			}
			if(m_pSignalDecoderCondition1->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedEnd))
			{
			}
			l_rDynamicBoxContext.markInputAsDeprecated(1, i);
		}
		l_oCovarianceMatrixCondition1 = l_oCovarianceMatrixCondition1/ ((double)l_iNumberOfCondition1Trials);
		this->getLogManager() << LogLevel_Debug << "Number of trials for condition 1: " << l_iNumberOfCondition1Trials << "\n";

		this->getLogManager() << LogLevel_Trace << "Decoding motor signal 2...\n";

		itpp::mat l_oCovarianceMatrixCondition2;
		int l_iNumberOfCondition2Trials = 0;
		for(i=0; i<l_rDynamicBoxContext.getInputChunkCount(2); i++)
		{
			TParameterHandler<const IMemoryBuffer*> ip_pMemoryBuffer(m_pSignalDecoderCondition2->getInputParameter(OVP_GD_Algorithm_SignalStreamDecoder_InputParameterId_MemoryBufferToDecode));
			ip_pMemoryBuffer=l_rDynamicBoxContext.getInputChunk(2, i);
			m_pSignalDecoderCondition2->process();
			if(m_pSignalDecoderCondition2->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedHeader))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition2->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				l_oCovarianceMatrixCondition2(ip_pMatrix->getDimensionSize(0),ip_pMatrix->getDimensionSize(0));
			}
			if(m_pSignalDecoderCondition2->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedBuffer))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition2->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				itpp::mat l_oMatrix=itppextcsp::convert(*ip_pMatrix);
				l_oCovarianceMatrixCondition2 += itppextcsp::cov(l_oMatrix);
				l_iNumberOfCondition2Trials++;
			}
			if(m_pSignalDecoderCondition2->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedEnd))
			{
			}
			l_rDynamicBoxContext.markInputAsDeprecated(2, i);
		}
		l_oCovarianceMatrixCondition2 = l_oCovarianceMatrixCondition2/ ((double)l_iNumberOfCondition2Trials);
		this->getLogManager() << LogLevel_Debug << "Number of trials for condition 2: " << l_iNumberOfCondition2Trials << "\n";

		if(l_iNumberOfCondition1Trials==0 || l_iNumberOfCondition2Trials==0)
		{
			this->getLogManager() << LogLevel_Error << "No signal received... Can't continue\n";
			return true;
		}

		this->getLogManager() << LogLevel_Trace << "Computing eigen vector decomposition...\n";

		itpp::cmat l_oEigenVector;
		itpp::cvec l_oEigenValue;
		uint32 l_ui32ChannelCount= l_oCovarianceMatrixCondition1.rows();

		if(itpp::eig(itpp::inv(l_oCovarianceMatrixCondition2)*l_oCovarianceMatrixCondition1, l_oEigenValue, l_oEigenVector))
		{
			std::map < double, itpp::vec > l_vEigenVector;
			for(i=0; i<l_ui32ChannelCount; i++)
			{
				itpp::cvec l_oVector=l_oEigenVector.get_col(i);
				l_vEigenVector[itpp::real(l_oEigenValue)[i]]=itpp::real(l_oVector);
			}

			FILE* l_pFile=::fopen(m_sSpatialFilterConfigurationFilename.toASCIIString(), "wb");
			if(!l_pFile)
			{
				this->getLogManager() << LogLevel_Error << "The file [" << m_sSpatialFilterConfigurationFilename << "] could not be opened for writing...";
				return false;
			}

			std::map < double, itpp::vec >::const_iterator it_forward;
			::fprintf(l_pFile, "<OpenViBE-SettingsOverride>\n");
			::fprintf(l_pFile, "\t<SettingValue>");
			this->getLogManager() << LogLevel_Debug << "lowest eigenvalues: " << "\n";
			for(it_forward=l_vEigenVector.begin(), i=0; it_forward!=l_vEigenVector.end() && i< ::ceil(m_ui64FilterDimension/2.0); it_forward++, i++)
			{
				this->getLogManager() << LogLevel_Debug << it_forward->first << ", ";
				for(j=0; j<l_ui32ChannelCount; j++)
				{
					::fprintf(l_pFile, "%e ", it_forward->second[j]);
				}
			}
			this->getLogManager() << LogLevel_Debug << "\n";

			std::map < double, itpp::vec >::const_reverse_iterator it_backward;
			this->getLogManager() << LogLevel_Debug << "highest eigenvalues: " << "\n";
			for(it_backward=l_vEigenVector.rbegin(), i=0; it_backward!=l_vEigenVector.rend() && i< ::floor(m_ui64FilterDimension/2.0); it_backward++, i++)
			{
				this->getLogManager() << LogLevel_Debug << it_backward->first << ", ";
				for(j=0; j<l_ui32ChannelCount; j++)
				{
					::fprintf(l_pFile, "%e ", it_backward->second[j]);
				}
			}
			this->getLogManager() << LogLevel_Debug << "\n";
			::fprintf(l_pFile, "</SettingValue>\n");
			::fprintf(l_pFile, "\t<SettingValue>%d</SettingValue>\n", uint32(m_ui64FilterDimension));
			::fprintf(l_pFile, "\t<SettingValue>%d</SettingValue>\n", l_ui32ChannelCount);
			::fprintf(l_pFile, "</OpenViBE-SettingsOverride>\n");
			::fclose(l_pFile);

		}
		else
		{
			this->getLogManager() << LogLevel_ImportantWarning << "Eigen vector decomposition failed...\n";
			return true;
		}

		this->getLogManager() << LogLevel_Info << "CSP Spatial filter trained successfully.\n";
	}

	return true;
}
<commit_msg>OpenViBE-plugins-signal-processing-gpl *ovpCBoxAlgorithmCSPSpatialFilterTrainer.cpp : fixed an error message (missing '\n' at the end).<commit_after>#include "ovpCBoxAlgorithmCSPSpatialFilterTrainer.h"

#include <system/Memory.h>

#include <complex>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <map>
#include <math.h>
#include <iostream>

#include <itpp/base/algebra/eigen.h>
#include <itpp/base/algebra/inv.h>
#include <itpp/base/converters.h>
#include <itpp/stat/misc_stat.h>

using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBE::Plugins;

using namespace OpenViBEPlugins;
using namespace OpenViBEPlugins::SignalProcessingGpl;

using namespace itpp;

// Taken from http://techlogbook.wordpress.com/2009/08/12/adding-generalized-eigenvalue-functions-to-it
//            http://techlogbook.wordpress.com/2009/08/12/calling-lapack-functions-from-c-codes
//            http://sourceforge.net/projects/itpp/forums/forum/115656/topic/3363490?message=7557038
//
// http://icl.cs.utk.edu/projectsfiles/f2j/javadoc/org/netlib/lapack/DSYGV.html
// http://www.lassp.cornell.edu/sethna/GeneDynamics/NetworkCodeDocumentation/lapack_8h.html#a17

namespace
{
	extern "C"
	{
		// This symbol comes from LAPACK
/*
		void zggev_(char *jobvl, char *jobvr, int *n, std::complex<double> *a,
			int *lda, std::complex<double> *b, int *ldb, std::complex<double> *alpha,
			std::complex<double> *beta, std::complex<double> *vl,
			int *ldvl, std::complex<double> *vr, int *ldvr,
			std::complex<double> *work, int *lwork, double *rwork, int *info);
*/
		int dsygv_(int* itype, char* jobz, char* uplo, int* n, double* a,
			int* lda, double* b, int* ldb, double* w, double* work, int* lwork, int* info);
	}
};

namespace itppextcsp
{
	itpp::mat convert(const IMatrix& rMatrix)
	{
		itpp::mat l_oResult(
			rMatrix.getDimensionSize(1),
			rMatrix.getDimensionSize(0));
		System::Memory::copy(l_oResult._data(), rMatrix.getBuffer(), rMatrix.getBufferElementCount()*sizeof(float64));
		return l_oResult.transpose();
	}

	itpp::mat cov(const itpp::mat inputMat)
	{
		itpp::mat l_oResult(inputMat.rows(),inputMat.rows());
		itpp::mat centeredMat(inputMat.rows(),inputMat.rows());
		centeredMat = itpp::repmat(itpp::sum(inputMat,2), 1, inputMat.cols(), false);
		centeredMat = centeredMat / ((double)inputMat.cols());
		centeredMat = inputMat-centeredMat;
		l_oResult = centeredMat*centeredMat.transpose();
		l_oResult = l_oResult / ((double)(inputMat.cols()-1));
		l_oResult = l_oResult / itpp::trace(l_oResult);
		return l_oResult;
	}
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::initialize(void)
{
	m_pStimulationDecoder=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationStreamDecoder));
	m_pStimulationDecoder->initialize();

	m_pSignalDecoderCondition1=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalStreamDecoder));
	m_pSignalDecoderCondition1->initialize();

	m_pSignalDecoderCondition2=&this->getAlgorithmManager().getAlgorithm(this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_SignalStreamDecoder));
	m_pSignalDecoderCondition2->initialize();

	m_ui64StimulationIdentifier=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
	m_sSpatialFilterConfigurationFilename=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
	m_ui64FilterDimension=FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);

	return true;
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::uninitialize(void)
{
	m_pSignalDecoderCondition1->uninitialize();
	m_pSignalDecoderCondition2->uninitialize();
	m_pStimulationDecoder->uninitialize();

	this->getAlgorithmManager().releaseAlgorithm(*m_pSignalDecoderCondition1);
	this->getAlgorithmManager().releaseAlgorithm(*m_pSignalDecoderCondition2);
	this->getAlgorithmManager().releaseAlgorithm(*m_pStimulationDecoder);

	m_pSignalDecoderCondition1=NULL;
	m_pSignalDecoderCondition2=NULL;
	m_pStimulationDecoder=NULL;

	return true;
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::processInput(uint32 ui32InputIndex)
{
	getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
	return true;
}

boolean CBoxAlgorithmCSPSpatialFilterTrainer::process(void)
{
	IBoxIO& l_rDynamicBoxContext=this->getDynamicBoxContext();

	boolean l_bShouldTrain=false;
	uint32 i, j, k;

	for(i=0; i<l_rDynamicBoxContext.getInputChunkCount(0); i++)
	{
		TParameterHandler < const IMemoryBuffer* > ip_pMemoryBuffer(m_pStimulationDecoder->getInputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_InputParameterId_MemoryBufferToDecode));
		ip_pMemoryBuffer=l_rDynamicBoxContext.getInputChunk(0, i);
		m_pStimulationDecoder->process();
		if(m_pStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedHeader))
		{
		}
		if(m_pStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedBuffer))
		{
			TParameterHandler < IStimulationSet* > op_pStimulationSet(m_pStimulationDecoder->getOutputParameter(OVP_GD_Algorithm_StimulationStreamDecoder_OutputParameterId_StimulationSet));
			for(j=0; j<op_pStimulationSet->getStimulationCount(); j++)
			{
				l_bShouldTrain |= (op_pStimulationSet->getStimulationIdentifier(j)==m_ui64StimulationIdentifier);
			}
		}
		if(m_pStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationStreamDecoder_OutputTriggerId_ReceivedEnd))
		{
		}
		l_rDynamicBoxContext.markInputAsDeprecated(0, i);
	}

	if(l_bShouldTrain)
	{
		this->getLogManager() << LogLevel_Info << "Received train stimulation - be patient\n";

		this->getLogManager() << LogLevel_Trace << "Decoding motor signal 1...\n";

		itpp::mat l_oCovarianceMatrixCondition1;
		int l_iNumberOfCondition1Trials = 0;
		for(i=0; i<l_rDynamicBoxContext.getInputChunkCount(1); i++)
		{
			TParameterHandler<const IMemoryBuffer*> ip_pMemoryBuffer(m_pSignalDecoderCondition1->getInputParameter(OVP_GD_Algorithm_SignalStreamDecoder_InputParameterId_MemoryBufferToDecode));
			ip_pMemoryBuffer=l_rDynamicBoxContext.getInputChunk(1, i);
			m_pSignalDecoderCondition1->process();
			if(m_pSignalDecoderCondition1->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedHeader))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition1->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				l_oCovarianceMatrixCondition1(ip_pMatrix->getDimensionSize(0),ip_pMatrix->getDimensionSize(0));
			}
			if(m_pSignalDecoderCondition1->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedBuffer))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition1->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				itpp::mat l_oMatrix=itppextcsp::convert(*ip_pMatrix);
				l_oCovarianceMatrixCondition1 += itppextcsp::cov(l_oMatrix);
				l_iNumberOfCondition1Trials++;
			}
			if(m_pSignalDecoderCondition1->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedEnd))
			{
			}
			l_rDynamicBoxContext.markInputAsDeprecated(1, i);
		}
		l_oCovarianceMatrixCondition1 = l_oCovarianceMatrixCondition1/ ((double)l_iNumberOfCondition1Trials);
		this->getLogManager() << LogLevel_Debug << "Number of trials for condition 1: " << l_iNumberOfCondition1Trials << "\n";

		this->getLogManager() << LogLevel_Trace << "Decoding motor signal 2...\n";

		itpp::mat l_oCovarianceMatrixCondition2;
		int l_iNumberOfCondition2Trials = 0;
		for(i=0; i<l_rDynamicBoxContext.getInputChunkCount(2); i++)
		{
			TParameterHandler<const IMemoryBuffer*> ip_pMemoryBuffer(m_pSignalDecoderCondition2->getInputParameter(OVP_GD_Algorithm_SignalStreamDecoder_InputParameterId_MemoryBufferToDecode));
			ip_pMemoryBuffer=l_rDynamicBoxContext.getInputChunk(2, i);
			m_pSignalDecoderCondition2->process();
			if(m_pSignalDecoderCondition2->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedHeader))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition2->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				l_oCovarianceMatrixCondition2(ip_pMatrix->getDimensionSize(0),ip_pMatrix->getDimensionSize(0));
			}
			if(m_pSignalDecoderCondition2->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedBuffer))
			{
				TParameterHandler<IMatrix*> ip_pMatrix(m_pSignalDecoderCondition2->getOutputParameter(OVP_GD_Algorithm_SignalStreamDecoder_OutputParameterId_Matrix));
				itpp::mat l_oMatrix=itppextcsp::convert(*ip_pMatrix);
				l_oCovarianceMatrixCondition2 += itppextcsp::cov(l_oMatrix);
				l_iNumberOfCondition2Trials++;
			}
			if(m_pSignalDecoderCondition2->isOutputTriggerActive(OVP_GD_Algorithm_SignalStreamDecoder_OutputTriggerId_ReceivedEnd))
			{
			}
			l_rDynamicBoxContext.markInputAsDeprecated(2, i);
		}
		l_oCovarianceMatrixCondition2 = l_oCovarianceMatrixCondition2/ ((double)l_iNumberOfCondition2Trials);
		this->getLogManager() << LogLevel_Debug << "Number of trials for condition 2: " << l_iNumberOfCondition2Trials << "\n";

		if(l_iNumberOfCondition1Trials==0 || l_iNumberOfCondition2Trials==0)
		{
			this->getLogManager() << LogLevel_Error << "No signal received... Can't continue\n";
			return true;
		}

		this->getLogManager() << LogLevel_Trace << "Computing eigen vector decomposition...\n";

		itpp::cmat l_oEigenVector;
		itpp::cvec l_oEigenValue;
		uint32 l_ui32ChannelCount= l_oCovarianceMatrixCondition1.rows();

		if(itpp::eig(itpp::inv(l_oCovarianceMatrixCondition2)*l_oCovarianceMatrixCondition1, l_oEigenValue, l_oEigenVector))
		{
			std::map < double, itpp::vec > l_vEigenVector;
			for(i=0; i<l_ui32ChannelCount; i++)
			{
				itpp::cvec l_oVector=l_oEigenVector.get_col(i);
				l_vEigenVector[itpp::real(l_oEigenValue)[i]]=itpp::real(l_oVector);
			}

			FILE* l_pFile=::fopen(m_sSpatialFilterConfigurationFilename.toASCIIString(), "wb");
			if(!l_pFile)
			{
				this->getLogManager() << LogLevel_Error << "The file [" << m_sSpatialFilterConfigurationFilename << "] could not be opened for writing...\n";
				return false;
			}

			std::map < double, itpp::vec >::const_iterator it_forward;
			::fprintf(l_pFile, "<OpenViBE-SettingsOverride>\n");
			::fprintf(l_pFile, "\t<SettingValue>");
			this->getLogManager() << LogLevel_Debug << "lowest eigenvalues: " << "\n";
			for(it_forward=l_vEigenVector.begin(), i=0; it_forward!=l_vEigenVector.end() && i< ::ceil(m_ui64FilterDimension/2.0); it_forward++, i++)
			{
				this->getLogManager() << LogLevel_Debug << it_forward->first << ", ";
				for(j=0; j<l_ui32ChannelCount; j++)
				{
					::fprintf(l_pFile, "%e ", it_forward->second[j]);
				}
			}
			this->getLogManager() << LogLevel_Debug << "\n";

			std::map < double, itpp::vec >::const_reverse_iterator it_backward;
			this->getLogManager() << LogLevel_Debug << "highest eigenvalues: " << "\n";
			for(it_backward=l_vEigenVector.rbegin(), i=0; it_backward!=l_vEigenVector.rend() && i< ::floor(m_ui64FilterDimension/2.0); it_backward++, i++)
			{
				this->getLogManager() << LogLevel_Debug << it_backward->first << ", ";
				for(j=0; j<l_ui32ChannelCount; j++)
				{
					::fprintf(l_pFile, "%e ", it_backward->second[j]);
				}
			}
			this->getLogManager() << LogLevel_Debug << "\n";
			::fprintf(l_pFile, "</SettingValue>\n");
			::fprintf(l_pFile, "\t<SettingValue>%d</SettingValue>\n", uint32(m_ui64FilterDimension));
			::fprintf(l_pFile, "\t<SettingValue>%d</SettingValue>\n", l_ui32ChannelCount);
			::fprintf(l_pFile, "</OpenViBE-SettingsOverride>\n");
			::fclose(l_pFile);

		}
		else
		{
			this->getLogManager() << LogLevel_ImportantWarning << "Eigen vector decomposition failed...\n";
			return true;
		}

		this->getLogManager() << LogLevel_Info << "CSP Spatial filter trained successfully.\n";
	}

	return true;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/python.hpp>
#include <mapnik/raster_symbolizer.hpp>

void export_raster_symbolizer()
{
    using namespace boost::python;
    using mapnik::raster_symbolizer;

    class_<raster_symbolizer>("RasterSymbolizer",
				    init<>("Default ctor"))

    .add_property("mode",
            make_function(&raster_symbolizer::get_mode,return_value_policy<copy_const_reference>()),
            &raster_symbolizer::set_mode,
            "Get/Set merging mode.\n"
            "Possible values are:\n"
            "normal, grain_merge, grain_merge2, multiply,\n"
            "multiply2, divide, divide2, screen, and hard_light\n"
            "\n"
            "Usage:\n"
            "\n"
            ">>> from mapnik import RasterSymbolizer\n"
            ">>> r = RasterSymbolizer()\n"
            ">>> r.mode = 'grain_merge2'\n"
            )

    .add_property("scaling",
            make_function(&raster_symbolizer::get_scaling,return_value_policy<copy_const_reference>()),
            &raster_symbolizer::set_scaling,
            "Get/Set scaling algorithm.\n"
            "Possible values are:\n"
            "fast, bilinear, and bilinear8\n"
            "\n"
            "Usage:\n"
            "\n"
            ">>> from mapnik import RasterSymbolizer\n"
            ">>> r = RasterSymbolizer()\n"
            ">>> r.scaling = 'bilinear8'\n"
            )

    .add_property("opacity",
            &raster_symbolizer::get_opacity,
            &raster_symbolizer::set_opacity,
            "Get/Set opacity.\n"
            "\n"
            "Usage:\n"
            "\n"
            ">>> from mapnik import RasterSymbolizer\n"
            ">>> r = RasterSymbolizer()\n"
            ">>> r.opacity = .5\n"
            )
	;
}
<commit_msg>+add pickle support for raster_symbolizer - see #345<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

#include <boost/python.hpp>
#include <mapnik/raster_symbolizer.hpp>

using mapnik::raster_symbolizer;

struct raster_symbolizer_pickle_suite : boost::python::pickle_suite
{
   /*
   static boost::python::tuple
   getinitargs(const raster_symbolizer& r)
   {
      return boost::python::make_tuple();
   }
   */

   static  boost::python::tuple
   getstate(const raster_symbolizer& r)
   {
        return boost::python::make_tuple(r.get_mode(),r.get_scaling(),r.get_opacity());
   }

   static void
   setstate (raster_symbolizer& r, boost::python::tuple state)
   {
        using namespace boost::python;
        if (len(state) != 3)
        {
            PyErr_SetObject(PyExc_ValueError,
                         ("expected 3-item tuple in call to __setstate__; got %s"
                          % state).ptr()
            );
            throw_error_already_set();
        }

        r.set_mode(extract<std::string>(state[0]));
        r.set_scaling(extract<std::string>(state[1]));
        r.set_opacity(extract<float>(state[2]));
   }

};

void export_raster_symbolizer()
{
    using namespace boost::python;

    class_<raster_symbolizer>("RasterSymbolizer",
				    init<>("Default ctor"))

    .def_pickle(raster_symbolizer_pickle_suite())

    .add_property("mode",
            make_function(&raster_symbolizer::get_mode,return_value_policy<copy_const_reference>()),
            &raster_symbolizer::set_mode,
            "Get/Set merging mode.\n"
            "Possible values are:\n"
            "normal, grain_merge, grain_merge2, multiply,\n"
            "multiply2, divide, divide2, screen, and hard_light\n"
            "\n"
            "Usage:\n"
            "\n"
            ">>> from mapnik import RasterSymbolizer\n"
            ">>> r = RasterSymbolizer()\n"
            ">>> r.mode = 'grain_merge2'\n"
            )

    .add_property("scaling",
            make_function(&raster_symbolizer::get_scaling,return_value_policy<copy_const_reference>()),
            &raster_symbolizer::set_scaling,
            "Get/Set scaling algorithm.\n"
            "Possible values are:\n"
            "fast, bilinear, and bilinear8\n"
            "\n"
            "Usage:\n"
            "\n"
            ">>> from mapnik import RasterSymbolizer\n"
            ">>> r = RasterSymbolizer()\n"
            ">>> r.scaling = 'bilinear8'\n"
            )

    .add_property("opacity",
            &raster_symbolizer::get_opacity,
            &raster_symbolizer::set_opacity,
            "Get/Set opacity.\n"
            "\n"
            "Usage:\n"
            "\n"
            ">>> from mapnik import RasterSymbolizer\n"
            ">>> r = RasterSymbolizer()\n"
            ">>> r.opacity = .5\n"
            )
	;
}
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <python/helpers/numpy_memory_chunk.h>
#include <python/helpers/python_wrap_vil_smart_ptr.h>

#include <vistk/python/any_conversion/prototypes.h>
#include <vistk/python/any_conversion/registration.h>

#include <boost/python/converter/registry.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/object.hpp>

#include <vil/vil_image_view.h>
#include <vil/vil_memory_chunk.h>

#include <numpy/ndarrayobject.h>
#include <numpy/ndarraytypes.h>

/**
 * \file vil.cxx
 *
 * \brief Python bindings for \link vil_image_view\endlink.
 */

using namespace boost::python;

template <typename T>
static NPY_TYPES python_pixel_type();

template <typename T>
class vil_image_converter
{
  public:
    typedef T image_t;
    typedef typename image_t::pixel_type pixel_t;

    vil_image_converter()
    {
      boost::python::converter::registry::push_back(
        &convertible,
        &construct,
        boost::python::type_id<image_t>());
    }
    ~vil_image_converter()
    {
    }

    static void* convertible(PyObject* obj)
    {
      if (obj == Py_None)
      {
        return NULL;
      }

      if (PyArray_Check(obj))
      {
        PyArrayObject* const arr = reinterpret_cast<PyArrayObject*>(obj);
        int const ndim = PyArray_NDIM(arr);

        if (ndim != 3)
        {
          return NULL;
        }

        NPY_TYPES const expected_type = python_pixel_type<pixel_t>();
        int const type = PyArray_TYPE(arr);

        if (type != expected_type)
        {
          return NULL;
        }

        return obj;
      }

      return NULL;
    }

    static PyObject* convert(image_t const& img)
    {
      NPY_TYPES const arr_type = python_pixel_type<pixel_t>();
      int const nd = 3;
      npy_intp* const dims = PyDimMem_NEW(nd);
      npy_intp* const strides = PyDimMem_NEW(nd);
      bool const contig = img.is_contiguous();

      dims[0] = img.ni();
      dims[1] = img.nj();
      dims[2] = img.nplanes();

      strides[0] = img.istep();
      strides[1] = img.jstep();
      strides[2] = img.planestep();

      int flags = 0;

      if (contig)
      {
        if (img.planestep() == 1)
        {
          flags |= NPY_CONTIGUOUS;
        }
        else if (img.istep() == 1)
        {
          flags |= NPY_FORTRAN;
        }
      }

      flags |= NPY_WRITEABLE;
      flags |= NPY_NOTSWAPPED;

      uintptr_t const mem = reinterpret_cast<uintptr_t>(img.top_left_ptr());

      if (!(mem % sizeof(T)))
      {
        flags |= NPY_ALIGNED;
      }

      PyObject* obj = Py_None;

      if (img.memory_chunk())
      {
        object bp_obj = object(img.memory_chunk());
        obj = bp_obj.ptr();
      }
      else
      {
        /// \todo Log that vil doesn't own this memory...there be dragon's here.
        Py_INCREF(obj);
      }

      PyObject* const arr = PyArray_New(&PyArray_Type, nd, dims, arr_type, strides, reinterpret_cast<void*>(mem), 0, flags, obj);

      return arr;
    }

    static void construct(PyObject* obj, boost::python::converter::rvalue_from_python_stage1_data* data)
    {
      void* storage = reinterpret_cast<boost::python::converter::rvalue_from_python_storage<image_t>*>(data)->storage.bytes;

      PyArrayObject* const arr = reinterpret_cast<PyArrayObject*>(obj);
      npy_intp const* const dims = PyArray_DIMS(arr);
      npy_intp const* const strides = PyArray_STRIDES(arr);
      void* const mem = PyArray_DATA(arr);

      vil_memory_chunk_sptr chunk = new numpy_memory_chunk(arr);

      new (storage) image_t(chunk, reinterpret_cast<pixel_t*>(mem),
                            dims[0], dims[1], dims[2],
                            strides[0], strides[1], strides[2]);
      data->convertible = storage;
    }
};

template <typename T>
void register_vil_image_converter();

BOOST_PYTHON_MODULE(vil)
{
  import_array();

  // Expose vil_memory_chunk to Python. This is treated as opaque because Python
  // shouldn't be messing with such things, but it allows us to have numpy
  // arrays hold a reference to the memory chunk that is being used when
  // converting a vil_image_view into a NumPy array.
  class_<vil_memory_chunk, vil_memory_chunk_sptr, boost::noncopyable>("_VilMemoryChunk"
    , "<internal>"
    , no_init);

  register_vil_image_converter<vil_image_view<bool> >();
  register_vil_image_converter<vil_image_view<uint8_t> >();
  register_vil_image_converter<vil_image_view<float> >();
  register_vil_image_converter<vil_image_view<double> >();

  vistk::python::register_type<vil_image_view<bool> >(10);
  vistk::python::register_type<vil_image_view<uint8_t> >(10);
  vistk::python::register_type<vil_image_view<float> >(10);
  vistk::python::register_type<vil_image_view<double> >(10);
}

template <>
NPY_TYPES
python_pixel_type<bool>()
{
  return NPY_BOOL;
}

template <>
NPY_TYPES
python_pixel_type<uint8_t>()
{
  return NPY_UBYTE;
}

template <>
NPY_TYPES
python_pixel_type<float>()
{
  return NPY_FLOAT;
}

template <>
NPY_TYPES
python_pixel_type<double>()
{
  return NPY_DOUBLE;
}

template <typename T>
void
register_vil_image_converter()
{
  typedef vil_image_converter<T> converter_t;
  typedef typename converter_t::image_t image_t;

  boost::python::to_python_converter<image_t, converter_t>();
  converter_t();
}
<commit_msg>Clean up headers<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <python/helpers/numpy_memory_chunk.h>
#include <python/helpers/python_wrap_vil_smart_ptr.h>

#include <vistk/python/any_conversion/prototypes.h>
#include <vistk/python/any_conversion/registration.h>

#include <boost/python/converter/registry.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/python/module.hpp>
#include <boost/python/object.hpp>
#include <boost/cstdint.hpp>

#include <vil/vil_image_view.h>
#include <vil/vil_memory_chunk.h>

#include <Python.h>

#include <numpy/arrayobject.h>

/**
 * \file vil.cxx
 *
 * \brief Python bindings for \link vil_image_view\endlink.
 */

using namespace boost::python;

template <typename T>
static NPY_TYPES python_pixel_type();

template <typename T>
class vil_image_converter
{
  public:
    typedef T image_t;
    typedef typename image_t::pixel_type pixel_t;

    vil_image_converter()
    {
      boost::python::converter::registry::push_back(
        &convertible,
        &construct,
        boost::python::type_id<image_t>());
    }
    ~vil_image_converter()
    {
    }

    static void* convertible(PyObject* obj)
    {
      if (obj == Py_None)
      {
        return NULL;
      }

      if (PyArray_Check(obj))
      {
        PyArrayObject* const arr = reinterpret_cast<PyArrayObject*>(obj);
        int const ndim = PyArray_NDIM(arr);

        if (ndim != 3)
        {
          return NULL;
        }

        NPY_TYPES const expected_type = python_pixel_type<pixel_t>();
        int const type = PyArray_TYPE(arr);

        if (type != expected_type)
        {
          return NULL;
        }

        return obj;
      }

      return NULL;
    }

    static PyObject* convert(image_t const& img)
    {
      NPY_TYPES const arr_type = python_pixel_type<pixel_t>();
      int const nd = 3;
      npy_intp* const dims = PyDimMem_NEW(nd);
      npy_intp* const strides = PyDimMem_NEW(nd);
      bool const contig = img.is_contiguous();

      dims[0] = img.ni();
      dims[1] = img.nj();
      dims[2] = img.nplanes();

      strides[0] = img.istep();
      strides[1] = img.jstep();
      strides[2] = img.planestep();

      int flags = 0;

      if (contig)
      {
        if (img.planestep() == 1)
        {
          flags |= NPY_CONTIGUOUS;
        }
        else if (img.istep() == 1)
        {
          flags |= NPY_FORTRAN;
        }
      }

      flags |= NPY_WRITEABLE;
      flags |= NPY_NOTSWAPPED;

      uintptr_t const mem = reinterpret_cast<uintptr_t>(img.top_left_ptr());

      if (!(mem % sizeof(T)))
      {
        flags |= NPY_ALIGNED;
      }

      PyObject* obj = Py_None;

      if (img.memory_chunk())
      {
        object bp_obj = object(img.memory_chunk());
        obj = bp_obj.ptr();
      }
      else
      {
        /// \todo Log that vil doesn't own this memory...there be dragon's here.
        Py_INCREF(obj);
      }

      PyObject* const arr = PyArray_New(&PyArray_Type, nd, dims, arr_type, strides, reinterpret_cast<void*>(mem), 0, flags, obj);

      return arr;
    }

    static void construct(PyObject* obj, boost::python::converter::rvalue_from_python_stage1_data* data)
    {
      void* storage = reinterpret_cast<boost::python::converter::rvalue_from_python_storage<image_t>*>(data)->storage.bytes;

      PyArrayObject* const arr = reinterpret_cast<PyArrayObject*>(obj);
      npy_intp const* const dims = PyArray_DIMS(arr);
      npy_intp const* const strides = PyArray_STRIDES(arr);
      void* const mem = PyArray_DATA(arr);

      vil_memory_chunk_sptr chunk = new numpy_memory_chunk(arr);

      new (storage) image_t(chunk, reinterpret_cast<pixel_t*>(mem),
                            dims[0], dims[1], dims[2],
                            strides[0], strides[1], strides[2]);
      data->convertible = storage;
    }
};

template <typename T>
void register_vil_image_converter();

BOOST_PYTHON_MODULE(vil)
{
  import_array();

  // Expose vil_memory_chunk to Python. This is treated as opaque because Python
  // shouldn't be messing with such things, but it allows us to have numpy
  // arrays hold a reference to the memory chunk that is being used when
  // converting a vil_image_view into a NumPy array.
  class_<vil_memory_chunk, vil_memory_chunk_sptr, boost::noncopyable>("_VilMemoryChunk"
    , "<internal>"
    , no_init);

  register_vil_image_converter<vil_image_view<bool> >();
  register_vil_image_converter<vil_image_view<uint8_t> >();
  register_vil_image_converter<vil_image_view<float> >();
  register_vil_image_converter<vil_image_view<double> >();

  vistk::python::register_type<vil_image_view<bool> >(10);
  vistk::python::register_type<vil_image_view<uint8_t> >(10);
  vistk::python::register_type<vil_image_view<float> >(10);
  vistk::python::register_type<vil_image_view<double> >(10);
}

template <>
NPY_TYPES
python_pixel_type<bool>()
{
  return NPY_BOOL;
}

template <>
NPY_TYPES
python_pixel_type<uint8_t>()
{
  return NPY_UBYTE;
}

template <>
NPY_TYPES
python_pixel_type<float>()
{
  return NPY_FLOAT;
}

template <>
NPY_TYPES
python_pixel_type<double>()
{
  return NPY_DOUBLE;
}

template <typename T>
void
register_vil_image_converter()
{
  typedef vil_image_converter<T> converter_t;
  typedef typename converter_t::image_t image_t;

  boost::python::to_python_converter<image_t, converter_t>();
  converter_t();
}
<|endoftext|>