<commit_before>//===-- JIT.cpp - LLVM Just in Time Compiler ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the top-level support for creating a Just-In-Time
// compiler for the current architecture.
//
//===----------------------------------------------------------------------===//

#include "VM.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "Support/CommandLine.h"

// FIXME: REMOVE THIS
#include "llvm/PassManager.h"

#if !defined(ENABLE_X86_JIT) && !defined(ENABLE_SPARC_JIT)
#define NO_JITS_ENABLED
#endif

namespace {
  enum ArchName { x86, Sparc };

#ifndef NO_JITS_ENABLED
  cl::opt<ArchName>
  Arch("march", cl::desc("Architecture to JIT to:"), cl::Prefix,
       cl::values(
#ifdef ENABLE_X86_JIT
                  clEnumVal(x86, "  IA-32 (Pentium and above)"),
#endif
#ifdef ENABLE_SPARC_JIT
                  clEnumValN(Sparc, "sparc", "  Sparc-V9"),
#endif
                  0),
#if defined(ENABLE_X86_JIT)
  cl::init(x86)
#elif defined(ENABLE_SPARC_JIT)
  cl::init(Sparc)
#endif
       );
#endif /* NO_JITS_ENABLED */
}

/// create - Create an return a new JIT compiler if there is one available
/// for the current target.  Otherwise, return null.
///
ExecutionEngine *VM::create(ModuleProvider *MP) {
  TargetMachine* (*TargetMachineAllocator)(const Module &) = 0;

  // Allow a command-line switch to override what *should* be the default target
  // machine for this platform. This allows for debugging a Sparc JIT on X86 --
  // our X86 machines are much faster at recompiling LLVM and linking LLI.
#ifndef NO_JITS_ENABLED

  switch (Arch) {
#ifdef ENABLE_X86_JIT
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
#endif
#ifdef ENABLE_SPARC_JIT
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
#endif
  default:
    assert(0 && "-march flag not supported on this host!");
  }
#else
  return 0;
#endif

  // Allocate a target...
  TargetMachine *Target = TargetMachineAllocator(*MP->getModule());
  assert(Target && "Could not allocate target machine!");

  // Create the virtual machine object...
  return new VM(MP, Target);
}

VM::VM(ModuleProvider *MP, TargetMachine *tm) : ExecutionEngine(MP), TM(*tm),
  PM(MP)
{
  setTargetData(TM.getTargetData());

  // Initialize MCE
  MCE = createEmitter(*this);

  setupPassManager();

  emitGlobals();
}

/// run - Start execution with the specified function and arguments.
///
GenericValue VM::run(Function *F, const std::vector<GenericValue> &ArgValues)
{
  assert (F && "Function *F was null at entry to run()");

  int (*PF)(int, char **, const char **) =
    (int(*)(int, char **, const char **))getPointerToFunction(F);
  assert(PF != 0 && "Pointer to fn's code was null after getPointerToFunction");

  // Call the function.
  int ExitCode = PF(ArgValues[0].IntVal, (char **) GVTOP (ArgValues[1]),
		    (const char **) GVTOP (ArgValues[2]));

  // Run any atexit handlers now!
  runAtExitHandlers();

  GenericValue rv;
  rv.IntVal = ExitCode;
  return rv;
}
<commit_msg>Remove #include of PassManager.h which was marked FIXME, and apparently is no longer used.<commit_after>//===-- JIT.cpp - LLVM Just in Time Compiler ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the top-level support for creating a Just-In-Time
// compiler for the current architecture.
//
//===----------------------------------------------------------------------===//

#include "VM.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachineImpls.h"
#include "Support/CommandLine.h"

#if !defined(ENABLE_X86_JIT) && !defined(ENABLE_SPARC_JIT)
#define NO_JITS_ENABLED
#endif

namespace {
  enum ArchName { x86, Sparc };

#ifndef NO_JITS_ENABLED
  cl::opt<ArchName>
  Arch("march", cl::desc("Architecture to JIT to:"), cl::Prefix,
       cl::values(
#ifdef ENABLE_X86_JIT
                  clEnumVal(x86, "  IA-32 (Pentium and above)"),
#endif
#ifdef ENABLE_SPARC_JIT
                  clEnumValN(Sparc, "sparc", "  Sparc-V9"),
#endif
                  0),
#if defined(ENABLE_X86_JIT)
  cl::init(x86)
#elif defined(ENABLE_SPARC_JIT)
  cl::init(Sparc)
#endif
       );
#endif /* NO_JITS_ENABLED */
}

/// create - Create an return a new JIT compiler if there is one available
/// for the current target.  Otherwise, return null.
///
ExecutionEngine *VM::create(ModuleProvider *MP) {
  TargetMachine* (*TargetMachineAllocator)(const Module &) = 0;

  // Allow a command-line switch to override what *should* be the default target
  // machine for this platform. This allows for debugging a Sparc JIT on X86 --
  // our X86 machines are much faster at recompiling LLVM and linking LLI.
#ifndef NO_JITS_ENABLED

  switch (Arch) {
#ifdef ENABLE_X86_JIT
  case x86:
    TargetMachineAllocator = allocateX86TargetMachine;
    break;
#endif
#ifdef ENABLE_SPARC_JIT
  case Sparc:
    TargetMachineAllocator = allocateSparcTargetMachine;
    break;
#endif
  default:
    assert(0 && "-march flag not supported on this host!");
  }
#else
  return 0;
#endif

  // Allocate a target...
  TargetMachine *Target = TargetMachineAllocator(*MP->getModule());
  assert(Target && "Could not allocate target machine!");

  // Create the virtual machine object...
  return new VM(MP, Target);
}

VM::VM(ModuleProvider *MP, TargetMachine *tm) : ExecutionEngine(MP), TM(*tm),
  PM(MP)
{
  setTargetData(TM.getTargetData());

  // Initialize MCE
  MCE = createEmitter(*this);

  setupPassManager();

  emitGlobals();
}

/// run - Start execution with the specified function and arguments.
///
GenericValue VM::run(Function *F, const std::vector<GenericValue> &ArgValues)
{
  assert (F && "Function *F was null at entry to run()");

  int (*PF)(int, char **, const char **) =
    (int(*)(int, char **, const char **))getPointerToFunction(F);
  assert(PF != 0 && "Pointer to fn's code was null after getPointerToFunction");

  // Call the function.
  int ExitCode = PF(ArgValues[0].IntVal, (char **) GVTOP (ArgValues[1]),
		    (const char **) GVTOP (ArgValues[2]));

  // Run any atexit handlers now!
  runAtExitHandlers();

  GenericValue rv;
  rv.IntVal = ExitCode;
  return rv;
}
<|endoftext|>


<commit_before>#include <microscopes/lda/kernels.hpp>

namespace microscopes {
namespace kernels {
namespace lda_crp {

std::vector<float>
calc_dish_posterior_t(microscopes::lda::state &state, size_t j, size_t t, common::rng_t &rng) {
    std::vector<float> log_p_k(state.dishes_.size());

    auto k_old = state.restaurants_[j][t];
    auto n_jt_val = state.n_jt[j][t];
    for (size_t i = 0; i < state.dishes_.size(); i++) {
        auto k = state.dishes_[i];
        float n_k_val = state.n_k.get(k); // V*beta when k == i == 0
        if (k == k_old) n_k_val -= n_jt_val;
        log_p_k[i] = distributions::fast_log(i == 0 ? state.gamma_ : state.m_k[k]);
        log_p_k[i] += distributions::fast_lgamma(n_k_val);
        log_p_k[i] -= distributions::fast_lgamma(n_k_val + n_jt_val);
    }

    for (auto &kv : state.n_jtv[j][t]) {
        auto w = kv.first; // w is word index
        auto n_jtw = kv.second; // n_jtw is # of times word w appears at table t in doc j.
        if (n_jtw == 0) continue; // if word w isn't at table t, continue. log_pk wouldn't change.

        for (size_t i = 0; i < state.dishes_.size(); i++) {
            float n_kw;
            n_kw = state.n_kv[state.dishes_[i]].get(w); // beta when k == i == 0
            if (state.dishes_[i] == state.restaurants_[j][t]) n_kw -= n_jtw;
            log_p_k[i] += distributions::fast_lgamma(n_kw + n_jtw);
            log_p_k[i] -= distributions::fast_lgamma(n_kw);
        }
    }

    std::vector<float> p_k;
    p_k.reserve(state.dishes_.size());
    float max_value = *std::max_element(log_p_k.begin(), log_p_k.end());
    for (auto log_p_k_value : log_p_k) {
        p_k.push_back(exp(log_p_k_value - max_value));
    }
    lda_util::normalize(p_k);
    return p_k;
}

std::vector<float>
calc_dish_posterior_w(microscopes::lda::state &state, const std::vector<float> &f_k, common::rng_t &rng){
    Eigen::VectorXf p_k(state.dishes_.size());
    for (size_t i = 0; i < state.dishes_.size(); ++i) {
        p_k(i) = state.m_k[state.dishes_[i]] * f_k[state.dishes_[i]];
    }
    p_k(0) = state.gamma_ / state.V;
    p_k /= p_k.sum();
    return std::vector<float>(p_k.data(), p_k.data() + p_k.size());
}

std::vector<float>
calc_f_k(microscopes::lda::state &state, size_t v, common::rng_t &rng) {
    Eigen::VectorXf f_k(state.n_kv.size());

    f_k(0) = (state.n_kv[0].get(v) - state.beta_) / state.n_k.get(0);
    for (size_t k = 1; k < state.n_kv.size(); k++)
    {
        f_k(k) = state.n_kv[k].get(v) / state.n_k.get(k);
    }

    return std::vector<float>(f_k.data(), f_k.data() + f_k.size());
}

std::vector<float>
calc_table_posterior(microscopes::lda::state &state, size_t j, std::vector<float> &f_k, common::rng_t &rng) {
    std::vector<size_t> using_table = state.using_t[j];
    Eigen::VectorXf p_t(using_table.size());

    for (size_t i = 0; i < using_table.size(); i++) {
        auto p = using_table[i];
        p_t(i) = state.n_jt[j][p] * f_k[state.restaurants_[j][p]];
    }
    Eigen::Map<Eigen::VectorXf> eigen_f_k(f_k.data(), f_k.size());
    Eigen::Map<Eigen::Matrix<size_t, Eigen::Dynamic, 1>> eigen_m_k(state.m_k.data(), state.m_k.size());
    float p_x_ji = state.gamma_ / state.V + eigen_f_k.dot(eigen_m_k.cast<float>());
    p_t[0] = p_x_ji * state.alpha_ / (state.gamma_ + state.ntables());
    p_t /= p_t.sum();
    return std::vector<float>(p_t.data(), p_t.data() + p_t.size());
}

void
sampling_t(microscopes::lda::state &state, size_t j, size_t i, common::rng_t &rng) {
    state.remove_table(j, i);
    size_t v = state.get_word(j, i);
    std::vector<float> f_k = calc_f_k(state, v, rng);
    std::vector<float> p_t = calc_table_posterior(state, j, f_k, rng);

    size_t t_new = state.using_t[j][common::util::sample_discrete(p_t, rng)];
    if (t_new == 0)
    {
        auto p_k = calc_dish_posterior_w(state, f_k, rng);
        size_t k_new = state.dishes_[common::util::sample_discrete(p_k, rng)];
        if (k_new == 0) k_new = state.create_dish();
        t_new = state.create_table(j, k_new);
    }
    state.add_table(j, t_new, i);
}

void
sampling_k(microscopes::lda::state &state, size_t j, size_t t, common::rng_t &rng) {
    state.leave_from_dish(j, t);
    auto p_k = calc_dish_posterior_t(state, j, t, rng);
    size_t k_new = state.dishes_[common::util::sample_discrete(p_k, rng)];
    if (k_new == 0) k_new = state.create_dish();
    state.seat_at_dish(j, t, k_new);
}

} // namespace lda_crp

void
lda_crp_gibbs(microscopes::lda::state &state, common::rng_t &rng)
{
    for (size_t j = 0; j < state.nentities(); ++j) {
        for (size_t i = 0; i < state.nterms(j); ++i) {
            lda_crp::sampling_t(state, j, i, rng);
        }
    }
    for (size_t j = 0; j < state.nentities(); ++j) {
        for (auto t : state.using_t[j]) {
            if (t != 0) {
                lda_crp::sampling_k(state, j, t, rng);
            }
        }
    }
}

} // namespace kernels
} // namespace microscopes<commit_msg>Clarify use of f_k<commit_after>#include <microscopes/lda/kernels.hpp>

namespace microscopes {
namespace kernels {
namespace lda_crp {

std::vector<float>
calc_dish_posterior_t(microscopes::lda::state &state, size_t j, size_t t, common::rng_t &rng) {
    std::vector<float> log_p_k(state.dishes_.size());

    auto k_old = state.restaurants_[j][t];
    auto n_jt_val = state.n_jt[j][t];
    for (size_t i = 0; i < state.dishes_.size(); i++) {
        auto k = state.dishes_[i];
        float n_k_val = state.n_k.get(k); // V*beta when k == i == 0
        if (k == k_old) n_k_val -= n_jt_val;
        log_p_k[i] = distributions::fast_log(i == 0 ? state.gamma_ : state.m_k[k]);
        log_p_k[i] += distributions::fast_lgamma(n_k_val);
        log_p_k[i] -= distributions::fast_lgamma(n_k_val + n_jt_val);
    }

    for (auto &kv : state.n_jtv[j][t]) {
        auto w = kv.first; // w is word index
        auto n_jtw = kv.second; // n_jtw is # of times word w appears at table t in doc j.
        if (n_jtw == 0) continue; // if word w isn't at table t, continue. log_pk wouldn't change.

        for (size_t i = 0; i < state.dishes_.size(); i++) {
            float n_kw;
            n_kw = state.n_kv[state.dishes_[i]].get(w); // beta when k == i == 0
            if (state.dishes_[i] == state.restaurants_[j][t]) n_kw -= n_jtw;
            log_p_k[i] += distributions::fast_lgamma(n_kw + n_jtw);
            log_p_k[i] -= distributions::fast_lgamma(n_kw);
        }
    }

    std::vector<float> p_k;
    p_k.reserve(state.dishes_.size());
    float max_value = *std::max_element(log_p_k.begin(), log_p_k.end());
    for (auto log_p_k_value : log_p_k) {
        p_k.push_back(exp(log_p_k_value - max_value));
    }
    lda_util::normalize(p_k);
    return p_k;
}

std::vector<float>
calc_dish_posterior_w(microscopes::lda::state &state, const std::vector<float> &f_k, common::rng_t &rng){
    Eigen::VectorXf p_k(state.dishes_.size());
    for (size_t i = 0; i < state.dishes_.size(); ++i) {
        p_k(i) = state.m_k[state.dishes_[i]] * f_k[state.dishes_[i]];
    }
    p_k(0) = state.gamma_ / state.V;
    p_k /= p_k.sum();
    return std::vector<float>(p_k.data(), p_k.data() + p_k.size());
}

std::vector<float>
calc_f_k(microscopes::lda::state &state, size_t v, common::rng_t &rng) {
    Eigen::VectorXf f_k(state.n_kv.size());

    f_k(0) = 0;
    for (size_t k = 1; k < state.n_kv.size(); k++)
    {
        f_k(k) = state.n_kv[k].get(v) / state.n_k.get(k);
    }

    return std::vector<float>(f_k.data(), f_k.data() + f_k.size());
}

std::vector<float>
calc_table_posterior(microscopes::lda::state &state, size_t j, std::vector<float> &f_k, common::rng_t &rng) {
    std::vector<size_t> using_table = state.using_t[j];
    Eigen::VectorXf p_t(using_table.size());

    for (size_t i = 1; i < using_table.size(); i++) {
        auto p = using_table[i];
        p_t(i) = state.n_jt[j][p] * f_k[state.restaurants_[j][p]];
    }
    Eigen::Map<Eigen::VectorXf> eigen_f_k(f_k.data(), f_k.size());
    Eigen::Map<Eigen::Matrix<size_t, Eigen::Dynamic, 1>> eigen_m_k(state.m_k.data(), state.m_k.size());
    float p_x_ji = state.gamma_ / state.V + eigen_f_k.dot(eigen_m_k.cast<float>());
    p_t(0) = p_x_ji * state.alpha_ / (state.gamma_ + state.ntables());
    p_t /= p_t.sum();
    return std::vector<float>(p_t.data(), p_t.data() + p_t.size());
}

void
sampling_t(microscopes::lda::state &state, size_t j, size_t i, common::rng_t &rng) {
    state.remove_table(j, i);
    size_t v = state.get_word(j, i);
    std::vector<float> f_k = calc_f_k(state, v, rng);
    std::vector<float> p_t = calc_table_posterior(state, j, f_k, rng);

    size_t t_new = state.using_t[j][common::util::sample_discrete(p_t, rng)];
    if (t_new == 0)
    {
        auto p_k = calc_dish_posterior_w(state, f_k, rng);
        size_t k_new = state.dishes_[common::util::sample_discrete(p_k, rng)];
        if (k_new == 0) k_new = state.create_dish();
        t_new = state.create_table(j, k_new);
    }
    state.add_table(j, t_new, i);
}

void
sampling_k(microscopes::lda::state &state, size_t j, size_t t, common::rng_t &rng) {
    state.leave_from_dish(j, t);
    auto p_k = calc_dish_posterior_t(state, j, t, rng);
    size_t k_new = state.dishes_[common::util::sample_discrete(p_k, rng)];
    if (k_new == 0) k_new = state.create_dish();
    state.seat_at_dish(j, t, k_new);
}

} // namespace lda_crp

void
lda_crp_gibbs(microscopes::lda::state &state, common::rng_t &rng)
{
    for (size_t j = 0; j < state.nentities(); ++j) {
        for (size_t i = 0; i < state.nterms(j); ++i) {
            lda_crp::sampling_t(state, j, i, rng);
        }
    }
    for (size_t j = 0; j < state.nentities(); ++j) {
        for (auto t : state.using_t[j]) {
            if (t != 0) {
                lda_crp::sampling_k(state, j, t, rng);
            }
        }
    }
}

} // namespace kernels
} // namespace microscopes<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* 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 Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_TOPOLOGY_POINTSETTOPOLOGY_INL
#define SOFA_COMPONENT_TOPOLOGY_POINTSETTOPOLOGY_INL

#include <sofa/component/topology/PointSetTopology.h>
#include <sofa/simulation/common/TopologyChangeVisitor.h>
#include <sofa/simulation/common/StateChangeVisitor.h>
#include <sofa/simulation/tree/GNode.h>
#include <sofa/helper/io/MeshTopologyLoader.h>
#include <sofa/defaulttype/VecTypes.h>

namespace sofa
{

namespace component
{

namespace topology
{

using namespace sofa::defaulttype;
using namespace sofa::core::componentmodel::behavior;

/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////PointSetTopology/////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

template<class DataTypes>
PointSetTopology<DataTypes>::PointSetTopology(MechanicalObject<DataTypes> *obj)
    : f_m_topologyContainer(new DataPtr< PointSetTopologyContainer >(new PointSetTopologyContainer(), "Point Container"))
    , object(obj)
    , revisionCounter(0)
{
    // TODO: move this to init if possible
    m_topologyContainer = f_m_topologyContainer->beginEdit();
    this->m_topologyContainer->setTopology(this);
    m_topologyModifier=(new PointSetTopologyModifier<DataTypes>(this));
    m_topologyAlgorithms=(new PointSetTopologyAlgorithms<DataTypes>(this));
    m_geometryAlgorithms=(new PointSetGeometryAlgorithms<DataTypes>(this));

    this->addField(this->f_m_topologyContainer, "pointcontainer");
}

template<class DataTypes>
void PointSetTopology<DataTypes>::init()
{
    f_m_topologyContainer->beginEdit();
}

template<class DataTypes>
void PointSetTopology<DataTypes>::propagateTopologicalChanges()
{
    sofa::simulation::TopologyChangeVisitor a;
    this->getContext()->executeVisitor(&a);

    // remove the changes we just propagated, so that we don't send then again next time
    this->resetTopologyChangeList();

    ++revisionCounter;
}

template<class DataTypes>
void PointSetTopology<DataTypes>::propagateStateChanges()
{
    sofa::simulation::StateChangeVisitor a;
    this->getContext()->executeVisitor(&a);

    // remove the changes we just propagated, so that we don't send then again next time
    this->resetStateChangeList();
}

template<class DataTypes>
bool PointSetTopology<DataTypes>::load(const char *filename)
{
    return getPointSetTopologyModifier()->load(filename);
}

template<class DataTypes>
void PointSetTopology<DataTypes>::applyScale(const double scale)
{
    return getPointSetTopologyModifier()->applyScale(scale);
}

template<class DataTypes>
void PointSetTopology<DataTypes>::applyTranslation(const double dx,const double dy,const double dz)
{
    return getPointSetTopologyModifier()->applyTranslation(dx,dy,dz);
}

/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////PointSetGeometryAlgorithms///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

template <class DataTypes>
typename DataTypes::Coord PointSetGeometryAlgorithms<DataTypes>::getPointSetCenter() const
{
    typename DataTypes::Coord center;
    // get restPosition
    PointSetTopology<DataTypes> *topology = getPointSetTopology();
    typename DataTypes::VecCoord& p = *(topology->getDOF()->getX0());

    const unsigned int numVertices = topology->getDOFNumber();
    for(unsigned int i=0; i<numVertices; ++i)
    {
        center += p[i];
    }

    center /= numVertices;
    return center;
}

template<class DataTypes>
void  PointSetGeometryAlgorithms<DataTypes>::getEnclosingSphere(typename DataTypes::Coord &center,
        typename DataTypes::Real &radius) const
{
    // get restPosition
    PointSetTopology<DataTypes> *topology = getPointSetTopology();
    typename DataTypes::VecCoord& p = *(topology->getDOF()->getX0());

    const unsigned int numVertices = topology->getDOFNumber();
    for(unsigned int i=0; i<numVertices; ++i)
    {
        center += p[i];
    }
    center /= numVertices;
    radius = (Real) 0;

    for(unsigned int i=0; i<numVertices; ++i)
    {
        const Coord dp = center-p[i];
        const Real val = dot(dp,dp);
        if(val > radius)
            radius = val;
    }
    radius = (Real)sqrt((double) radius);
}

template<class DataTypes>
void  PointSetGeometryAlgorithms<DataTypes>::getAABB(typename DataTypes::Real bb[6] ) const
{
    // get restPosition
    PointSetTopology<DataTypes> *parent = getPointSetTopology();
    typename DataTypes::VecCoord& p = *parent->getDOF()->getX0();

    bb[0] = (Real) p[0][0];
    bb[1] = (Real) p[0][1];
    bb[2] = (Real) p[0][2];
    bb[3] = (Real) p[0][0];
    bb[4] = (Real) p[0][1];
    bb[5] = (Real) p[0][2];

    for(unsigned int i=1; i<p.size(); ++i)
    {
        // min
        if(bb[0] > (Real) p[i][0]) bb[0] = (Real) p[i][0];	// x
        if(bb[1] > (Real) p[i][1]) bb[1] = (Real) p[i][1];	// y
        if(bb[2] > (Real) p[i][2]) bb[2] = (Real) p[i][2];	// z

        // max
        if(bb[3] < (Real) p[i][0]) bb[3] = (Real) p[i][0];	// x
        if(bb[4] < (Real) p[i][1]) bb[4] = (Real) p[i][1];	// y
        if(bb[5] < (Real) p[i][2]) bb[5] = (Real) p[i][2];	// z
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////PointSetTopologyModifier/////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

template<class DataTypes>
class PointSetTopologyLoader : public helper::io::MeshTopologyLoader
{
public:
    typedef typename DataTypes::VecCoord VecCoord;
    typedef typename DataTypes::Coord Coord;
    typedef typename DataTypes::Real Real;

    VecCoord pointArray;

    PointSetTopologyLoader() {}

    virtual void addPoint(double px, double py, double pz)
    {
        //BUGFIX(Jeremie A.): The following does not work for 1D/2D datatypes
        //pointArray.push_back(Coord((Real)px,(Real)py,(Real)pz));
        Coord c;
        DataTypes::set(c,px,py,pz);
        pointArray.push_back(c);
    }
};

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::loadPointSet(PointSetTopologyLoader<DataTypes> *loader)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    if ((loader->pointArray.size() > 0) && (topology->getDOFNumber() <= 1))
    {
        /// resize the DOF stored in the mechanical object
        topology->getDOF()->resize(loader->pointArray.size());

        /// store position and vertex index in containers
        for (unsigned int index=0; index<loader->pointArray.size(); ++index)
        {
            (*topology->getDOF()->getX())[index] = loader->pointArray[index];
        }
    }
}

template<class DataTypes>
bool PointSetTopologyModifier<DataTypes>::load(const char *filename)
{
    PointSetTopologyLoader<DataTypes> loader;
    if (!loader.load(filename))
        return false;
    else
    {
        loadPointSet(&loader);
        return true;
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::applyTranslation (const double dx,const double dy,const double dz)
{
    getPointSetTopology()->getDOF()->applyTranslation(dx,dy,dz);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::applyScale (const double s)
{
    getPointSetTopology()->getDOF()->applyScale(s);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::swapPoints(const int i1,const int i2)
{
    getPointSetTopology()->getDOF()->swapValues( i1, i2 );

    PointsIndicesSwap *e = new PointsIndicesSwap( i1, i2 ); // local or global indices ? (example of edges)
    this->addTopologyChange(e);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsProcess(const unsigned int /*nPoints*/, const bool /*addDOF*/)
{}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsProcess(const unsigned int /*nPoints*/,
        const sofa::helper::vector< sofa::helper::vector< unsigned int > >& /*ancestors*/,
        const sofa::helper::vector< sofa::helper::vector< double > >& /*baryCoefs*/,
        const bool /*addDOF*/)
{}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addNewPoint(unsigned int i, const sofa::helper::vector< double >& x)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    unsigned int prevSizeMechObj = i; //container->getNumberOfVertices();//topology->getDOFNumber();

    // resizing the state vectors
    topology->getDOF()->resize( prevSizeMechObj + 1 );

    topology->getDOF()->computeNewPoint(prevSizeMechObj, x);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsWarning(const unsigned int nPoints, const bool addDOF)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    if(addDOF)
    {
        PointsAdded *e2 = new PointsAdded(nPoints);
        addStateChange(e2);
        topology->propagateStateChanges();
    }

    // Warning that vertices just got created
    PointsAdded *e = new PointsAdded(nPoints);
    this->addTopologyChange(e);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsWarning(const unsigned int nPoints,
        const sofa::helper::vector< sofa::helper::vector< unsigned int > > &ancestors,
        const sofa::helper::vector< sofa::helper::vector< double       > >& coefs,
        const bool addDOF)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    if(addDOF)
    {
        PointsAdded *e2 = new PointsAdded(nPoints, ancestors, coefs);
        addStateChange(e2);
        topology->propagateStateChanges();
    }

    // Warning that vertices just got created
    PointsAdded *e = new PointsAdded(nPoints, ancestors, coefs);
    this->addTopologyChange(e);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::removePointsWarning(sofa::helper::vector<unsigned int> &indices,
        const bool removeDOF)
{
    // TODO: clarify why sorting is necessary
    std::sort( indices.begin(), indices.end(), std::greater<unsigned int>() );

    // Warning that these vertices will be deleted
    PointsRemoved *e = new PointsRemoved(indices);
    this->addTopologyChange(e);

    if(removeDOF)
    {
        PointsRemoved *e2=new PointsRemoved(indices);
        addStateChange(e2);
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::removePointsProcess(const sofa::helper::vector<unsigned int> & /*indices*/,
        const bool removeDOF)
{
    if(removeDOF)
    {
        getPointSetTopology()->propagateStateChanges();
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::renumberPointsWarning( const sofa::helper::vector<unsigned int> &index,
        const sofa::helper::vector<unsigned int> &inv_index,
        const bool renumberDOF)
{
    // Warning that these vertices will be deleted
    PointsRenumbering *e = new PointsRenumbering(index, inv_index);
    this->addTopologyChange(e);

    if(renumberDOF)
    {
        PointsRenumbering *e2 = new PointsRenumbering(index, inv_index);
        addStateChange(e2);
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::renumberPointsProcess( const sofa::helper::vector<unsigned int> &/*index*/,
        const sofa::helper::vector<unsigned int> &/*inv_index*/,
        const bool renumberDOF)
{
    if(renumberDOF)
    {
        getPointSetTopology()->propagateStateChanges();
    }
}

} // namespace topology

} // namespace component

} // namespace sofa

#endif
<commit_msg>r2759/sofa-dev : BUGFIX: When calling create/destroy callbacks from topological *Data classes, the reference now always point to the right cell within the vector, instead of a temporary instance that is then push_back. This way components can use methods that only rely on the given index (which some already did), and we have better performances when many elements are created as only one resize is done.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
*                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* 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 Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_TOPOLOGY_POINTSETTOPOLOGY_INL
#define SOFA_COMPONENT_TOPOLOGY_POINTSETTOPOLOGY_INL

#include <sofa/component/topology/PointSetTopology.h>
#include <sofa/simulation/common/TopologyChangeVisitor.h>
#include <sofa/simulation/common/StateChangeVisitor.h>
#include <sofa/simulation/tree/GNode.h>
#include <sofa/helper/io/MeshTopologyLoader.h>
#include <sofa/defaulttype/VecTypes.h>

namespace sofa
{

namespace component
{

namespace topology
{

using namespace sofa::defaulttype;
using namespace sofa::core::componentmodel::behavior;

/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////PointSetTopology/////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

template<class DataTypes>
PointSetTopology<DataTypes>::PointSetTopology(MechanicalObject<DataTypes> *obj)
    : object(obj),
      f_m_topologyContainer(new DataPtr< PointSetTopologyContainer >(new PointSetTopologyContainer(), "Point Container")),
      revisionCounter(0)
{
    // TODO: move this to init if possible
    m_topologyContainer = f_m_topologyContainer->beginEdit();
    this->m_topologyContainer->setTopology(this);
    m_topologyModifier=(new PointSetTopologyModifier<DataTypes>(this));
    m_topologyAlgorithms=(new PointSetTopologyAlgorithms<DataTypes>(this));
    m_geometryAlgorithms=(new PointSetGeometryAlgorithms<DataTypes>(this));

    this->addField(this->f_m_topologyContainer, "pointcontainer");
}

template<class DataTypes>
void PointSetTopology<DataTypes>::init()
{
    f_m_topologyContainer->beginEdit();
}

template<class DataTypes>
void PointSetTopology<DataTypes>::propagateTopologicalChanges()
{
    sofa::simulation::TopologyChangeVisitor a;
    this->getContext()->executeVisitor(&a);

    // remove the changes we just propagated, so that we don't send then again next time
    this->resetTopologyChangeList();

    ++revisionCounter;
}

template<class DataTypes>
void PointSetTopology<DataTypes>::propagateStateChanges()
{
    sofa::simulation::StateChangeVisitor a;
    this->getContext()->executeVisitor(&a);

    // remove the changes we just propagated, so that we don't send then again next time
    this->resetStateChangeList();
}

template<class DataTypes>
bool PointSetTopology<DataTypes>::load(const char *filename)
{
    return getPointSetTopologyModifier()->load(filename);
}

template<class DataTypes>
void PointSetTopology<DataTypes>::applyScale(const double scale)
{
    return getPointSetTopologyModifier()->applyScale(scale);
}

template<class DataTypes>
void PointSetTopology<DataTypes>::applyTranslation(const double dx,const double dy,const double dz)
{
    return getPointSetTopologyModifier()->applyTranslation(dx,dy,dz);
}

/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////PointSetGeometryAlgorithms///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

template <class DataTypes>
typename DataTypes::Coord PointSetGeometryAlgorithms<DataTypes>::getPointSetCenter() const
{
    typename DataTypes::Coord center;
    // get restPosition
    PointSetTopology<DataTypes> *topology = getPointSetTopology();
    typename DataTypes::VecCoord& p = *(topology->getDOF()->getX0());

    const unsigned int numVertices = topology->getDOFNumber();
    for(unsigned int i=0; i<numVertices; ++i)
    {
        center += p[i];
    }

    center /= numVertices;
    return center;
}

template<class DataTypes>
void  PointSetGeometryAlgorithms<DataTypes>::getEnclosingSphere(typename DataTypes::Coord &center,
        typename DataTypes::Real &radius) const
{
    // get restPosition
    PointSetTopology<DataTypes> *topology = getPointSetTopology();
    typename DataTypes::VecCoord& p = *(topology->getDOF()->getX0());

    const unsigned int numVertices = topology->getDOFNumber();
    for(unsigned int i=0; i<numVertices; ++i)
    {
        center += p[i];
    }
    center /= numVertices;
    radius = (Real) 0;

    for(unsigned int i=0; i<numVertices; ++i)
    {
        const Coord dp = center-p[i];
        const Real val = dot(dp,dp);
        if(val > radius)
            radius = val;
    }
    radius = (Real)sqrt((double) radius);
}

template<class DataTypes>
void  PointSetGeometryAlgorithms<DataTypes>::getAABB(typename DataTypes::Real bb[6] ) const
{
    // get restPosition
    PointSetTopology<DataTypes> *parent = getPointSetTopology();
    typename DataTypes::VecCoord& p = *parent->getDOF()->getX0();

    bb[0] = (Real) p[0][0];
    bb[1] = (Real) p[0][1];
    bb[2] = (Real) p[0][2];
    bb[3] = (Real) p[0][0];
    bb[4] = (Real) p[0][1];
    bb[5] = (Real) p[0][2];

    for(unsigned int i=1; i<p.size(); ++i)
    {
        // min
        if(bb[0] > (Real) p[i][0]) bb[0] = (Real) p[i][0];	// x
        if(bb[1] > (Real) p[i][1]) bb[1] = (Real) p[i][1];	// y
        if(bb[2] > (Real) p[i][2]) bb[2] = (Real) p[i][2];	// z

        // max
        if(bb[3] < (Real) p[i][0]) bb[3] = (Real) p[i][0];	// x
        if(bb[4] < (Real) p[i][1]) bb[4] = (Real) p[i][1];	// y
        if(bb[5] < (Real) p[i][2]) bb[5] = (Real) p[i][2];	// z
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////PointSetTopologyModifier/////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

template<class DataTypes>
class PointSetTopologyLoader : public helper::io::MeshTopologyLoader
{
public:
    typedef typename DataTypes::VecCoord VecCoord;
    typedef typename DataTypes::Coord Coord;
    typedef typename DataTypes::Real Real;

    VecCoord pointArray;

    PointSetTopologyLoader() {}

    virtual void addPoint(double px, double py, double pz)
    {
        //BUGFIX(Jeremie A.): The following does not work for 1D/2D datatypes
        //pointArray.push_back(Coord((Real)px,(Real)py,(Real)pz));
        Coord c;
        DataTypes::set(c,px,py,pz);
        pointArray.push_back(c);
    }
};

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::loadPointSet(PointSetTopologyLoader<DataTypes> *loader)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    if ((loader->pointArray.size() > 0) && (topology->getDOFNumber() <= 1))
    {
        /// resize the DOF stored in the mechanical object
        topology->getDOF()->resize(loader->pointArray.size());

        /// store position and vertex index in containers
        for (unsigned int index=0; index<loader->pointArray.size(); ++index)
        {
            (*topology->getDOF()->getX())[index] = loader->pointArray[index];
        }
    }
}

template<class DataTypes>
bool PointSetTopologyModifier<DataTypes>::load(const char *filename)
{
    PointSetTopologyLoader<DataTypes> loader;
    if (!loader.load(filename))
        return false;
    else
    {
        loadPointSet(&loader);
        return true;
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::applyTranslation (const double dx,const double dy,const double dz)
{
    getPointSetTopology()->getDOF()->applyTranslation(dx,dy,dz);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::applyScale (const double s)
{
    getPointSetTopology()->getDOF()->applyScale(s);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::swapPoints(const int i1,const int i2)
{
    getPointSetTopology()->getDOF()->swapValues( i1, i2 );

    PointsIndicesSwap *e = new PointsIndicesSwap( i1, i2 ); // local or global indices ? (example of edges)
    this->addTopologyChange(e);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsProcess(const unsigned int /*nPoints*/, const bool /*addDOF*/)
{}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsProcess(const unsigned int /*nPoints*/,
        const sofa::helper::vector< sofa::helper::vector< unsigned int > >& /*ancestors*/,
        const sofa::helper::vector< sofa::helper::vector< double > >& /*baryCoefs*/,
        const bool /*addDOF*/)
{}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addNewPoint(unsigned int i, const sofa::helper::vector< double >& x)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    unsigned int prevSizeMechObj = i; //container->getNumberOfVertices();//topology->getDOFNumber();

    // resizing the state vectors
    topology->getDOF()->resize( prevSizeMechObj + 1 );

    topology->getDOF()->computeNewPoint(prevSizeMechObj, x);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsWarning(const unsigned int nPoints, const bool addDOF)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    if(addDOF)
    {
        PointsAdded *e2 = new PointsAdded(nPoints);
        addStateChange(e2);
        topology->propagateStateChanges();
    }

    // Warning that vertices just got created
    PointsAdded *e = new PointsAdded(nPoints);
    this->addTopologyChange(e);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::addPointsWarning(const unsigned int nPoints,
        const sofa::helper::vector< sofa::helper::vector< unsigned int > > &ancestors,
        const sofa::helper::vector< sofa::helper::vector< double       > >& coefs,
        const bool addDOF)
{
    PointSetTopology<DataTypes> *topology = getPointSetTopology();

    if(addDOF)
    {
        PointsAdded *e2 = new PointsAdded(nPoints, ancestors, coefs);
        addStateChange(e2);
        topology->propagateStateChanges();
    }

    // Warning that vertices just got created
    PointsAdded *e = new PointsAdded(nPoints, ancestors, coefs);
    this->addTopologyChange(e);
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::removePointsWarning(sofa::helper::vector<unsigned int> &indices,
        const bool removeDOF)
{
    // TODO: clarify why sorting is necessary
    std::sort( indices.begin(), indices.end(), std::greater<unsigned int>() );

    // Warning that these vertices will be deleted
    PointsRemoved *e = new PointsRemoved(indices);
    this->addTopologyChange(e);

    if(removeDOF)
    {
        PointsRemoved *e2=new PointsRemoved(indices);
        addStateChange(e2);
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::removePointsProcess(const sofa::helper::vector<unsigned int> & /*indices*/,
        const bool removeDOF)
{
    if(removeDOF)
    {
        getPointSetTopology()->propagateStateChanges();
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::renumberPointsWarning( const sofa::helper::vector<unsigned int> &index,
        const sofa::helper::vector<unsigned int> &inv_index,
        const bool renumberDOF)
{
    // Warning that these vertices will be deleted
    PointsRenumbering *e = new PointsRenumbering(index, inv_index);
    this->addTopologyChange(e);

    if(renumberDOF)
    {
        PointsRenumbering *e2 = new PointsRenumbering(index, inv_index);
        addStateChange(e2);
    }
}

template<class DataTypes>
void PointSetTopologyModifier<DataTypes>::renumberPointsProcess( const sofa::helper::vector<unsigned int> &/*index*/,
        const sofa::helper::vector<unsigned int> &/*inv_index*/,
        const bool renumberDOF)
{
    if(renumberDOF)
    {
        getPointSetTopology()->propagateStateChanges();
    }
}

} // namespace topology

} // namespace component

} // namespace sofa

#endif
<|endoftext|>


<commit_before>/*!
 * \author ddubois
 * \date 30-Aug-18.
 */

#include <windows.h>

#include "dx12_render_engine.hpp"
#include "dx12_opaque_types.hpp"
#include <d3d12sdklayers.h>
#include "../../util/logger.hpp"

namespace nova {
    dx12_render_engine::dx12_render_engine(const settings &settings) : render_engine(settings) {
        create_device();
        create_rtv_command_queue();
        create_fence_wait_event();

        std::vector<command_list> direct_buffers;
        direct_buffers.reserve(32);    // Not sure how many we need, this should be enough
        buffer_pool.emplace(D3D12_COMMAND_LIST_TYPE_DIRECT, direct_buffers);

        std::vector<command_list> copy_buffers;
        copy_buffers.reserve(32);
        buffer_pool.emplace(D3D12_COMMAND_LIST_TYPE_COPY, copy_buffers);

        std::vector<command_list> compute_buffers;
        compute_buffers.reserve(32);
        buffer_pool.emplace(D3D12_COMMAND_LIST_TYPE_COMPUTE, compute_buffers);
    }

    void dx12_render_engine::open_window(uint32_t width, uint32_t height) {
        window = std::make_unique<win32_window>(width, height);
        create_swapchain();
        create_render_target_descriptor_heap();
    }

    const std::string dx12_render_engine::get_engine_name() {
        return "DirectX 12";
    }

    void dx12_render_engine::create_device() {
//#ifndef NDEBUG
        ComPtr<ID3D12Debug> debug_controller;
        D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller));
        debug_controller->EnableDebugLayer();
//#endif

        NOVA_LOG(TRACE) << "Creating DX12 device";

        HRESULT hr;

        hr = CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG, IID_PPV_ARGS(&dxgi_factory));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create DXGI Factory";
            throw render_engine_initialization_exception("Could not create DXGI Factory");
        }
        NOVA_LOG(TRACE) << "Device created";

        ComPtr<IDXGIAdapter1> adapter;

        uint32_t adapter_index = 0;
        bool adapter_found = false;

        while(dxgi_factory->EnumAdapters1(adapter_index, &adapter) != DXGI_ERROR_NOT_FOUND) {
            DXGI_ADAPTER_DESC1 desc;
            adapter->GetDesc1(&desc);

            if(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
                // Ignore software devices
                adapter_index++;
                continue;
            }

            // Direct3D 12 is feature level 11.
            //
            // cool
            hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);
            if(SUCCEEDED(hr)) {
                adapter_found = true;
                break;
            }

            adapter_index++;
        }

        if(!adapter_found) {
            NOVA_LOG(FATAL) << "Could not find a GPU that supports DX12";
            throw render_engine_initialization_exception("Could not find a GPU that supports DX12");
        }

        NOVA_LOG(TRACE) << "Adapter found";

        hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create Dx12 device";
            throw render_engine_initialization_exception("Could not create Dx12 device");
        }
    }

    void dx12_render_engine::create_rtv_command_queue() {
        D3D12_COMMAND_QUEUE_DESC rtv_queue_desc = {};

        HRESULT hr = device->CreateCommandQueue(&rtv_queue_desc, IID_PPV_ARGS(&direct_command_queue));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create main command queue";
            throw render_engine_initialization_exception("Could not create main command queue");
        }
    }

    void dx12_render_engine::create_swapchain() {
        if(!window) {
            NOVA_LOG(FATAL) << "Cannot initialize the swapchain before the window!";
            throw render_engine_initialization_exception("Cannot initialize the swapchain before the window");
        }

        const auto& window_size = window->get_window_size();

        DXGI_SAMPLE_DESC sample_desc = {};
        sample_desc.Count = 1;

        DXGI_SWAP_CHAIN_DESC1 swapchain_description {};
        swapchain_description.Width = window_size.width;
        swapchain_description.Height = window_size.height;
        swapchain_description.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

        swapchain_description.SampleDesc = sample_desc;
        swapchain_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapchain_description.BufferCount = FRAME_BUFFER_COUNT;

        swapchain_description.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;

        ComPtr<IDXGISwapChain1> swapchain_uncast;
        // No target window specified in DXGI_SWAP_CHAIN_DESC, and no window associated with owning factory. [ MISCELLANEOUS ERROR #6: ]
        HRESULT hr = dxgi_factory->CreateSwapChainForHwnd(direct_command_queue.Get(), window->get_window_handle(), &swapchain_description, nullptr, nullptr, &swapchain_uncast);
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create swapchain";
            if(hr == DXGI_ERROR_INVALID_CALL) {
                NOVA_LOG(INFO) << "Invalid call - one or more of the parameters was wrong";
            } else if(hr == DXGI_STATUS_OCCLUDED) {
                NOVA_LOG(INFO) << "Fullscreen is unavaible";
            } else if(hr == E_OUTOFMEMORY) {
                NOVA_LOG(INFO) << "Out of memory. Soz bro :/";
            }

            throw render_engine_initialization_exception("Could not create swapchain");
        }

        swapchain_uncast->QueryInterface(IID_PPV_ARGS(&swapchain));
    }

    void dx12_render_engine::create_render_target_descriptor_heap() {
        D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_descriptor = {};
        rtv_heap_descriptor.NumDescriptors = FRAME_BUFFER_COUNT;
        rtv_heap_descriptor.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;

        // The heap isn't visible to shaders because shaders don't need to read the swapchain... but we still need a
        // descriptor heap
        rtv_heap_descriptor.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        HRESULT hr = device->CreateDescriptorHeap(&rtv_heap_descriptor, IID_PPV_ARGS(&rtv_descriptor_heap));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create descriptor heap for the RTV";
            throw render_engine_initialization_exception("Could not create descriptor head for the RTV");
        }

        rtv_descriptor_size = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

        CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(rtv_descriptor_heap->GetCPUDescriptorHandleForHeapStart());

        for(uint32_t i = 0; i < FRAME_BUFFER_COUNT; i++) {
            hr = swapchain->GetBuffer(i, IID_PPV_ARGS(&rendertargets[i]));
            if(FAILED(hr)) {
                NOVA_LOG(FATAL) << "Could not create RTV for swapchain image " << i;
                throw render_engine_initialization_exception("Could not create RTV for swapchain");
            }

            // Create the Render Target View, which binds the swapchain buffer to the RTV handle
            device->CreateRenderTargetView(rendertargets[i].Get(), nullptr, rtv_handle);

            // Increment the RTV handle
            rtv_handle.Offset(1, rtv_descriptor_size);
        }
    }

    std::shared_ptr<iwindow> dx12_render_engine::get_window() const {
        return window;
    }

    void dx12_render_engine::render_frame() {
        gfx_command_list present_commands = get_graphics_command_list();

        // Wait for the previous frame at our index to finish
        frame_index = swapchain->GetCurrentBackBufferIndex();
        if(present_commands.submission_fence->GetCompletedValue() < present_commands.fence_value) {
            present_commands.submission_fence->SetEventOnCompletion(present_commands.fence_value, full_frame_fence_event);
            WaitForSingleObject(full_frame_fence_event, INFINITE);
        }
        // There is enough space in a 32-bit integer to run Nova at 60 fps for almost three years. Running Nova
        // continuously for more than one year is not supported
        present_commands.fence_value++;

        HRESULT hr = present_commands.allocator->Reset();
        if(FAILED(hr)) {
            NOVA_LOG(WARN) << "Could not reset command list allocator, memory usage will likely increase dramatically";
        }

        present_commands.list->Reset(present_commands.allocator.Get(), nullptr);

        CD3DX12_RESOURCE_BARRIER to_render_target = CD3DX12_RESOURCE_BARRIER::Transition(rendertargets[frame_index].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
        present_commands.list->ResourceBarrier(1, &to_render_target);

        CD3DX12_CPU_DESCRIPTOR_HANDLE current_framebuffer_rtv(rtv_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), frame_index, rtv_descriptor_size);
        present_commands.list->OMSetRenderTargets(1, &current_framebuffer_rtv, false, nullptr);

        glm::vec4 clear_color(0, 0.2f, 0.4f, 1.0f);
        present_commands.list->ClearRenderTargetView(current_framebuffer_rtv, &clear_color.x, 0, nullptr);

        CD3DX12_RESOURCE_BARRIER to_presentable = CD3DX12_RESOURCE_BARRIER::Transition(rendertargets[frame_index].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
        present_commands.list->ResourceBarrier(1, &to_presentable);

        present_commands.list->Close();

        ID3D12CommandList* commands[] = {present_commands.list.Get()};
        direct_command_queue->ExecuteCommandLists(1, commands);
        direct_command_queue->Signal(present_commands.submission_fence.Get(), present_commands.fence_value);

        swapchain->Present(0, 0);

        release_command_list(present_commands);

    }

    command_list dx12_render_engine::allocate_command_list(D3D12_COMMAND_LIST_TYPE command_list_type) {
        ComPtr<ID3D12CommandAllocator> allocator;
        HRESULT hr = device->CreateCommandAllocator(command_list_type, IID_PPV_ARGS(&allocator));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create command buffer";
            throw std::runtime_error("Could not create command buffer");
        }

        ComPtr<ID3D12CommandList> list;
        hr = device->CreateCommandList(0, command_list_type, allocator.Get(), nullptr, IID_PPV_ARGS(&list));
        if(FAILED(hr)) {
            NOVA_LOG(ERROR) << "Could not create a command list of type " << (uint32_t)command_list_type;
            throw std::runtime_error("Could not create command list");
        }

        ComPtr<ID3D12Fence> fence;
        device->CreateFence(1, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));

        command_list cmd_list = {};
        cmd_list.list = list;
        cmd_list.allocator = allocator;
        cmd_list.submission_fence = fence;

        return cmd_list;
    }

    gfx_command_list dx12_render_engine::get_graphics_command_list() {
        command_list new_list = {};
        ComPtr<ID3D12GraphicsCommandList> graphics_list;
        auto& buffers = buffer_pool.at(D3D12_COMMAND_LIST_TYPE_DIRECT);
        if(buffers.empty()) {
            new_list = allocate_command_list(D3D12_COMMAND_LIST_TYPE_DIRECT);

        } else {
            new_list = buffers.back();
            buffers.pop_back();
        }
        new_list.list->QueryInterface(IID_PPV_ARGS(&graphics_list));

        gfx_command_list gfx_list = {};
        gfx_list.list = graphics_list;
        gfx_list.allocator = new_list.allocator;
        gfx_list.submission_fence = new_list.submission_fence;

        return gfx_list;
    }

    void dx12_render_engine::release_command_list(gfx_command_list list) {

    }

    void dx12_render_engine::create_fence_wait_event() {
        full_frame_fence_event = CreateEvent(nullptr, false, false, nullptr);
    }
}
<commit_msg>DX12 draws blue<commit_after>/*!
 * \author ddubois
 * \date 30-Aug-18.
 */

#include <windows.h>

#include "dx12_render_engine.hpp"
#include "dx12_opaque_types.hpp"
#include <d3d12sdklayers.h>
#include "../../util/logger.hpp"

namespace nova {
    dx12_render_engine::dx12_render_engine(const settings &settings) : render_engine(settings) {
        create_device();
        create_rtv_command_queue();
        create_fence_wait_event();

        std::vector<command_list> direct_buffers;
        direct_buffers.reserve(32);    // Not sure how many we need, this should be enough
        buffer_pool.emplace(D3D12_COMMAND_LIST_TYPE_DIRECT, direct_buffers);

        std::vector<command_list> copy_buffers;
        copy_buffers.reserve(32);
        buffer_pool.emplace(D3D12_COMMAND_LIST_TYPE_COPY, copy_buffers);

        std::vector<command_list> compute_buffers;
        compute_buffers.reserve(32);
        buffer_pool.emplace(D3D12_COMMAND_LIST_TYPE_COMPUTE, compute_buffers);
    }

    void dx12_render_engine::open_window(uint32_t width, uint32_t height) {
        window = std::make_unique<win32_window>(width, height);
        create_swapchain();
        create_render_target_descriptor_heap();
    }

    const std::string dx12_render_engine::get_engine_name() {
        return "DirectX 12";
    }

    void dx12_render_engine::create_device() {
//#ifndef NDEBUG
        ComPtr<ID3D12Debug> debug_controller;
        D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller));
        debug_controller->EnableDebugLayer();
//#endif

        NOVA_LOG(TRACE) << "Creating DX12 device";

        HRESULT hr;

        hr = CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG, IID_PPV_ARGS(&dxgi_factory));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create DXGI Factory";
            throw render_engine_initialization_exception("Could not create DXGI Factory");
        }
        NOVA_LOG(TRACE) << "Device created";

        ComPtr<IDXGIAdapter1> adapter;

        uint32_t adapter_index = 0;
        bool adapter_found = false;

        while(dxgi_factory->EnumAdapters1(adapter_index, &adapter) != DXGI_ERROR_NOT_FOUND) {
            DXGI_ADAPTER_DESC1 desc;
            adapter->GetDesc1(&desc);

            if(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
                // Ignore software devices
                adapter_index++;
                continue;
            }

            // Direct3D 12 is feature level 11.
            //
            // cool
            hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);
            if(SUCCEEDED(hr)) {
                adapter_found = true;
                break;
            }

            adapter_index++;
        }

        if(!adapter_found) {
            NOVA_LOG(FATAL) << "Could not find a GPU that supports DX12";
            throw render_engine_initialization_exception("Could not find a GPU that supports DX12");
        }

        NOVA_LOG(TRACE) << "Adapter found";

        hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create Dx12 device";
            throw render_engine_initialization_exception("Could not create Dx12 device");
        }
    }

    void dx12_render_engine::create_rtv_command_queue() {
        D3D12_COMMAND_QUEUE_DESC rtv_queue_desc = {};

        HRESULT hr = device->CreateCommandQueue(&rtv_queue_desc, IID_PPV_ARGS(&direct_command_queue));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create main command queue";
            throw render_engine_initialization_exception("Could not create main command queue");
        }
    }

    void dx12_render_engine::create_swapchain() {
        if(!window) {
            NOVA_LOG(FATAL) << "Cannot initialize the swapchain before the window!";
            throw render_engine_initialization_exception("Cannot initialize the swapchain before the window");
        }

        const auto& window_size = window->get_window_size();

        DXGI_SAMPLE_DESC sample_desc = {};
        sample_desc.Count = 1;

        DXGI_SWAP_CHAIN_DESC1 swapchain_description {};
        swapchain_description.Width = window_size.width;
        swapchain_description.Height = window_size.height;
        swapchain_description.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

        swapchain_description.SampleDesc = sample_desc;
        swapchain_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        swapchain_description.BufferCount = FRAME_BUFFER_COUNT;

        swapchain_description.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;

        ComPtr<IDXGISwapChain1> swapchain_uncast;
        // No target window specified in DXGI_SWAP_CHAIN_DESC, and no window associated with owning factory. [ MISCELLANEOUS ERROR #6: ]
        HRESULT hr = dxgi_factory->CreateSwapChainForHwnd(direct_command_queue.Get(), window->get_window_handle(), &swapchain_description, nullptr, nullptr, &swapchain_uncast);
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create swapchain";
            if(hr == DXGI_ERROR_INVALID_CALL) {
                NOVA_LOG(INFO) << "Invalid call - one or more of the parameters was wrong";
            } else if(hr == DXGI_STATUS_OCCLUDED) {
                NOVA_LOG(INFO) << "Fullscreen is unavaible";
            } else if(hr == E_OUTOFMEMORY) {
                NOVA_LOG(INFO) << "Out of memory. Soz bro :/";
            }

            throw render_engine_initialization_exception("Could not create swapchain");
        }

        swapchain_uncast->QueryInterface(IID_PPV_ARGS(&swapchain));
    }

    void dx12_render_engine::create_render_target_descriptor_heap() {
        D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_descriptor = {};
        rtv_heap_descriptor.NumDescriptors = FRAME_BUFFER_COUNT;
        rtv_heap_descriptor.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;

        // The heap isn't visible to shaders because shaders don't need to read the swapchain... but we still need a
        // descriptor heap
        rtv_heap_descriptor.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        HRESULT hr = device->CreateDescriptorHeap(&rtv_heap_descriptor, IID_PPV_ARGS(&rtv_descriptor_heap));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create descriptor heap for the RTV";
            throw render_engine_initialization_exception("Could not create descriptor head for the RTV");
        }

        rtv_descriptor_size = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

        CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle(rtv_descriptor_heap->GetCPUDescriptorHandleForHeapStart());

        for(uint32_t i = 0; i < FRAME_BUFFER_COUNT; i++) {
            hr = swapchain->GetBuffer(i, IID_PPV_ARGS(&rendertargets[i]));
            if(FAILED(hr)) {
                NOVA_LOG(FATAL) << "Could not create RTV for swapchain image " << i;
                throw render_engine_initialization_exception("Could not create RTV for swapchain");
            }

            // Create the Render Target View, which binds the swapchain buffer to the RTV handle
            device->CreateRenderTargetView(rendertargets[i].Get(), nullptr, rtv_handle);

            // Increment the RTV handle
            rtv_handle.Offset(1, rtv_descriptor_size);
        }
    }

    std::shared_ptr<iwindow> dx12_render_engine::get_window() const {
        return window;
    }

    void dx12_render_engine::render_frame() {
        gfx_command_list present_commands = get_graphics_command_list();

        // Wait for the previous frame at our index to finish
        frame_index = swapchain->GetCurrentBackBufferIndex();
        if(present_commands.submission_fence->GetCompletedValue() < present_commands.fence_value) {
            present_commands.submission_fence->SetEventOnCompletion(present_commands.fence_value, full_frame_fence_event);
            WaitForSingleObject(full_frame_fence_event, INFINITE);
        }
        // There is enough space in a 32-bit integer to run Nova at 60 fps for almost three years. Running Nova
        // continuously for more than one year is not supported
        present_commands.fence_value++;

        HRESULT hr = present_commands.allocator->Reset();
        if(FAILED(hr)) {
            NOVA_LOG(WARN) << "Could not reset command list allocator, memory usage will likely increase dramatically";
        }

        present_commands.list->Reset(present_commands.allocator.Get(), nullptr);

        CD3DX12_RESOURCE_BARRIER to_render_target = CD3DX12_RESOURCE_BARRIER::Transition(rendertargets[frame_index].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
        present_commands.list->ResourceBarrier(1, &to_render_target);

        CD3DX12_CPU_DESCRIPTOR_HANDLE current_framebuffer_rtv(rtv_descriptor_heap->GetCPUDescriptorHandleForHeapStart(), frame_index, rtv_descriptor_size);
        present_commands.list->OMSetRenderTargets(1, &current_framebuffer_rtv, false, nullptr);

        glm::vec4 clear_color(0, 0.2f, 0.4f, 1.0f);
        present_commands.list->ClearRenderTargetView(current_framebuffer_rtv, &clear_color.x, 0, nullptr);

        CD3DX12_RESOURCE_BARRIER to_presentable = CD3DX12_RESOURCE_BARRIER::Transition(rendertargets[frame_index].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
        present_commands.list->ResourceBarrier(1, &to_presentable);

        present_commands.list->Close();

        ID3D12CommandList* commands[] = {present_commands.list.Get()};
        direct_command_queue->ExecuteCommandLists(1, commands);
        direct_command_queue->Signal(present_commands.submission_fence.Get(), present_commands.fence_value);

        swapchain->Present(0, 0);

        release_command_list(present_commands);

    }

    command_list dx12_render_engine::allocate_command_list(D3D12_COMMAND_LIST_TYPE command_list_type) {
        ComPtr<ID3D12CommandAllocator> allocator;
        HRESULT hr = device->CreateCommandAllocator(command_list_type, IID_PPV_ARGS(&allocator));
        if(FAILED(hr)) {
            NOVA_LOG(FATAL) << "Could not create command buffer";
            throw std::runtime_error("Could not create command buffer");
        }

        ComPtr<ID3D12CommandList> list;
        hr = device->CreateCommandList(0, command_list_type, allocator.Get(), nullptr, IID_PPV_ARGS(&list));
        if(FAILED(hr)) {
            NOVA_LOG(ERROR) << "Could not create a command list of type " << (uint32_t)command_list_type;
            throw std::runtime_error("Could not create command list");
        }

        ComPtr<ID3D12Fence> fence;
        device->CreateFence(1, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));

        command_list cmd_list = {};
        cmd_list.list = list;
        cmd_list.allocator = allocator;
        cmd_list.submission_fence = fence;

        return cmd_list;
    }

    gfx_command_list dx12_render_engine::get_graphics_command_list() {
        command_list new_list = {};
        ComPtr<ID3D12GraphicsCommandList> graphics_list;
        auto& buffers = buffer_pool.at(D3D12_COMMAND_LIST_TYPE_DIRECT);
        if(buffers.empty()) {
            new_list = allocate_command_list(D3D12_COMMAND_LIST_TYPE_DIRECT);

        } else {
            new_list = buffers.back();
            buffers.pop_back();
        }
        new_list.list->QueryInterface(IID_PPV_ARGS(&graphics_list));

        gfx_command_list gfx_list = {};
        gfx_list.list = graphics_list;
        gfx_list.allocator = new_list.allocator;
        gfx_list.submission_fence = new_list.submission_fence;

        return gfx_list;
    }

    void dx12_render_engine::release_command_list(gfx_command_list list) {

    }

    void dx12_render_engine::create_fence_wait_event() {
        full_frame_fence_event = CreateEvent(nullptr, false, false, nullptr);
    }

    void dx12_render_engine::set_frame_graph() {

    }
}
<|endoftext|>


<commit_before>#include "Runtime.h"
#include "Object.h"
#include "Integer.h"
#include "Nil.h"
#include "SnowString.h"
#include <stdarg.h>

namespace snow {
	VALUE create_object(Object* prototype) {
		return value(new Object(prototype));
	}

	VALUE create_function(FunctionPtr ptr) {
		return value(new Function(ptr));
	}

	VALUE create_string(const char* str) {
		return value(new String(str));
	}

	VALUE create_float(double d) {
		return nil();
	}

	static VALUE va_call(VALUE function_or_object, VALUE self, uint64_t num_args, va_list& ap) {
		if (!is_object(function_or_object))
			return function_or_object;
		return object_for(function_or_object)->va_call(self, num_args, ap);
	}

	VALUE call(VALUE function_or_object, uint64_t num_args, ...) {
		VALUE ret;
		va_list ap;
		va_start(ap, num_args);
		ret = va_call(function_or_object, NULL, num_args, ap);
		va_end(ap);
		return ret;
	}

	VALUE call_method(VALUE self, const char* message, uint64_t num_args, ...) {
		VALUE ret;
		va_list ap;
		va_start(ap, num_args);
		VALUE function_or_object = send(object_for(self), message);
		if (is_nil(function_or_object))
			warn("METHOD %s UNDEFINED on object 0x%llx (%s)!", message, object_for(self), value_to_string(object_for(self)->get("name")));
		ret = va_call(function_or_object, self, num_args, ap);
		va_end(ap);
		return ret;
	}

	VALUE send(VALUE obj, const char* message) {
		Object* o = object_for(obj);
		return o->get(message);
	}

	VALUE copy(VALUE obj) {
		if (is_object(obj))
			return object(obj)->copy();
		else
			return obj;
	}

	void destroy(VALUE _obj) {
		if (is_object(_obj)) {
			Object* obj = object(_obj);

			VALUE finalize = send(obj, "finalize");
			call(finalize, 0);

			for (auto iter = iterate(obj->members()); iter; ++iter) {
				destroy(iter->second);
			}

			delete obj;
		}
	}

	const char* value_to_string(VALUE _obj) {
		Object* obj = object_for(_obj);

		VALUE returned = call_method(obj, "to_string", 0);

		assert_object(returned, String);

		auto string = object_cast<String>(returned);

		return (const char*)(*string);
	}

	Object* object_for(VALUE obj) {
		switch (value_type(obj)) {
			case kObjectType:
				// Safeguard: NULL pointers become 'nil'
				return obj ? object(obj) : nil_prototype();
			case kEvenIntegerType:
			case kOddIntegerType:
				return integer_prototype();
			default:
			case kSpecialType:
				switch (special_value(obj)) {
					case kTrue:
					case kFalse:
//						return boolean_prototype();
						break;
					default:
					case kNil:
						return nil_prototype();
				}
				break;
		}

		return nil_prototype();
	}
}<commit_msg>runtime: value_to_string shouldn't call object_for -- call_method handles immediates<commit_after>#include "Runtime.h"
#include "Object.h"
#include "Integer.h"
#include "Nil.h"
#include "SnowString.h"
#include <stdarg.h>

namespace snow {
	VALUE create_object(Object* prototype) {
		return value(new Object(prototype));
	}

	VALUE create_function(FunctionPtr ptr) {
		return value(new Function(ptr));
	}

	VALUE create_string(const char* str) {
		return value(new String(str));
	}

	VALUE create_float(double d) {
		return nil();
	}

	static VALUE va_call(VALUE function_or_object, VALUE self, uint64_t num_args, va_list& ap) {
		if (!is_object(function_or_object))
			return function_or_object;
		return object_for(function_or_object)->va_call(self, num_args, ap);
	}

	VALUE call(VALUE function_or_object, uint64_t num_args, ...) {
		VALUE ret;
		va_list ap;
		va_start(ap, num_args);
		ret = va_call(function_or_object, NULL, num_args, ap);
		va_end(ap);
		return ret;
	}

	VALUE call_method(VALUE self, const char* message, uint64_t num_args, ...) {
		VALUE ret;
		va_list ap;
		va_start(ap, num_args);
		VALUE function_or_object = send(object_for(self), message);
		if (is_nil(function_or_object))
			warn("METHOD %s UNDEFINED on object 0x%llx (%s)!", message, object_for(self), value_to_string(object_for(self)->get("name")));
		ret = va_call(function_or_object, self, num_args, ap);
		va_end(ap);
		return ret;
	}

	VALUE send(VALUE obj, const char* message) {
		Object* o = object_for(obj);
		return o->get(message);
	}

	VALUE copy(VALUE obj) {
		if (is_object(obj))
			return object(obj)->copy();
		else
			return obj;
	}

	void destroy(VALUE _obj) {
		if (is_object(_obj)) {
			Object* obj = object(_obj);

			VALUE finalize = send(obj, "finalize");
			call(finalize, 0);

			for (auto iter = iterate(obj->members()); iter; ++iter) {
				destroy(iter->second);
			}

			delete obj;
		}
	}

	const char* value_to_string(VALUE obj) {
		VALUE returned = call_method(obj, "to_string", 0);

		assert_object(returned, String);

		auto string = object_cast<String>(returned);

		return (const char*)(*string);
	}

	Object* object_for(VALUE obj) {
		switch (value_type(obj)) {
			case kObjectType:
				// Safeguard: NULL pointers become 'nil'
				return obj ? object(obj) : nil_prototype();
			case kEvenIntegerType:
			case kOddIntegerType:
				return integer_prototype();
			default:
			case kSpecialType:
				switch (special_value(obj)) {
					case kTrue:
					case kFalse:
//						return boolean_prototype();
						break;
					default:
					case kNil:
						return nil_prototype();
				}
				break;
		}

		return nil_prototype();
	}
}<|endoftext|>


<commit_before>#pragma once

#ifndef BEARTRAP_HPP
#define BEARTRAP_HPP

#include "gridtick_interface.hpp"
#include "piece.hpp"

#include <ge/mesh.hpp>
#include <ge/mesh_actor.hpp>
#include <ge/texture_asset.hpp>
#include "grid.hpp"

class beartrap : public piece
{
	ge::mesh_actor* mesh;

public:
	void initialize(glm::uvec2 location)
	{
		piece::initialize({ location.x, location.y, 1 });
		add_interface<beartrap, gridtick_interface>();
		mesh = ge::actor::factory<ge::mesh_actor>(this, "turret/turret.meshsettings").get();
		mesh->set_mat_param("Texture", get_asset<ge::texture_asset>("spike.texture"));

		sig_die.connect([](piece* p) { p->set_parent(NULL); });
	}
	void tick_grid()
	{
		if (countdown_to_action >= 0) {
			countdown_to_action--;
			return;
		}
		else
			countdown_to_action = now.speed;
		glm::ivec3 myLocation = get_grid_location();
		auto actors = m_grid->get_actors_from_coord(glm::ivec3(myLocation.x, myLocation.y, 2));
		for (int x = 0; x < actors.size(); x++) {
			actors[x]->damage(3, this);
		}
	}
};

#endif  // TURRET_HPP
<commit_msg>bear trap changes<commit_after>#pragma once

#ifndef BEARTRAP_HPP
#define BEARTRAP_HPP

#include "gridtick_interface.hpp"
#include "piece.hpp"

#include <ge/mesh.hpp>
#include <ge/mesh_actor.hpp>
#include <ge/texture_asset.hpp>
#include "grid.hpp"

class beartrap : public piece
{
	ge::mesh_actor* mesh;

public:
	void initialize(glm::uvec2 location)
	{
		piece::initialize({ location.x, location.y, 1 });
		add_interface<beartrap, gridtick_interface>();
		mesh = ge::actor::factory<ge::mesh_actor>(this, "turret/turret.meshsettings").get();
		mesh->set_mat_param("Texture", get_asset<ge::texture_asset>("spike.texture"));

		sig_die.connect([](piece* p) { p->set_parent(NULL); });
		now.speed = 0;
	}
	void tick_grid()
	{
		if (countdown_to_action >= 0) {
			countdown_to_action--;
			return;
		}
		else
			countdown_to_action = now.speed;
		glm::ivec3 myLocation = get_grid_location();
		auto actors = m_grid->get_actors_from_coord(glm::ivec3(myLocation.x, myLocation.y, 2));
		for (int x = 0; x < actors.size(); x++) {
			actors[x]->active=false;
			active = false;
		}
	}
};

#endif  // TURRET_HPP
<|endoftext|>


<commit_before>// @(#)root/reflex:$Name:  $:$Id: ClassBuilder.cxx,v 1.2 2005/11/03 15:24:40 roiser Exp $
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2005, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#include "Reflex/Builder/ClassBuilder.h"

#include "Reflex/Type.h"
#include "Reflex/Member.h"

#include "Class.h"
#include "ClassTemplateInstance.h"
#include "Reflex/Tools.h"
#include "Typedef.h"
#include "Enum.h"
#include "DataMember.h"
#include "FunctionMemberTemplateInstance.h"

//-------------------------------------------------------------------------------
ROOT::Reflex::ClassBuilderImpl::ClassBuilderImpl( const char * nam,
                                                  const std::type_info & ti,
                                                  size_t size,
                                                  unsigned int modifiers )
//-------------------------------------------------------------------------------
  : fClass( 0 ),
    fLastMember( 0 )
{
  Type c = Type::ByName(nam);
  if ( c ) {
    // Class already exists. Check if it was a class.
    if (! c.IsClass() ) throw RuntimeError("Attempt to replace a non-Class At with a Class At");
  }

  if ( Tools::IsTemplated( nam))  fClass = new ClassTemplateInstance( nam,
                                                                       size,
                                                                       ti,
                                                                       modifiers );
  else                             fClass = new Class( nam,
                                                       size,
                                                       ti,
                                                       modifiers );
}

//-------------------------------------------------------------------------------
ROOT::Reflex::ClassBuilderImpl::~ClassBuilderImpl() {
//-------------------------------------------------------------------------------
  FireClassCallback( fClass->ThisType() );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddBase( const Type & bas,
                                              OffsetFunction offsFP,
                                              unsigned int modifiers ) {
//-------------------------------------------------------------------------------
  fClass->AddBase( bas, offsFP, modifiers );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddDataMember( const char * nam,
                                                    const Type & typ,
                                                    size_t offs,
                                                    unsigned int modifiers ) {
//-------------------------------------------------------------------------------
  fLastMember = Member(new DataMember( nam, typ, offs, modifiers ));
  fClass->AddDataMember( fLastMember );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddFunctionMember( const char * nam,
                                                        const Type & typ,
                                                        StubFunction stubFP,
                                                        void*        stubCtx,
                                                        const char * params,
                                                        unsigned int modifiers ) {
//-------------------------------------------------------------------------------
  if ( Tools::IsTemplated( nam ))
    fLastMember = Member(new FunctionMemberTemplateInstance( nam,
                                                             typ,
                                                             stubFP,
                                                             stubCtx,
                                                             params,
                                                             modifiers,
                                                             (Scope)(*fClass)));
  else
    fLastMember = Member(new FunctionMember( nam,
                                             typ,
                                             stubFP,
                                             stubCtx,
                                             params,
                                             modifiers ));
  fClass->AddFunctionMember( fLastMember );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddTypedef( const Type & typ,
                                                 const char * def ) {
//-------------------------------------------------------------------------------
  new Typedef( def, typ );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddEnum( const char * nam,
                                              const char * values,
                                              const std::type_info * ti ) {
//-------------------------------------------------------------------------------

  Enum * e = new Enum(nam, *ti);

  std::vector<std::string> valVec = std::vector<std::string>();
  Tools::StringSplit(valVec, values, ";");

  for (std::vector<std::string>::const_iterator it = valVec.begin();
       it != valVec.end(); ++it ) {
    std::string name = "";
    std::string value = "";
    Tools::StringSplitPair(name, value, *it, "=");
    unsigned long valInt = atol(value.c_str());
    e->AddDataMember( Member( new DataMember( name.c_str(),
                                              Type::ByName("int"),
                                              valInt,
                                              0 )));
  }
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddProperty( const char * key,
                                                  const char * value ) {
//-------------------------------------------------------------------------------
  AddProperty( key, Any(value) );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddProperty( const char * key,
                                                  Any value ) {
//-------------------------------------------------------------------------------
  if ( fLastMember ) fLastMember.Properties().AddProperty( key, value );
  else                fClass->Properties().AddProperty(key, value);
}

<commit_msg>fixing ambigous operator<commit_after>// @(#)root/reflex:$Name:  $:$Id: ClassBuilder.cxx,v 1.3 2005/11/11 07:18:06 roiser Exp $
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2005, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#include "Reflex/Builder/ClassBuilder.h"

#include "Reflex/Type.h"
#include "Reflex/Member.h"

#include "Class.h"
#include "ClassTemplateInstance.h"
#include "Reflex/Tools.h"
#include "Typedef.h"
#include "Enum.h"
#include "DataMember.h"
#include "FunctionMemberTemplateInstance.h"

//-------------------------------------------------------------------------------
ROOT::Reflex::ClassBuilderImpl::ClassBuilderImpl( const char * nam,
                                                  const std::type_info & ti,
                                                  size_t size,
                                                  unsigned int modifiers )
//-------------------------------------------------------------------------------
  : fClass( 0 ),
    fLastMember( 0 )
{
  Type c = Type::ByName(nam);
  if ( c ) {
    // Class already exists. Check if it was a class.
    if (! c.IsClass() ) throw RuntimeError("Attempt to replace a non-Class At with a Class At");
  }

  if ( Tools::IsTemplated( nam))  fClass = new ClassTemplateInstance( nam,
                                                                       size,
                                                                       ti,
                                                                       modifiers );
  else                             fClass = new Class( nam,
                                                       size,
                                                       ti,
                                                       modifiers );
}

//-------------------------------------------------------------------------------
ROOT::Reflex::ClassBuilderImpl::~ClassBuilderImpl() {
//-------------------------------------------------------------------------------
  FireClassCallback( fClass->ThisType() );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddBase( const Type & bas,
                                              OffsetFunction offsFP,
                                              unsigned int modifiers ) {
//-------------------------------------------------------------------------------
  fClass->AddBase( bas, offsFP, modifiers );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddDataMember( const char * nam,
                                                    const Type & typ,
                                                    size_t offs,
                                                    unsigned int modifiers ) {
//-------------------------------------------------------------------------------
  fLastMember = Member(new DataMember( nam, typ, offs, modifiers ));
  fClass->AddDataMember( fLastMember );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddFunctionMember( const char * nam,
                                                        const Type & typ,
                                                        StubFunction stubFP,
                                                        void*        stubCtx,
                                                        const char * params,
                                                        unsigned int modifiers ) {
//-------------------------------------------------------------------------------
  if ( Tools::IsTemplated( nam ))
    fLastMember = Member(new FunctionMemberTemplateInstance( nam,
                                                             typ,
                                                             stubFP,
                                                             stubCtx,
                                                             params,
                                                             modifiers,
                                                             *(dynamic_cast<ScopeBase*>(fClass))));
  else
    fLastMember = Member(new FunctionMember( nam,
                                             typ,
                                             stubFP,
                                             stubCtx,
                                             params,
                                             modifiers ));
  fClass->AddFunctionMember( fLastMember );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddTypedef( const Type & typ,
                                                 const char * def ) {
//-------------------------------------------------------------------------------
  new Typedef( def, typ );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddEnum( const char * nam,
                                              const char * values,
                                              const std::type_info * ti ) {
//-------------------------------------------------------------------------------

  Enum * e = new Enum(nam, *ti);

  std::vector<std::string> valVec = std::vector<std::string>();
  Tools::StringSplit(valVec, values, ";");

  for (std::vector<std::string>::const_iterator it = valVec.begin();
       it != valVec.end(); ++it ) {
    std::string name = "";
    std::string value = "";
    Tools::StringSplitPair(name, value, *it, "=");
    unsigned long valInt = atol(value.c_str());
    e->AddDataMember( Member( new DataMember( name.c_str(),
                                              Type::ByName("int"),
                                              valInt,
                                              0 )));
  }
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddProperty( const char * key,
                                                  const char * value ) {
//-------------------------------------------------------------------------------
  AddProperty( key, Any(value) );
}

//-------------------------------------------------------------------------------
void ROOT::Reflex::ClassBuilderImpl::AddProperty( const char * key,
                                                  Any value ) {
//-------------------------------------------------------------------------------
  if ( fLastMember ) fLastMember.Properties().AddProperty( key, value );
  else                fClass->Properties().AddProperty(key, value);
}

<|endoftext|>


<commit_before><commit_msg>coverity#708045 Uninitialized scalar field<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2015 Cloudius Systems
 */

#include "commitlog.hh"
#include <db/commitlog/commitlog.hh>
#include "api/api-doc/commitlog.json.hh"
#include <vector>

namespace api {

void set_commitlog(http_context& ctx, routes& r) {
    httpd::commitlog_json::get_active_segment_names.set(r,
            [&ctx](std::unique_ptr<request> req) {
        auto res = make_shared<std::vector<sstring>>();
        return ctx.db.map_reduce([res](std::vector<sstring> names) {
            res->insert(res->end(), names.begin(), names.end());
        }, [](database& db) {
            if (db.commitlog() == nullptr) {
                return make_ready_future<std::vector<sstring>>(std::vector<sstring>());
            }
            return make_ready_future<std::vector<sstring>>(db.commitlog()->get_active_segment_names());
        }).then([res] {
            return make_ready_future<json::json_return_type>(*res.get());
        });
    });

    // We currently do not support archive segments
    httpd::commitlog_json::get_archiving_segment_names.set(r, [](const_req req) {
        std::vector<sstring> res;
        return res;
    });
}

}
<commit_msg>Adding the commit log metric stub implementation<commit_after>/*
 * Copyright 2015 Cloudius Systems
 */

#include "commitlog.hh"
#include <db/commitlog/commitlog.hh>
#include "api/api-doc/commitlog.json.hh"
#include <vector>

namespace api {

void set_commitlog(http_context& ctx, routes& r) {
    httpd::commitlog_json::get_active_segment_names.set(r,
            [&ctx](std::unique_ptr<request> req) {
        auto res = make_shared<std::vector<sstring>>();
        return ctx.db.map_reduce([res](std::vector<sstring> names) {
            res->insert(res->end(), names.begin(), names.end());
        }, [](database& db) {
            if (db.commitlog() == nullptr) {
                return make_ready_future<std::vector<sstring>>(std::vector<sstring>());
            }
            return make_ready_future<std::vector<sstring>>(db.commitlog()->get_active_segment_names());
        }).then([res] {
            return make_ready_future<json::json_return_type>(*res.get());
        });
    });

    // We currently do not support archive segments
    httpd::commitlog_json::get_archiving_segment_names.set(r, [](const_req req) {
        std::vector<sstring> res;
        return res;
    });

    httpd::commitlog_json::get_completed_tasks.set(r, [](std::unique_ptr<request> req) {
        //TBD
        return make_ready_future<json::json_return_type>(0);
    });

    httpd::commitlog_json::get_pending_tasks.set(r, [](std::unique_ptr<request> req) {
        //TBD
        return make_ready_future<json::json_return_type>(0);
    });

    httpd::commitlog_json::get_total_commit_log_size.set(r, [](std::unique_ptr<request> req) {
        //TBD
        return make_ready_future<json::json_return_type>(0);
    });
}

}
<|endoftext|>