<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "ActionWarehouse.h"
#include "ActionFactory.h"
#include "Parser.h"
#include "MooseObjectAction.h"
#include "InputFileFormatter.h"
#include "InputParameters.h"
#include "MooseMesh.h"

ActionWarehouse::ActionWarehouse(MooseApp & app, Syntax & syntax, ActionFactory & factory) :
    _app(app),
    _syntax(syntax),
    _action_factory(factory),
    _generator_valid(false),
    _show_actions(false),
    _mesh(NULL),
    _displaced_mesh(NULL),
    _problem(NULL),
    _executioner(NULL)
{
}

ActionWarehouse::~ActionWarehouse()
{
}

void
ActionWarehouse::build()
{
  _ordered_names = _syntax.getSortedActionName();
  for (std::vector<std::string>::iterator it = _ordered_names.begin(); it != _ordered_names.end(); ++it)
    buildBuildableActions(*it);
}

void
ActionWarehouse::clear()
{
  for (std::map<std::string, std::vector<Action *> >::iterator it = _action_blocks.begin(); it != _action_blocks.end(); ++it)
  {
    for (std::vector<Action *>::iterator jt = (*it).second.begin(); jt != (*it).second.end(); ++jt)
      delete *jt;
  }
  _action_blocks.clear();
  _generator_valid = false;
}

void
ActionWarehouse::addActionBlock(Action * blk)
{
  std::string action_name = blk->getAction();

  // Some error checking
  if (!_syntax.hasActionName(action_name))
    mooseError("A(n) " << action_name << " is not a registered action name");

  // Make sure that the ObjectAction action_name and Action action_name are consistent
  // otherwise that means that is action was built by the wrong type
  MooseObjectAction * moa = dynamic_cast<MooseObjectAction *>(blk);
  if (moa)
  {
    InputParameters mparams = moa->getObjectParams();
    if (mparams.have_parameter<std::string>("built_by_action"))
    {
      std::string moose_action_name = moa->getObjectParams().get<std::string>("built_by_action");
      if ((moose_action_name != action_name) &&  // if there is a mismatch, that means there is an object in the wrong section, unless...
          ! // NOT in the exception list...
          ((action_name == "add_aux_bc" && moose_action_name == "add_aux_kernel") ||
           (action_name == "add_postprocessor" && moose_action_name == "add_user_object") ||
           (action_name == "add_user_object" && moose_action_name == "add_postprocessor")))
        mooseError("Inconsistent Action Name detected! Action that satisfies " + action_name + " is building a MOOSE Object that normally satisfies " + moose_action_name);
    }
  }

  _action_blocks[action_name].push_back(blk);
}

ActionIterator
ActionWarehouse::actionBlocksWithActionBegin(const std::string & action_name)
{
  return _action_blocks[action_name].begin();
}

ActionIterator
ActionWarehouse::actionBlocksWithActionEnd(const std::string & action_name)
{
  return _action_blocks[action_name].end();
}

const std::vector<Action *> &
ActionWarehouse::getActionsByName(const std::string & action_name) const
{
  return _action_blocks.at(action_name);
}

void
ActionWarehouse::buildBuildableActions(const std::string &action_name)
{
  if (_syntax.isActionRequired(action_name) && _action_blocks[action_name].empty())
  {
    bool ret_value = false;
    std::pair<std::multimap<std::string, std::string>::iterator,
              std::multimap<std::string, std::string>::iterator> range = _action_factory.getA(action_name);
    for (std::multimap<std::string, std::string>::iterator it = range.first; it != range.second; ++it)
    {
      InputParameters params = _action_factory.getValidParams(it->second);
      params.set<ActionWarehouse *>("awh") = this;

      if (params.areAllRequiredParamsValid())
      {
        addActionBlock(_action_factory.create(it->second, "", params));
        ret_value = true;
      }
    }

    if (!ret_value)
      _unsatisfied_dependencies.insert(action_name);
  }
}

void
ActionWarehouse::checkUnsatisfiedActions() const
{
  std::stringstream oss;
  bool empty = true;

  for (std::set<std::string>::const_iterator i = _unsatisfied_dependencies.begin(); i != _unsatisfied_dependencies.end(); ++i)
  {
    if (_action_blocks.find(*i) == _action_blocks.end())
    {
      if (empty)
        empty = false;
      else
        oss << " ";
      oss << *i;
    }
  }

  if (!empty)
    mooseError(std::string("The following unsatisfied actions where found while setting up the MOOSE problem:\n")
               + oss.str() + "\n");
}

void
ActionWarehouse::printActionDependencySets()
{
  std::cerr << "[DBG][ACT] Ordered Actions:\n";

  const std::vector<std::set<std::string> > & ordered_names = _syntax.getSortedActionNameSet();
  for (std::vector<std::set<std::string> >::const_iterator i = ordered_names.begin(); i != ordered_names.end(); ++i)
  {
    std::cerr << "[DBG][ACT] (";
    unsigned int jj = 0;
    for (std::set<std::string>::const_iterator j = i->begin(); j != i->end(); ++j)
    {
      if (jj++) std::cerr << ", ";
      std::cout << *j;
    }
    std::cout << ")\n";

    for (std::set<std::string>::const_iterator j = i->begin(); j != i->end(); ++j)
    {
      for (std::vector<Action *>::const_iterator k = _action_blocks[*j].begin(); k != _action_blocks[*j].end(); ++k)
        std::cerr << "[DBG][ACT]" << "\t" << (*k)->getAction() << "\n";
    }
  }
}

void
ActionWarehouse::executeAllActions()
{
  if (_show_actions)
  {
    std::cerr << "[DBG][ACT] Action Dependency Sets:\n";
    printActionDependencySets();
    std::cerr << "[DBG][ACT] Executing actions:" << std::endl;
  }

  for (std::vector<std::string>::iterator it = _ordered_names.begin(); it != _ordered_names.end(); ++it)
  {
    std::string action_name = *it;
    executeActionsWithAction(action_name);
  }
}

void
ActionWarehouse::executeActionsWithAction(const std::string & name)
{
  for (ActionIterator act_iter = actionBlocksWithActionBegin(name);
       act_iter != actionBlocksWithActionEnd(name);
       ++act_iter)
  {
    if (_show_actions)
      std::cerr << "[DBG][ACT] - " << (*act_iter)->name() << std::endl;
    (*act_iter)->act();
  }
}

void
ActionWarehouse::printInputFile(std::ostream & out)
{
  InputFileFormatter tree(false);

  std::map<std::string, std::vector<Action *> >::iterator iter;

  std::vector<Action *> ordered_actions;
  ordered_actions.clear();
  for (iter = _action_blocks.begin(); iter != _action_blocks.end(); ++iter)
    for (std::vector<Action *>::iterator j = iter->second.begin(); j != iter->second.end(); ++j)
      ordered_actions.push_back(*j);

  for (std::vector<Action* >::iterator i = ordered_actions.begin();
       i != ordered_actions.end();
       ++i)
   {
    std::string name ((*i)->name());
    std::string action ((*i)->getAction());

    bool is_parent;
    if (_syntax.isAssociated(name, &is_parent) != "")
     {
      InputParameters params = (*i)->getParams();
      tree.insertNode(name, action, true, &params);

      MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(*i);
      if (moose_object_action)
       {
        InputParameters obj_params = moose_object_action->getObjectParams();
        tree.insertNode(name, action, false, &obj_params);
       }
     }
  }

  out << tree.print("");
}
<commit_msg>Improve error message<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "ActionWarehouse.h"
#include "ActionFactory.h"
#include "Parser.h"
#include "MooseObjectAction.h"
#include "InputFileFormatter.h"
#include "InputParameters.h"
#include "MooseMesh.h"

ActionWarehouse::ActionWarehouse(MooseApp & app, Syntax & syntax, ActionFactory & factory) :
    _app(app),
    _syntax(syntax),
    _action_factory(factory),
    _generator_valid(false),
    _show_actions(false),
    _mesh(NULL),
    _displaced_mesh(NULL),
    _problem(NULL),
    _executioner(NULL)
{
}

ActionWarehouse::~ActionWarehouse()
{
}

void
ActionWarehouse::build()
{
  _ordered_names = _syntax.getSortedActionName();
  for (std::vector<std::string>::iterator it = _ordered_names.begin(); it != _ordered_names.end(); ++it)
    buildBuildableActions(*it);
}

void
ActionWarehouse::clear()
{
  for (std::map<std::string, std::vector<Action *> >::iterator it = _action_blocks.begin(); it != _action_blocks.end(); ++it)
  {
    for (std::vector<Action *>::iterator jt = (*it).second.begin(); jt != (*it).second.end(); ++jt)
      delete *jt;
  }
  _action_blocks.clear();
  _generator_valid = false;
}

void
ActionWarehouse::addActionBlock(Action * blk)
{
  std::string action_name = blk->getAction();

  // Some error checking
  if (!_syntax.hasActionName(action_name))
    mooseError("A(n) " << action_name << " is not a registered action name");

  // Make sure that the ObjectAction action_name and Action action_name are consistent
  // otherwise that means that is action was built by the wrong type
  MooseObjectAction * moa = dynamic_cast<MooseObjectAction *>(blk);
  if (moa)
  {
    InputParameters mparams = moa->getObjectParams();
    if (mparams.have_parameter<std::string>("built_by_action"))
    {
      std::string moose_action_name = moa->getObjectParams().get<std::string>("built_by_action");
      if ((moose_action_name != action_name) &&  // if there is a mismatch, that means there is an object in the wrong section, unless...
          ! // NOT in the exception list...
          ((action_name == "add_aux_bc" && moose_action_name == "add_aux_kernel") ||
           (action_name == "add_postprocessor" && moose_action_name == "add_user_object") ||
           (action_name == "add_user_object" && moose_action_name == "add_postprocessor")))
        mooseError("Inconsistent Action Name detected (" + blk->name() + ")! Action that satisfies " + action_name + " is building a MOOSE Object that normally satisfies " + moose_action_name);
    }
  }

  _action_blocks[action_name].push_back(blk);
}

ActionIterator
ActionWarehouse::actionBlocksWithActionBegin(const std::string & action_name)
{
  return _action_blocks[action_name].begin();
}

ActionIterator
ActionWarehouse::actionBlocksWithActionEnd(const std::string & action_name)
{
  return _action_blocks[action_name].end();
}

const std::vector<Action *> &
ActionWarehouse::getActionsByName(const std::string & action_name) const
{
  return _action_blocks.at(action_name);
}

void
ActionWarehouse::buildBuildableActions(const std::string &action_name)
{
  if (_syntax.isActionRequired(action_name) && _action_blocks[action_name].empty())
  {
    bool ret_value = false;
    std::pair<std::multimap<std::string, std::string>::iterator,
              std::multimap<std::string, std::string>::iterator> range = _action_factory.getA(action_name);
    for (std::multimap<std::string, std::string>::iterator it = range.first; it != range.second; ++it)
    {
      InputParameters params = _action_factory.getValidParams(it->second);
      params.set<ActionWarehouse *>("awh") = this;

      if (params.areAllRequiredParamsValid())
      {
        addActionBlock(_action_factory.create(it->second, "", params));
        ret_value = true;
      }
    }

    if (!ret_value)
      _unsatisfied_dependencies.insert(action_name);
  }
}

void
ActionWarehouse::checkUnsatisfiedActions() const
{
  std::stringstream oss;
  bool empty = true;

  for (std::set<std::string>::const_iterator i = _unsatisfied_dependencies.begin(); i != _unsatisfied_dependencies.end(); ++i)
  {
    if (_action_blocks.find(*i) == _action_blocks.end())
    {
      if (empty)
        empty = false;
      else
        oss << " ";
      oss << *i;
    }
  }

  if (!empty)
    mooseError(std::string("The following unsatisfied actions where found while setting up the MOOSE problem:\n")
               + oss.str() + "\n");
}

void
ActionWarehouse::printActionDependencySets()
{
  std::cerr << "[DBG][ACT] Ordered Actions:\n";

  const std::vector<std::set<std::string> > & ordered_names = _syntax.getSortedActionNameSet();
  for (std::vector<std::set<std::string> >::const_iterator i = ordered_names.begin(); i != ordered_names.end(); ++i)
  {
    std::cerr << "[DBG][ACT] (";
    unsigned int jj = 0;
    for (std::set<std::string>::const_iterator j = i->begin(); j != i->end(); ++j)
    {
      if (jj++) std::cerr << ", ";
      std::cout << *j;
    }
    std::cout << ")\n";

    for (std::set<std::string>::const_iterator j = i->begin(); j != i->end(); ++j)
    {
      for (std::vector<Action *>::const_iterator k = _action_blocks[*j].begin(); k != _action_blocks[*j].end(); ++k)
        std::cerr << "[DBG][ACT]" << "\t" << (*k)->getAction() << "\n";
    }
  }
}

void
ActionWarehouse::executeAllActions()
{
  if (_show_actions)
  {
    std::cerr << "[DBG][ACT] Action Dependency Sets:\n";
    printActionDependencySets();
    std::cerr << "[DBG][ACT] Executing actions:" << std::endl;
  }

  for (std::vector<std::string>::iterator it = _ordered_names.begin(); it != _ordered_names.end(); ++it)
  {
    std::string action_name = *it;
    executeActionsWithAction(action_name);
  }
}

void
ActionWarehouse::executeActionsWithAction(const std::string & name)
{
  for (ActionIterator act_iter = actionBlocksWithActionBegin(name);
       act_iter != actionBlocksWithActionEnd(name);
       ++act_iter)
  {
    if (_show_actions)
      std::cerr << "[DBG][ACT] - " << (*act_iter)->name() << std::endl;
    (*act_iter)->act();
  }
}

void
ActionWarehouse::printInputFile(std::ostream & out)
{
  InputFileFormatter tree(false);

  std::map<std::string, std::vector<Action *> >::iterator iter;

  std::vector<Action *> ordered_actions;
  ordered_actions.clear();
  for (iter = _action_blocks.begin(); iter != _action_blocks.end(); ++iter)
    for (std::vector<Action *>::iterator j = iter->second.begin(); j != iter->second.end(); ++j)
      ordered_actions.push_back(*j);

  for (std::vector<Action* >::iterator i = ordered_actions.begin();
       i != ordered_actions.end();
       ++i)
   {
    std::string name ((*i)->name());
    std::string action ((*i)->getAction());

    bool is_parent;
    if (_syntax.isAssociated(name, &is_parent) != "")
     {
      InputParameters params = (*i)->getParams();
      tree.insertNode(name, action, true, &params);

      MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(*i);
      if (moose_object_action)
       {
        InputParameters obj_params = moose_object_action->getObjectParams();
        tree.insertNode(name, action, false, &obj_params);
       }
     }
  }

  out << tree.print("");
}
<|endoftext|>


<commit_before>#include "block.hpp"
#include <iomanip>

using namespace std;
using namespace boost;

namespace bohrium{
namespace core{

const char Block::TAG[] = "Block";

Block::Block(SymbolTable& globals, vector<tac_t>& program)
: globals_(globals), program_(program), operands_(NULL), noperands_(0), symbol_text_(""), symbol_(""), omask_(0)
{}

Block::~Block()
{
    if (operands_) {
        delete[] operands_;
        operands_   = NULL;
        noperands_  = 0;
    }
}

void Block::clear(void)
{                               // Reset the current state of the block
    tacs_.clear();              // tacs
    array_tacs_.clear();        // array_tacs
    base_refs_.clear();

    omask_ = 0;

    iterspace_.layout = SCALAR_TEMP; // iteraton space
    iterspace_.ndim = 0;
    iterspace_.shape = NULL;
    iterspace_.nelem = 0;

    if (operands_) {            // operands
        delete[] operands_;
        operands_   = NULL;
        noperands_  = 0;
    }
    global_to_local_.clear();   // global to local operand mapping
    local_to_global_.clear();   // local to global operand mapping

    symbol_text_    = "";       // textual symbol representation
    symbol_         = "";       // hashed symbol representation
}

void Block::compose(bh_ir_kernel& krnl)
{
    // An array pointers to operands
    // Will be handed to the kernel-function.
    operands_ = new operand_t*[krnl.instr_indexes.size()*3];

    for(std::vector<uint64_t>::iterator idx_it = krnl.instr_indexes.begin();
        idx_it != krnl.instr_indexes.end();
        ++idx_it) {

        tac_t& tac = program_[*idx_it];

        tacs_.push_back(&tac);              // <-- All tacs
        omask_ |= tac.op;                   // Update omask

        if ((tac.op & (ARRAY_OPS))>0) {
            array_tacs_.push_back(&tac);    // <-- Only array operations
        }

        // Map operands to local-scope
        switch(tac_noperands(tac)) {
            case 3:
                localize(tac.in2);
            case 2:
                localize(tac.in1);
            case 1:
                localize(tac.out);
            default:
                break;
        }
    }
}

void Block::compose(size_t prg_begin, size_t prg_end)
{
    // An array pointers to operands
    // Will be handed to the kernel-function.
    operands_ = new operand_t*[(prg_end-prg_begin+1)*3];

    for(size_t prg_idx=prg_begin; prg_idx<=prg_end; ++prg_idx) {
        tac_t& tac = program_[prg_idx];

        tacs_.push_back(&tac);              // <-- All tacs
        omask_ |= tac.op;                   // Update omask

        if ((tac.op & (ARRAY_OPS))>0) {
            array_tacs_.push_back(&tac);    // <-- Only array operations
        }

        // Map operands to local-scope
        switch(tac_noperands(tac)) {
            case 3:
                localize(tac.in2);
            case 2:
                localize(tac.in1);
            case 1:
                localize(tac.out);
            default:
                break;
        }
    }
}

size_t Block::localize(size_t global_idx)
{
    //
    // Reuse operand identifiers: Detect if we have seen it before and reuse the index.
    size_t local_idx = 0;
    bool found = false;
    for(size_t i=0; i<noperands_; ++i) {
        if (!core::equivalent(*operands_[i], globals_[global_idx])) {
            continue; // Not equivalent, continue search.
        }
        // Found one! Use it instead of the incremented identifier.
        local_idx = i;
        found = true;
        break;
    }

    // Create the operand in block-scope
    if (!found) {
        local_idx = noperands_;
        operands_[local_idx] = &globals_[global_idx];
        ++noperands_;
    }

    //
    // Insert entry such that tac operands can be resolved in block-scope.
    global_to_local_.insert(pair<size_t,size_t>(global_idx, local_idx));
    local_to_global_.insert(pair<size_t,size_t>(local_idx, global_idx));

    // Maintain references to bases within the block.
    base_refs_[operands_[local_idx]->base].insert(global_idx);

    return local_idx;
}

bool Block::symbolize(void)
{
    stringstream tacs, operands_ss;

    //
    // Scope
    for(size_t i=0; i<noperands_; ++i) {
        operands_ss << "~" << i;
        operands_ss << core::layout_text_shand(operands_[i]->layout);
        operands_ss << core::etype_text_shand(operands_[i]->etype);

        // Let the "Restrictable" flag be part of the symbol.
        if (base_refs_[operands_[i]->base].size()==1) {
            operands_ss << "R";
        } else {
            operands_ss << "A";
        }
    }

    //
    // Program
    bool first = true;
    for(vector<tac_t*>::iterator tac_iter=tacs_.begin(); tac_iter!=tacs_.end(); ++tac_iter) {
        tac_t& tac = **tac_iter;

        // Do not include system opcodes in the kernel symbol.
        if ((tac.op == SYSTEM) || (tac.op == EXTENSION)) {
            continue;
        }
        if (!first) {   // Separate op+oper with "_"
            tacs  << "_";
        }
        first = false;

        tacs << core::operation_text(tac.op);
        tacs << "-" << core::operator_text(tac.oper);
        tacs << "-";
        size_t ndim = ((tac.op & (REDUCE_COMPLETE|REDUCE_PARTIAL))>0) ? globals_[tac.in1].ndim : globals_[tac.out].ndim;
        if (ndim <= 3) {
            tacs << ndim;
        } else {
            tacs << "N";
        }
        tacs << "D";

        switch(core::tac_noperands(tac)) {
            case 3:
                tacs << "_" << global_to_local(tac.out);
                tacs << "_" << global_to_local(tac.in1);
                tacs << "_" << global_to_local(tac.in2);
                break;

            case 2:
                tacs << "_" << global_to_local(tac.out);
                tacs << "_" << global_to_local(tac.in1);
                break;

            case 1:
                tacs << "_" << global_to_local(tac.out);
                break;

            case 0:
                break;

            default:
                fprintf(stderr, "Something horrible happened...\n");
        }
    }

    symbol_text_    = tacs.str() +"_"+ operands_ss.str();
    symbol_         = core::hash_text(symbol_text_);

    return true;
}

size_t Block::base_refcount(bh_base* base)
{
    return base_refs_[base].size();
}

operand_t& Block::operand(size_t local_idx)
{
    return *operands_[local_idx];
}

operand_t** Block::operands(void)
{
    return operands_;
}

size_t Block::noperands(void) const
{
    return noperands_;
}

size_t Block::global_to_local(size_t global_idx) const
{
    return global_to_local_.find(global_idx)->second;
}

size_t Block::local_to_global(size_t local_idx) const
{
    return local_to_global_.find(local_idx)->second;
}

tac_t& Block::tac(size_t idx) const
{
    return *tacs_[idx];
}

tac_t& Block::array_tac(size_t idx) const
{
    return *array_tacs_[idx];
}

uint32_t Block::omask(void)
{
    return omask_;
}

size_t Block::ntacs(void) const
{
    return tacs_.size();
}

size_t Block::narray_tacs(void) const
{
    return array_tacs_.size();
}

string Block::symbol(void) const
{
    return symbol_;
}

string Block::symbol_text(void) const
{
    return symbol_text_;
}

iterspace_t& Block::iterspace(void)
{
    return iterspace_;
}

void Block::update_iterspace(void)
{
    // NOTE: This stuff is only valid for SIJ, and FUSION, streaming
    //       will require another way to determine the iteration space.

    //
    // Determine layout, ndim and shape
    for(size_t tac_idx=0; tac_idx<ntacs(); ++tac_idx) {
        tac_t& tac = this->tac(tac_idx);
        if (not ((tac.op & (ARRAY_OPS))>0)) {   // Only interested in array ops
            continue;
        }
        if ((tac.op & (REDUCE_COMPLETE|REDUCE_PARTIAL))>0) {     // Reductions are weird
            if (globals_[tac.in1].layout >= iterspace_.layout) {
                iterspace_.layout = globals_[tac.in1].layout;
                iterspace_.ndim  = globals_[tac.in1].ndim;
                iterspace_.shape = globals_[tac.in1].shape;
            }
            if (globals_[tac.out].layout > iterspace_.layout) {
                iterspace_.layout = globals_[tac.out].layout;
            }
        } else {
            switch(tac_noperands(tac)) {
                case 3:
                    if (globals_[tac.in2].layout > iterspace_.layout) {
                        iterspace_.layout = globals_[tac.in2].layout;
                        if (iterspace_.layout > SCALAR_TEMP) {
                            iterspace_.ndim  = globals_[tac.in2].ndim;
                            iterspace_.shape = globals_[tac.in2].shape;
                        }
                    }
                case 2:
                    if (globals_[tac.in1].layout > iterspace_.layout) {
                        iterspace_.layout = globals_[tac.in1].layout;
                        if (iterspace_.layout > SCALAR_TEMP) {
                            iterspace_.ndim  = globals_[tac.in1].ndim;
                            iterspace_.shape = globals_[tac.in1].shape;
                        }
                    }
                case 1:
                    if (globals_[tac.out].layout > iterspace_.layout) {
                        iterspace_.layout = globals_[tac.out].layout;
                        if (iterspace_.layout > SCALAR_TEMP) {
                            iterspace_.ndim  = globals_[tac.out].ndim;
                            iterspace_.shape = globals_[tac.out].shape;
                        }
                    }
                default:
                    break;
            }
        }
    }

    if (NULL != iterspace_.shape) {             // Determine number of elements
        iterspace_.nelem = 1;
        for(int k=0; k<iterspace_.ndim; ++k) {
            iterspace_.nelem *= iterspace_.shape[k];
        }
    }
}

string Block::dot(void) const
{
    stringstream ss;
    return ss.str();
}

std::string Block::text_compact(void)
{
    stringstream ss;
    ss << setfill('0');
    ss << setw(3);
    ss << narray_tacs();
    ss << ",";
    ss << setfill(' ');
    ss << setw(36);
    ss << symbol();
    ss << ", ";
    ss << left;
    ss << setw(36);
    ss << setfill('-');
    ss << omask_aop_text(omask());
    ss << ", ";
    ss << left;
    ss << setfill('-');
    ss << setw(57);
    ss << iterspace_text(iterspace());

    return ss.str();
}

std::string Block::text(void)
{
    stringstream ss;
    ss << "BLOCK [" << symbol() << endl;
    ss << "TACS " << "omask(" << omask() << "), ntacs(" << ntacs() << ") {" << endl;
    for(uint64_t tac_idx=0; tac_idx<ntacs(); ++tac_idx) {
        ss << " " << tac_text(tac(tac_idx)) << endl;
    }
    ss << "}" << endl;

    ss << "OPERANDS (" << noperands() << ") {" << endl;
    for(size_t opr_idx=0; opr_idx < noperands(); ++opr_idx) {
        operand_t& opr = operand(opr_idx);
        ss << " loc_idx(" << opr_idx << ")";
        ss << " gbl_idx(" << local_to_global(opr_idx) << ") = ";
        ss << operand_text(opr);
        ss << endl;
    }
    ss << "}" << endl;

    ss << "BASE_REFS {" << endl;
    for(std::map<bh_base*, std::set<uint64_t> >::iterator it=base_refs_.begin();
        it!=base_refs_.end();
        ++it) {
        std::set<uint64_t>& op_bases = it->second;
        ss << " " << it->first << " = ";
        for(std::set<uint64_t>::iterator oit=op_bases.begin();
            oit != op_bases.end();
            oit++) {
            ss << *oit << ", ";
        }
        ss << endl;
    }
    ss << "}" << endl;

    ss << "ITERSPACE {" << endl;
    ss << " LAYOUT = " << layout_text(iterspace_.layout) << "," << endl;
    ss << " NDIM   = " << iterspace_.ndim << "," << endl;
    ss << " SHAPE  = {";
    for(int64_t dim=0; dim < iterspace_.ndim; ++dim) {
        ss << iterspace_.shape[dim];
        if (dim != (iterspace_.ndim-1)) {
            ss << ", ";
        }
    }
    ss << "}" << endl;
    ss << " NELEM  = " << iterspace_.nelem << endl;
    ss << "}" << endl;
    ss << "]" << endl;
    return ss.str();
}

}}
<commit_msg>cpu: Added INNER/AXIS to block symbol.<commit_after>#include "block.hpp"
#include <iomanip>

using namespace std;
using namespace boost;

namespace bohrium{
namespace core{

const char Block::TAG[] = "Block";

Block::Block(SymbolTable& globals, vector<tac_t>& program)
: globals_(globals), program_(program), operands_(NULL), noperands_(0), symbol_text_(""), symbol_(""), omask_(0)
{}

Block::~Block()
{
    if (operands_) {
        delete[] operands_;
        operands_   = NULL;
        noperands_  = 0;
    }
}

void Block::clear(void)
{                               // Reset the current state of the block
    tacs_.clear();              // tacs
    array_tacs_.clear();        // array_tacs
    base_refs_.clear();

    omask_ = 0;

    iterspace_.layout = SCALAR_TEMP; // iteraton space
    iterspace_.ndim = 0;
    iterspace_.shape = NULL;
    iterspace_.nelem = 0;

    if (operands_) {            // operands
        delete[] operands_;
        operands_   = NULL;
        noperands_  = 0;
    }
    global_to_local_.clear();   // global to local operand mapping
    local_to_global_.clear();   // local to global operand mapping

    symbol_text_    = "";       // textual symbol representation
    symbol_         = "";       // hashed symbol representation
}

void Block::compose(bh_ir_kernel& krnl)
{
    // An array pointers to operands
    // Will be handed to the kernel-function.
    operands_ = new operand_t*[krnl.instr_indexes.size()*3];

    for(std::vector<uint64_t>::iterator idx_it = krnl.instr_indexes.begin();
        idx_it != krnl.instr_indexes.end();
        ++idx_it) {

        tac_t& tac = program_[*idx_it];

        tacs_.push_back(&tac);              // <-- All tacs
        omask_ |= tac.op;                   // Update omask

        if ((tac.op & (ARRAY_OPS))>0) {
            array_tacs_.push_back(&tac);    // <-- Only array operations
        }

        // Map operands to local-scope
        switch(tac_noperands(tac)) {
            case 3:
                localize(tac.in2);
            case 2:
                localize(tac.in1);
            case 1:
                localize(tac.out);
            default:
                break;
        }
    }
}

void Block::compose(size_t prg_begin, size_t prg_end)
{
    // An array pointers to operands
    // Will be handed to the kernel-function.
    operands_ = new operand_t*[(prg_end-prg_begin+1)*3];

    for(size_t prg_idx=prg_begin; prg_idx<=prg_end; ++prg_idx) {
        tac_t& tac = program_[prg_idx];

        tacs_.push_back(&tac);              // <-- All tacs
        omask_ |= tac.op;                   // Update omask

        if ((tac.op & (ARRAY_OPS))>0) {
            array_tacs_.push_back(&tac);    // <-- Only array operations
        }

        // Map operands to local-scope
        switch(tac_noperands(tac)) {
            case 3:
                localize(tac.in2);
            case 2:
                localize(tac.in1);
            case 1:
                localize(tac.out);
            default:
                break;
        }
    }
}

size_t Block::localize(size_t global_idx)
{
    //
    // Reuse operand identifiers: Detect if we have seen it before and reuse the index.
    size_t local_idx = 0;
    bool found = false;
    for(size_t i=0; i<noperands_; ++i) {
        if (!core::equivalent(*operands_[i], globals_[global_idx])) {
            continue; // Not equivalent, continue search.
        }
        // Found one! Use it instead of the incremented identifier.
        local_idx = i;
        found = true;
        break;
    }

    // Create the operand in block-scope
    if (!found) {
        local_idx = noperands_;
        operands_[local_idx] = &globals_[global_idx];
        ++noperands_;
    }

    //
    // Insert entry such that tac operands can be resolved in block-scope.
    global_to_local_.insert(pair<size_t,size_t>(global_idx, local_idx));
    local_to_global_.insert(pair<size_t,size_t>(local_idx, global_idx));

    // Maintain references to bases within the block.
    base_refs_[operands_[local_idx]->base].insert(global_idx);

    return local_idx;
}

bool Block::symbolize(void)
{
    stringstream tacs, operands_ss;

    //
    // Scope
    for(size_t i=0; i<noperands_; ++i) {
        operands_ss << "~" << i;
        operands_ss << core::layout_text_shand(operands_[i]->layout);
        operands_ss << core::etype_text_shand(operands_[i]->etype);

        // Let the "Restrictable" flag be part of the symbol.
        if (base_refs_[operands_[i]->base].size()==1) {
            operands_ss << "R";
        } else {
            operands_ss << "A";
        }
    }

    //
    // Program
    bool first = true;
    for(vector<tac_t*>::iterator tac_iter=tacs_.begin(); tac_iter!=tacs_.end(); ++tac_iter) {
        tac_t& tac = **tac_iter;

        // Do not include system opcodes in the kernel symbol.
        if ((tac.op == SYSTEM) || (tac.op == EXTENSION)) {
            continue;
        }
        if (!first) {   // Separate op+oper with "_"
            tacs  << "_";
        }
        first = false;

        tacs << core::operation_text(tac.op);

        size_t ndim = ((tac.op & (REDUCE_COMPLETE|REDUCE_PARTIAL))>0) ? globals_[tac.in1].ndim : globals_[tac.out].ndim;

        //
        // Adding info of whether the kernel does reduction on the inner-most
        // dimensions or another "axis" dimension.
        //
        if ((tac.op & REDUCE_PARTIAL)>0) {
            if (*((uint64_t*)globals_[tac.in2].const_data) == (ndim-1)) {
                tacs << "-INNER";
            } else {
                tacs << "-AXIS";
            }
        }

        //
        // Add ndim up to 3
        //
        tacs << "-" << core::operator_text(tac.oper);
        tacs << "-";
        if (ndim <= 3) {
            tacs << ndim;
        } else {
            tacs << "N";
        }
        tacs << "D";

        // Add operand IDs
        switch(core::tac_noperands(tac)) {
            case 3:
                tacs << "_" << global_to_local(tac.out);
                tacs << "_" << global_to_local(tac.in1);
                tacs << "_" << global_to_local(tac.in2);
                break;

            case 2:
                tacs << "_" << global_to_local(tac.out);
                tacs << "_" << global_to_local(tac.in1);
                break;

            case 1:
                tacs << "_" << global_to_local(tac.out);
                break;

            case 0:
                break;

            default:
                fprintf(stderr, "Something horrible happened...\n");
        }
    }

    symbol_text_    = tacs.str() +"_"+ operands_ss.str();
    symbol_         = core::hash_text(symbol_text_);

    return true;
}

size_t Block::base_refcount(bh_base* base)
{
    return base_refs_[base].size();
}

operand_t& Block::operand(size_t local_idx)
{
    return *operands_[local_idx];
}

operand_t** Block::operands(void)
{
    return operands_;
}

size_t Block::noperands(void) const
{
    return noperands_;
}

size_t Block::global_to_local(size_t global_idx) const
{
    return global_to_local_.find(global_idx)->second;
}

size_t Block::local_to_global(size_t local_idx) const
{
    return local_to_global_.find(local_idx)->second;
}

tac_t& Block::tac(size_t idx) const
{
    return *tacs_[idx];
}

tac_t& Block::array_tac(size_t idx) const
{
    return *array_tacs_[idx];
}

uint32_t Block::omask(void)
{
    return omask_;
}

size_t Block::ntacs(void) const
{
    return tacs_.size();
}

size_t Block::narray_tacs(void) const
{
    return array_tacs_.size();
}

string Block::symbol(void) const
{
    return symbol_;
}

string Block::symbol_text(void) const
{
    return symbol_text_;
}

iterspace_t& Block::iterspace(void)
{
    return iterspace_;
}

void Block::update_iterspace(void)
{
    // NOTE: This stuff is only valid for SIJ, and FUSION, streaming
    //       will require another way to determine the iteration space.

    //
    // Determine layout, ndim and shape
    for(size_t tac_idx=0; tac_idx<ntacs(); ++tac_idx) {
        tac_t& tac = this->tac(tac_idx);
        if (not ((tac.op & (ARRAY_OPS))>0)) {   // Only interested in array ops
            continue;
        }
        if ((tac.op & (REDUCE_COMPLETE|REDUCE_PARTIAL))>0) {     // Reductions are weird
            if (globals_[tac.in1].layout >= iterspace_.layout) {
                iterspace_.layout = globals_[tac.in1].layout;
                iterspace_.ndim  = globals_[tac.in1].ndim;
                iterspace_.shape = globals_[tac.in1].shape;
            }
            if (globals_[tac.out].layout > iterspace_.layout) {
                iterspace_.layout = globals_[tac.out].layout;
            }
        } else {
            switch(tac_noperands(tac)) {
                case 3:
                    if (globals_[tac.in2].layout > iterspace_.layout) {
                        iterspace_.layout = globals_[tac.in2].layout;
                        if (iterspace_.layout > SCALAR_TEMP) {
                            iterspace_.ndim  = globals_[tac.in2].ndim;
                            iterspace_.shape = globals_[tac.in2].shape;
                        }
                    }
                case 2:
                    if (globals_[tac.in1].layout > iterspace_.layout) {
                        iterspace_.layout = globals_[tac.in1].layout;
                        if (iterspace_.layout > SCALAR_TEMP) {
                            iterspace_.ndim  = globals_[tac.in1].ndim;
                            iterspace_.shape = globals_[tac.in1].shape;
                        }
                    }
                case 1:
                    if (globals_[tac.out].layout > iterspace_.layout) {
                        iterspace_.layout = globals_[tac.out].layout;
                        if (iterspace_.layout > SCALAR_TEMP) {
                            iterspace_.ndim  = globals_[tac.out].ndim;
                            iterspace_.shape = globals_[tac.out].shape;
                        }
                    }
                default:
                    break;
            }
        }
    }

    if (NULL != iterspace_.shape) {             // Determine number of elements
        iterspace_.nelem = 1;
        for(int k=0; k<iterspace_.ndim; ++k) {
            iterspace_.nelem *= iterspace_.shape[k];
        }
    }
}

string Block::dot(void) const
{
    stringstream ss;
    return ss.str();
}

std::string Block::text_compact(void)
{
    stringstream ss;
    ss << setfill('0');
    ss << setw(3);
    ss << narray_tacs();
    ss << ",";
    ss << setfill(' ');
    ss << setw(36);
    ss << symbol();
    ss << ", ";
    ss << left;
    ss << setw(36);
    ss << setfill('-');
    ss << omask_aop_text(omask());
    ss << ", ";
    ss << left;
    ss << setfill('-');
    ss << setw(57);
    ss << iterspace_text(iterspace());

    return ss.str();
}

std::string Block::text(void)
{
    stringstream ss;
    ss << "BLOCK [" << symbol() << endl;
    ss << "TACS " << "omask(" << omask() << "), ntacs(" << ntacs() << ") {" << endl;
    for(uint64_t tac_idx=0; tac_idx<ntacs(); ++tac_idx) {
        ss << " " << tac_text(tac(tac_idx)) << endl;
    }
    ss << "}" << endl;

    ss << "OPERANDS (" << noperands() << ") {" << endl;
    for(size_t opr_idx=0; opr_idx < noperands(); ++opr_idx) {
        operand_t& opr = operand(opr_idx);
        ss << " loc_idx(" << opr_idx << ")";
        ss << " gbl_idx(" << local_to_global(opr_idx) << ") = ";
        ss << operand_text(opr);
        ss << endl;
    }
    ss << "}" << endl;

    ss << "BASE_REFS {" << endl;
    for(std::map<bh_base*, std::set<uint64_t> >::iterator it=base_refs_.begin();
        it!=base_refs_.end();
        ++it) {
        std::set<uint64_t>& op_bases = it->second;
        ss << " " << it->first << " = ";
        for(std::set<uint64_t>::iterator oit=op_bases.begin();
            oit != op_bases.end();
            oit++) {
            ss << *oit << ", ";
        }
        ss << endl;
    }
    ss << "}" << endl;

    ss << "ITERSPACE {" << endl;
    ss << " LAYOUT = " << layout_text(iterspace_.layout) << "," << endl;
    ss << " NDIM   = " << iterspace_.ndim << "," << endl;
    ss << " SHAPE  = {";
    for(int64_t dim=0; dim < iterspace_.ndim; ++dim) {
        ss << iterspace_.shape[dim];
        if (dim != (iterspace_.ndim-1)) {
            ss << ", ";
        }
    }
    ss << "}" << endl;
    ss << " NELEM  = " << iterspace_.nelem << endl;
    ss << "}" << endl;
    ss << "]" << endl;
    return ss.str();
}

}}
<|endoftext|>


<commit_before>//
// Copyright (c) articy Software GmbH & Co. KG. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

#include "Slate/UserInterfaceHelperFunctions.h"
#include "ArticyObject.h"
#include "Interfaces/ArticyObjectWithPreviewImage.h"
#include "ArticyAsset.h"
#include "Interfaces/ArticyObjectWithSpeaker.h"
#include "Interfaces/ArticyObjectWithDisplayName.h"
#include "Interfaces/ArticyObjectWithText.h"
#include "Kismet/KismetStringLibrary.h"
#include "ArticyImportData.h"
#include "ArticyImporterStyle.h"
#include "ArticyFlowClasses.h"
#include "ArticyEntity.h"
#include "Interfaces/ArticyObjectWithColor.h"

const FSlateBrush* UserInterfaceHelperFunctions::GetArticyTypeImage(const UArticyObject* ArticyObject, UserInterfaceHelperFunctions::EImageSize Size)
{
	if(!ArticyObject)
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.ArticyApplication.64")));
	}

	FString SizeString = "";
	if(Size == EImageSize::Large)
	{
		SizeString.Append("64");
	}
	else if(Size == EImageSize::Medium)
	{
		SizeString.Append("32");
	}
	else
	{
		SizeString.Append("16");
	}

	if(ArticyObject->IsA<UArticyDialogueFragment>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.DialogueFragment.").Append(SizeString)));
	}
	else if(ArticyObject->IsA<UArticyDialogue>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Dialogue.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyEntity>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Entity.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyFlowFragment>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.FlowFragment.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyHub>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Hub.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyJump>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Jump.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyInstruction>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Instruction.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyCondition>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Condition.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyAsset>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Asset.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyUserFolder>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.UserFolder.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyZone>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Zone.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLocation>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Location.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLocationImage>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.LocationImage.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLocationText>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.LocationText.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLink>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Link.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyComment>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Comment.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyTextObject>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.TextObject.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyPath>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Path.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyDocument>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Document.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticySpot>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Spot.").Append(SizeString)));
	}

	return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.ArticyApplication.64")));
}

UTexture2D* UserInterfaceHelperFunctions::GetDisplayImage(const UArticyObject* ArticyObject)
{
	UTexture2D* Image = nullptr;

	if (!ArticyObject)
	{
		return Image;
	}

	// if there is a preview image, use it as display image
	const IArticyObjectWithPreviewImage* ObjectWithPreviewImage = Cast<IArticyObjectWithPreviewImage>(ArticyObject);
	if (ObjectWithPreviewImage)
	{
		const FArticyId AssetID = ObjectWithPreviewImage->GetPreviewImage()->Asset;
		const UArticyObject* AssetObject = UArticyObject::FindAsset(AssetID);

		if (AssetObject)
		{
			Image = (Cast<UArticyAsset>(AssetObject))->LoadAsTexture2D();
			return Image;
		}
	}

	return Image;
}

bool UserInterfaceHelperFunctions::RetrievePreviewImage(const UArticyObject* ArticyObject, FSlateBrush& OutSlateBrush)
{
	UTexture2D* PreviewImage = GetDisplayImage(ArticyObject);

	if(PreviewImage)
	{
		OutSlateBrush.SetResourceObject(PreviewImage);
		return true;
	}

	return false;
}

bool UserInterfaceHelperFunctions::RetrieveSpeakerPreviewImage(const UArticyObject* ArticyObject, FSlateBrush& OutSlateBrush)
{
	const IArticyObjectWithSpeaker* ArticyObjectWithSpeaker = Cast<IArticyObjectWithSpeaker>(ArticyObject);

	if(ArticyObjectWithSpeaker)
	{
		UArticyObject* Speaker = UArticyObject::FindAsset(ArticyObjectWithSpeaker->GetSpeakerId());
		return RetrievePreviewImage(Speaker, OutSlateBrush);
	}

	return false;
}

const FArticyId* UserInterfaceHelperFunctions::GetTargetID(const UArticyObject* ArticyObject)
{
	static const auto PropName = FName("Target");
	UProperty* Prop = ArticyObject->GetProperty(PropName);

	if(!Prop)
	{
		return nullptr;
	}

	const FArticyId* TargetID = Prop->ContainerPtrToValuePtr<FArticyId>(ArticyObject);

	if(TargetID)
	{
		return TargetID;
	}

	return nullptr;
}

const FString UserInterfaceHelperFunctions::GetDisplayName(const UArticyObject* ArticyObject)
{
	FString DisplayName = "None";

	if (!ArticyObject)
	{
		return DisplayName;
	}

	const FArticyId* TargetID = UserInterfaceHelperFunctions::GetTargetID(ArticyObject);
	if (TargetID)
	{
		const UArticyObject* TargetObject = UArticyObject::FindAsset(*TargetID);

		if (TargetObject)
		{
			return GetDisplayName(TargetObject);
		}
	}

	// use the display name as display name, if available
	const IArticyObjectWithDisplayName* ArticyObjectWithDisplayName = Cast<IArticyObjectWithDisplayName>(ArticyObject);
	if (ArticyObjectWithDisplayName)
	{
		 DisplayName = ArticyObjectWithDisplayName->GetDisplayName().ToString();

		if (!DisplayName.IsEmpty())
		{
			return DisplayName;
		}
	}

	// use a text preview as display name, if available
	const IArticyObjectWithText* ArticyObjectWithText = Cast<IArticyObjectWithText>(ArticyObject);
	if (ArticyObjectWithText)
	{
		const FText Text = ArticyObjectWithText->GetText();

		// cut the string to the first X characters and attach "..." as a preview
		// primarily used for dialogue fragments, as they have neither preview image nor display name
		if (!Text.IsEmpty())
		{
			DisplayName = Text.ToString();
			DisplayName = UKismetStringLibrary::GetSubstring(DisplayName, 0, 14);

			if (Text.ToString().Len() > 14)
			{
				DisplayName.Append("...");
			}

			return DisplayName;
		}
	}

	return DisplayName;
}

const FLinearColor UserInterfaceHelperFunctions::GetColor(const UArticyObject* ArticyObject)
{
	FLinearColor Color(0.577, 0.76, 0.799);

	if (!ArticyObject)
	{
		return Color;
	}

	const FArticyId* TargetID = UserInterfaceHelperFunctions::GetTargetID(ArticyObject);

	if (TargetID)
	{
		const UArticyObject* TargetObject = UArticyObject::FindAsset(*TargetID);

		if (TargetObject)
		{
			return GetColor(TargetObject);
		}
	}

	const IArticyObjectWithColor* ObjectWithColor = Cast<IArticyObjectWithColor>(ArticyObject);
	if(ObjectWithColor)
	{
		Color = ObjectWithColor->GetColor();
		return Color;
	}

	return Color;
}

const bool UserInterfaceHelperFunctions::ShowObjectInArticy(const UArticyObject* ArticyObject)
{
	if(ArticyObject== nullptr)
	{
		return false;
	}
	FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");

	TArray<FAssetData> OutAssetData;
	AssetRegistryModule.Get().GetAssetsByClass(UArticyImportData::StaticClass()->GetFName(), OutAssetData, false);

	if(OutAssetData.Num() == 1)
	{
		UArticyImportData* ImportData = Cast<UArticyImportData>(OutAssetData[0].GetAsset());
		FString ProjectGuid = ImportData->GetProject().Guid;

		FArticyId ArticyId = ArticyObject->GetId();

		// restore the original Id in decimal
		const int32 High = ArticyId.High;
		const int32 Low = ArticyId.Low;
		const uint64 HighOriginal = (uint64) High <<  32;
		const uint64 LowOriginal = Low;
		const uint64 OriginalId = HighOriginal + LowOriginal;

		FString ArticyObjectId = FString::Printf(TEXT("%llu"), OriginalId);
		FString ArticyURL = FString::Printf(TEXT("articy://localhost/view/%s/%s?pane=selected&tab=current"), *ProjectGuid, *ArticyObjectId);
		UKismetSystemLibrary::LaunchURL(ArticyURL);
	}

	return true;
}
<commit_msg>Added sanity check for GetTargetID function<commit_after>//
// Copyright (c) articy Software GmbH & Co. KG. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

#include "Slate/UserInterfaceHelperFunctions.h"
#include "ArticyObject.h"
#include "Interfaces/ArticyObjectWithPreviewImage.h"
#include "ArticyAsset.h"
#include "Interfaces/ArticyObjectWithSpeaker.h"
#include "Interfaces/ArticyObjectWithDisplayName.h"
#include "Interfaces/ArticyObjectWithText.h"
#include "Kismet/KismetStringLibrary.h"
#include "ArticyImportData.h"
#include "ArticyImporterStyle.h"
#include "ArticyFlowClasses.h"
#include "ArticyEntity.h"
#include "Interfaces/ArticyObjectWithColor.h"

const FSlateBrush* UserInterfaceHelperFunctions::GetArticyTypeImage(const UArticyObject* ArticyObject, UserInterfaceHelperFunctions::EImageSize Size)
{
	if(!ArticyObject)
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.ArticyApplication.64")));
	}

	FString SizeString = "";
	if(Size == EImageSize::Large)
	{
		SizeString.Append("64");
	}
	else if(Size == EImageSize::Medium)
	{
		SizeString.Append("32");
	}
	else
	{
		SizeString.Append("16");
	}

	if(ArticyObject->IsA<UArticyDialogueFragment>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.DialogueFragment.").Append(SizeString)));
	}
	else if(ArticyObject->IsA<UArticyDialogue>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Dialogue.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyEntity>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Entity.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyFlowFragment>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.FlowFragment.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyHub>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Hub.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyJump>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Jump.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyInstruction>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Instruction.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyCondition>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Condition.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyAsset>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Asset.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyUserFolder>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.UserFolder.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyZone>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Zone.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLocation>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Location.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLocationImage>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.LocationImage.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLocationText>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.LocationText.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyLink>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Link.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyComment>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Comment.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyTextObject>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.TextObject.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyPath>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Path.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticyDocument>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Document.").Append(SizeString)));
	}
	else if (ArticyObject->IsA<UArticySpot>())
	{
		return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.Type.Spot.").Append(SizeString)));
	}

	return FArticyImporterStyle::Get().GetBrush(FName(*FString("ArticyImporter.ArticyApplication.64")));
}

UTexture2D* UserInterfaceHelperFunctions::GetDisplayImage(const UArticyObject* ArticyObject)
{
	UTexture2D* Image = nullptr;

	if (!ArticyObject)
	{
		return Image;
	}

	// if there is a preview image, use it as display image
	const IArticyObjectWithPreviewImage* ObjectWithPreviewImage = Cast<IArticyObjectWithPreviewImage>(ArticyObject);
	if (ObjectWithPreviewImage)
	{
		const FArticyId AssetID = ObjectWithPreviewImage->GetPreviewImage()->Asset;
		const UArticyObject* AssetObject = UArticyObject::FindAsset(AssetID);

		if (AssetObject)
		{
			Image = (Cast<UArticyAsset>(AssetObject))->LoadAsTexture2D();
			return Image;
		}
	}

	return Image;
}

bool UserInterfaceHelperFunctions::RetrievePreviewImage(const UArticyObject* ArticyObject, FSlateBrush& OutSlateBrush)
{
	UTexture2D* PreviewImage = GetDisplayImage(ArticyObject);

	if(PreviewImage)
	{
		OutSlateBrush.SetResourceObject(PreviewImage);
		return true;
	}

	return false;
}

bool UserInterfaceHelperFunctions::RetrieveSpeakerPreviewImage(const UArticyObject* ArticyObject, FSlateBrush& OutSlateBrush)
{
	const IArticyObjectWithSpeaker* ArticyObjectWithSpeaker = Cast<IArticyObjectWithSpeaker>(ArticyObject);

	if(ArticyObjectWithSpeaker)
	{
		UArticyObject* Speaker = UArticyObject::FindAsset(ArticyObjectWithSpeaker->GetSpeakerId());
		return RetrievePreviewImage(Speaker, OutSlateBrush);
	}

	return false;
}

const FArticyId* UserInterfaceHelperFunctions::GetTargetID(const UArticyObject* ArticyObject)
{
	if(!ArticyObject)
	{
		return nullptr;
	}

	static const auto PropName = FName("Target");
	UProperty* Prop = ArticyObject->GetProperty(PropName);

	if(!Prop)
	{
		return nullptr;
	}

	const FArticyId* TargetID = Prop->ContainerPtrToValuePtr<FArticyId>(ArticyObject);

	if(TargetID)
	{
		return TargetID;
	}

	return nullptr;
}

const FString UserInterfaceHelperFunctions::GetDisplayName(const UArticyObject* ArticyObject)
{
	FString DisplayName = "None";

	if (!ArticyObject)
	{
		return DisplayName;
	}

	const FArticyId* TargetID = UserInterfaceHelperFunctions::GetTargetID(ArticyObject);
	if (TargetID)
	{
		const UArticyObject* TargetObject = UArticyObject::FindAsset(*TargetID);

		if (TargetObject)
		{
			return GetDisplayName(TargetObject);
		}
	}

	// use the display name as display name, if available
	const IArticyObjectWithDisplayName* ArticyObjectWithDisplayName = Cast<IArticyObjectWithDisplayName>(ArticyObject);
	if (ArticyObjectWithDisplayName)
	{
		 DisplayName = ArticyObjectWithDisplayName->GetDisplayName().ToString();

		if (!DisplayName.IsEmpty())
		{
			return DisplayName;
		}
	}

	// use a text preview as display name, if available
	const IArticyObjectWithText* ArticyObjectWithText = Cast<IArticyObjectWithText>(ArticyObject);
	if (ArticyObjectWithText)
	{
		const FText Text = ArticyObjectWithText->GetText();

		// cut the string to the first X characters and attach "..." as a preview
		// primarily used for dialogue fragments, as they have neither preview image nor display name
		if (!Text.IsEmpty())
		{
			DisplayName = Text.ToString();
			DisplayName = UKismetStringLibrary::GetSubstring(DisplayName, 0, 14);

			if (Text.ToString().Len() > 14)
			{
				DisplayName.Append("...");
			}

			return DisplayName;
		}
	}

	return DisplayName;
}

const FLinearColor UserInterfaceHelperFunctions::GetColor(const UArticyObject* ArticyObject)
{
	FLinearColor Color(0.577, 0.76, 0.799);

	if (!ArticyObject)
	{
		return Color;
	}

	const FArticyId* TargetID = UserInterfaceHelperFunctions::GetTargetID(ArticyObject);

	if (TargetID)
	{
		const UArticyObject* TargetObject = UArticyObject::FindAsset(*TargetID);

		if (TargetObject)
		{
			return GetColor(TargetObject);
		}
	}

	const IArticyObjectWithColor* ObjectWithColor = Cast<IArticyObjectWithColor>(ArticyObject);
	if(ObjectWithColor)
	{
		Color = ObjectWithColor->GetColor();
		return Color;
	}

	return Color;
}

const bool UserInterfaceHelperFunctions::ShowObjectInArticy(const UArticyObject* ArticyObject)
{
	if(ArticyObject== nullptr)
	{
		return false;
	}
	FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");

	TArray<FAssetData> OutAssetData;
	AssetRegistryModule.Get().GetAssetsByClass(UArticyImportData::StaticClass()->GetFName(), OutAssetData, false);

	if(OutAssetData.Num() == 1)
	{
		UArticyImportData* ImportData = Cast<UArticyImportData>(OutAssetData[0].GetAsset());
		FString ProjectGuid = ImportData->GetProject().Guid;

		FArticyId ArticyId = ArticyObject->GetId();

		// restore the original Id in decimal
		const int32 High = ArticyId.High;
		const int32 Low = ArticyId.Low;
		const uint64 HighOriginal = (uint64) High <<  32;
		const uint64 LowOriginal = Low;
		const uint64 OriginalId = HighOriginal + LowOriginal;

		FString ArticyObjectId = FString::Printf(TEXT("%llu"), OriginalId);
		FString ArticyURL = FString::Printf(TEXT("articy://localhost/view/%s/%s?pane=selected&tab=current"), *ProjectGuid, *ArticyObjectId);
		UKismetSystemLibrary::LaunchURL(ArticyURL);
	}

	return true;
}
<|endoftext|>


<commit_before>#include "littletest.hpp"
#include <curl/curl.h>
#include "httpserver.hpp"

using namespace httpserver;

class simple_resource : public http_resource
{
    public:
        virtual void render_GET(const http_request& req, http_response** res)
        {
            *res = new http_string_response("OK", 200, "text/plain");
        }
};

LT_BEGIN_SUITE(basic_suite)

    webserver* ws;
    simple_resource* res;

    void set_up()
    {
        ws = new webserver(create_webserver(8080));
        res = new simple_resource();
        ws->register_resource("base", res);
        ws->start(false);
    }

    void tear_down()
    {
        ws->stop();
        delete ws;
        delete res;
    }
LT_END_SUITE(basic_suite)

LT_BEGIN_AUTO_TEST(basic_suite, read_body)
    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl = curl_easy_init();
    CURLcode res;
    curl_easy_setopt(curl, CURLOPT_URL, "localhost:8080/base");
    curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
    res = curl_easy_perform(curl);

    LT_ASSERT_EQ(res, 0);

LT_END_AUTO_TEST(read_body)

LT_BEGIN_AUTO_TEST_ENV()
    AUTORUN_TESTS()
LT_END_AUTO_TEST_ENV()
<commit_msg>Moved resource allocation inside test<commit_after>#include "littletest.hpp"
#include <curl/curl.h>
#include "httpserver.hpp"

using namespace httpserver;

class simple_resource : public http_resource
{
    public:
        virtual void render_GET(const http_request& req, http_response** res)
        {
            *res = new http_string_response("OK", 200, "text/plain");
        }
};

LT_BEGIN_SUITE(basic_suite)

    webserver* ws;
    simple_resource* res;

    void set_up()
    {
        ws = new webserver(create_webserver(8080));
        ws->start(false);
    }

    void tear_down()
    {
        ws->stop();
        delete ws;
        delete res;
    }
LT_END_SUITE(basic_suite)

LT_BEGIN_AUTO_TEST(basic_suite, read_body)
    res = new simple_resource();
    ws->register_resource("base", res);
    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl = curl_easy_init();
    CURLcode res;
    curl_easy_setopt(curl, CURLOPT_URL, "localhost:8080/base");
    curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
    res = curl_easy_perform(curl);

    LT_ASSERT_EQ(res, 0);

LT_END_AUTO_TEST(read_body)

LT_BEGIN_AUTO_TEST_ENV()
    AUTORUN_TESTS()
LT_END_AUTO_TEST_ENV()
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include <sys/stat.h>
#include <sys/resource.h>
#include <pwd.h>

#include "rhodes/JNIRhodes.h"
#include "common/AutoPointer.h"
#include "common/RhoStd.h"
#include "common/RhoConf.h"
#include "common/RhodesAppBase.h"
#include "common/app_build_capabilities.h"
#include "sqlite/sqlite3.h"
#include "logging/RhoLogConf.h"

//--------------------------------------------------------------------------------------------------
static rho::common::CAutoPtr<rho::common::AndroidLogSink> s_logSink(new rho::common::AndroidLogSink());
static rho::common::CAutoPtr<rho::common::AndroidMemoryInfoCollector> s_memory_info_collector(new rho::common::AndroidMemoryInfoCollector());

static rho::String s_root_path;
static rho::String s_sqlite_path;
static rho::String s_shared_path;
static rho::String s_log_path;

//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void android_set_path(const rho::String& root, const rho::String& sqlite, const rho::String& shared)
{
    s_root_path = root;
    s_sqlite_path = sqlite;
    s_shared_path = shared;
}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void android_set_log_path(const rho::String& path)
{
    s_log_path = path;
}
//--------------------------------------------------------------------------------------------------
rho::String const &rho_root_path()
{
    return s_root_path;
}
//--------------------------------------------------------------------------------------------------
rho::String const &rho_shared_path()
{
    return s_shared_path;
}
//--------------------------------------------------------------------------------------------------
const char* rho_native_rhopath()
{
    return rho_root_path().c_str();
}
//--------------------------------------------------------------------------------------------------
const char* rho_native_reruntimepath()
{
    return rho_root_path().c_str();
}
//--------------------------------------------------------------------------------------------------
rho::String rho_cur_path()
{
    char buf[PATH_MAX];
    if (::getcwd(buf, sizeof(buf)) == NULL)
        return "";
    return buf;
}
//--------------------------------------------------------------------------------------------------
rho::String rho_log_path()
{
    if (!s_log_path.empty())
    {
        return s_log_path;
    }
    else
    {
        return s_root_path;
    }
}
//--------------------------------------------------------------------------------------------------
static bool set_posix_environment(JNIEnv *env, jclass clsRE)
{
    // Set USER variable
    struct passwd *pwd = ::getpwuid(::getuid());
    if (!pwd)
    {
        env->ThrowNew(clsRE, "Can't find user name for current user");
        return false;
    }

    size_t len = ::strlen(pwd->pw_name) + 16;
    char *buf = (char *)::malloc(len + 1);
    buf[len] = '\0';
    ::snprintf(buf, len, "USER=%s", pwd->pw_name);
    int e = ::putenv(buf);
    ::free(buf);
    if (e != 0)
    {
        env->ThrowNew(clsRE, "Can't set USER environment variable");
        return false;
    }

    // Set HOME variable
    std::string root_path = rho_root_path();
    if (!root_path.empty() && root_path[root_path.size() - 1] == '/')
        root_path.erase(root_path.size() - 1);
    len = root_path.size() + 16;
    buf = (char *)::malloc(len + 1);
    buf[len] = '\0';
    ::snprintf(buf, len, "HOME=%s", root_path.c_str());
    e = ::putenv(buf);
    ::free(buf);
    if (e != 0)
    {
        env->ThrowNew(clsRE, "Can't set HOME environment variable");
        return false;
    }

    // Set TMP variable
    len = root_path.size() + 32;
    buf = (char *)::malloc(len + 1);
    buf[len] = '\0';
    ::snprintf(buf, len, "TMP=%s/tmp", root_path.c_str());
    e = ::putenv(buf);
    ::free(buf);
    if (e != 0)
    {
        env->ThrowNew(clsRE, "Can't set TMP environment variable");
        return false;
    }

    return true;
}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void android_setup(JNIEnv *env)
{
    jclass clsRE = getJNIClass(RHODES_JAVA_CLASS_RUNTIME_EXCEPTION);
    if (!clsRE)
        return;

    struct rlimit rlim;
    if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
    {
        env->ThrowNew(clsRE, "Can not get maximum number of open files");
        return;
    }
    if (rlim.rlim_max < (unsigned long)RHO_FD_BASE)
    {
        env->ThrowNew(clsRE, "Current limit of open files is less then RHO_FD_BASE");
        return;
    }
    if (rlim.rlim_cur > (unsigned long)RHO_FD_BASE)
    {
        rlim.rlim_cur = RHO_FD_BASE;
        rlim.rlim_max = RHO_FD_BASE;
        if (setrlimit(RLIMIT_NOFILE, &rlim) == -1)
        {
            env->ThrowNew(clsRE, "Can not set maximum number of open files");
            return;
        }
    }

    if (!set_posix_environment(env, clsRE)) return;

    if (::chdir(rho_root_path().c_str()) == -1)
    {
        env->ThrowNew(clsRE, "Can not chdir to HOME directory");
        return;
    }

    // Init SQLite temp directory
    sqlite3_temp_directory = (char*)s_sqlite_path.c_str();

    // Init logconf
    rho_logconf_Init(rho_log_path().c_str(), rho_root_path().c_str(), "");
    if (rho_root_path().compare(rho_shared_path()) != 0)
    {
        rho_conf_Init_from_shared_path(rho_shared_path().c_str());
    }

    // Disable log to stdout as on android all stdout redirects to /dev/null
    RHOCONF().setBool("LogToOutput", false, true);
    LOGCONF().setLogToOutput(false);
    // Add android system log sink
    LOGCONF().setLogView(s_logSink);

    LOGCONF().setMemoryInfoCollector(s_memory_info_collector);

}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void *rho_nativethread_start()
{
    JNIEnv *env;
    jvm()->AttachCurrentThread(&env, NULL);
    RAWTRACE2("Starting new thread - env: 0x%.8x, functions: 0x%.8x ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", env, env->functions);
    store_thr_jnienv(env);
    return NULL;
}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void rho_nativethread_end(void *)
{
    RAWTRACE1("Thread ended - env: 0x%.8x ===================================================", jnienv());
    jvm()->DetachCurrentThread();
    store_thr_jnienv(0);
}
//--------------------------------------------------------------------------------------------------
<commit_msg>EMBPD00169385 fix<commit_after>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include <sys/stat.h>
#include <sys/resource.h>
#include <pwd.h>

#include "rhodes/JNIRhodes.h"
#include "common/AutoPointer.h"
#include "common/RhoStd.h"
#include "common/RhoConf.h"
#include "common/RhodesAppBase.h"
#include "common/app_build_capabilities.h"
#include "sqlite/sqlite3.h"
#include "logging/RhoLogConf.h"

//--------------------------------------------------------------------------------------------------
static rho::common::CAutoPtr<rho::common::AndroidLogSink> s_logSink(new rho::common::AndroidLogSink());
static rho::common::CAutoPtr<rho::common::AndroidMemoryInfoCollector> s_memory_info_collector(new rho::common::AndroidMemoryInfoCollector());

static rho::String s_root_path;
static rho::String s_sqlite_path;
static rho::String s_shared_path;
static rho::String s_log_path;

//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void android_set_path(const rho::String& root, const rho::String& sqlite, const rho::String& shared)
{
    s_root_path = root;
    s_sqlite_path = sqlite;
    s_shared_path = shared;
}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void android_set_log_path(const rho::String& path)
{
    s_log_path = path;
}
//--------------------------------------------------------------------------------------------------
rho::String const &rho_root_path()
{
    return s_root_path;
}
//--------------------------------------------------------------------------------------------------
rho::String const &rho_shared_path()
{
    return s_shared_path;
}
//--------------------------------------------------------------------------------------------------
const char* rho_native_rhopath()
{
    return rho_root_path().c_str();
}
//--------------------------------------------------------------------------------------------------
const char* rho_native_reruntimepath()
{
    return rho_root_path().c_str();
}
//--------------------------------------------------------------------------------------------------
rho::String rho_cur_path()
{
    char buf[PATH_MAX];
    if (::getcwd(buf, sizeof(buf)) == NULL)
        return "";
    return buf;
}
//--------------------------------------------------------------------------------------------------
rho::String rho_log_path()
{
    if (!s_log_path.empty())
    {
        return s_log_path;
    }
    else
    {
        return s_root_path;
    }
}
//--------------------------------------------------------------------------------------------------
static bool set_posix_environment(JNIEnv *env, jclass clsRE)
{
    // Set USER variable
    struct passwd *pwd = ::getpwuid(::getuid());
    if (!pwd)
    {
        env->ThrowNew(clsRE, "Can't find user name for current user");
        return false;
    }

    size_t len = ::strlen(pwd->pw_name) + 16;
    char *buf = (char *)::malloc(len + 1);
    buf[len] = '\0';
    ::snprintf(buf, len, "USER=%s", pwd->pw_name);
    int e = ::putenv(buf);
    ::free(buf);
    if (e != 0)
    {
        env->ThrowNew(clsRE, "Can't set USER environment variable");
        return false;
    }

    // Set HOME variable
    std::string root_path = rho_root_path();
    if (!root_path.empty() && root_path[root_path.size() - 1] == '/')
        root_path.erase(root_path.size() - 1);
    len = root_path.size() + 16;
    buf = (char *)::malloc(len + 1);
    buf[len] = '\0';
    ::snprintf(buf, len, "HOME=%s", root_path.c_str());
    e = ::putenv(buf);
    ::free(buf);
    if (e != 0)
    {
        env->ThrowNew(clsRE, "Can't set HOME environment variable");
        return false;
    }

    // Set TMP variable
    len = root_path.size() + 32;
    buf = (char *)::malloc(len + 1);
    buf[len] = '\0';
    ::snprintf(buf, len, "TMP=%s/tmp", root_path.c_str());
    e = ::putenv(buf);
    ::free(buf);
    if (e != 0)
    {
        env->ThrowNew(clsRE, "Can't set TMP environment variable");
        return false;
    }

    return true;
}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void android_setup(JNIEnv *env)
{
    jclass clsRE = getJNIClass(RHODES_JAVA_CLASS_RUNTIME_EXCEPTION);
    if (!clsRE)
        return;

    // Init logconf
    rho_logconf_Init(rho_log_path().c_str(), rho_root_path().c_str(), "");
    if (rho_root_path().compare(rho_shared_path()) != 0)
    {
        rho_conf_Init_from_shared_path(rho_shared_path().c_str());
    }
  if(!(RHOCONF().isExist("useAssetFS")) || RHOCONF().getBool("useAssetFS")) {
    struct rlimit rlim;
    if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
    {
        env->ThrowNew(clsRE, "Can not get maximum number of open files");
        return;
    }
    if (rlim.rlim_max < (unsigned long)RHO_FD_BASE)
    {
        env->ThrowNew(clsRE, "Current limit of open files is less then RHO_FD_BASE");
        return;
    }
    if (rlim.rlim_cur > (unsigned long)RHO_FD_BASE)
    {
        rlim.rlim_cur = RHO_FD_BASE;
        rlim.rlim_max = RHO_FD_BASE;
        if (setrlimit(RLIMIT_NOFILE, &rlim) == -1)
        {
            env->ThrowNew(clsRE, "Can not set maximum number of open files");
            return;
        }
    }
  }

    if (!set_posix_environment(env, clsRE)) return;

    if (::chdir(rho_root_path().c_str()) == -1)
    {
        env->ThrowNew(clsRE, "Can not chdir to HOME directory");
        return;
    }

    // Init SQLite temp directory
    sqlite3_temp_directory = (char*)s_sqlite_path.c_str();

    // Disable log to stdout as on android all stdout redirects to /dev/null
    RHOCONF().setBool("LogToOutput", false, true);
    LOGCONF().setLogToOutput(false);
    // Add android system log sink
    LOGCONF().setLogView(s_logSink);

    LOGCONF().setMemoryInfoCollector(s_memory_info_collector);

}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void *rho_nativethread_start()
{
    JNIEnv *env;
    jvm()->AttachCurrentThread(&env, NULL);
    RAWTRACE2("Starting new thread - env: 0x%.8x, functions: 0x%.8x ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", env, env->functions);
    store_thr_jnienv(env);
    return NULL;
}
//--------------------------------------------------------------------------------------------------
RHO_GLOBAL void rho_nativethread_end(void *)
{
    RAWTRACE1("Thread ended - env: 0x%.8x ===================================================", jnienv());
    jvm()->DetachCurrentThread();
    store_thr_jnienv(0);
}
//-------------------
<|endoftext|>


<commit_before>//
//#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>
#include <algorithm>
#include <cmath>
#include "GPIOClass.h"

using namespace std;

void Pulse(GPIOClass* pin, double cycles);
void Wait(double seconds);
clock_t timer;
double time_to_complete;
double resolution = 100;

#define PI 4*atan(1)

int main (int argc, char *argv[]) {
	string type = argv[1];
	transform(type.begin(), type.end(), type.begin(), :: tolower);
	// lets assume that the way to run this is
	// pwm.exe [rising/falling/sine/constant]
	if (argc != 2) {
		cout << "Usage: pwm [rising/falling/sine/constant/blink]" << endl;
		return -1;
	}

	while (time_to_complete <= 0) {
		cout << "Input How Long To Run (in seconds)" << endl;
		cin >> time_to_complete;
	}

	GPIOClass* out1 = new GPIOClass("4");
	GPIOClass* in2 = new GPIOClass("17");

	out1->export_gpio();
	in2->export_gpio();

	out1->setdir_gpio("out");
	in2->setdir_gpio("in");

	cout << "Pins are setup." << endl;
	// avoiding flickering will be at 100hz
	// aka turn on and off 100 times a sec
	// a cycle of 0 is off
	// a cycle of 100 is on

	if (type == "rising") {
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		double t = time_to_complete;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			t -= 1;
			//Pulse(out1, sin((2PI/2) * abs(1/t)));
			//Wait(sin((PI/2) * abs(1/t)));
			Pulse(out1, sin((2*PI) * abs(1/t)));
			Wait(sin((2*PI) * abs(1/t)));
		}
	}
	if (type == "falling") {

	}
	if (type == "sine") {

	}
	if (type == "constant") {
		out1->setval_gpio("1"); // turn the pin on
		Wait(time_to_complete); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		out1->setval_gpio("0"); // turn the pin off
	}
	if (type == "blink") { // aka. TESTR
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			Pulse(out1, 1/resolution);
			Wait(4/resolution);
		}
	}
	cout << "Done." << endl;
}

//1 cycle is 1/100th of a second
//100 cycles is 1 sec
void Pulse(GPIOClass* pin, double cycles) {
	bool running = true;
	while (running) {
		pin->setval_gpio("1"); // turn the pin on
		Wait(cycles / resolution); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		pin->setval_gpio("0"); // turn the pin off
		running = false; // this is unnessesary but could be useful if modified a bit.
	}
}

void Wait ( double seconds )
{
	clock_t endwait;
	endwait = clock () + seconds * CLOCKS_PER_SEC ;
	while (clock() < endwait) {}
}
<commit_msg>Update pwm.cpp<commit_after>//
//#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>
#include <algorithm>
#include <cmath>
#include "GPIOClass.h"

using namespace std;

void Pulse(GPIOClass* pin, double cycles);
void Wait(double seconds);
clock_t timer;
double time_to_complete;
double resolution = 1000;

#define PI 4*atan(1)

int main (int argc, char *argv[]) {
	string type = argv[1];
	transform(type.begin(), type.end(), type.begin(), :: tolower);
	// lets assume that the way to run this is
	// pwm.exe [rising/falling/sine/constant]
	if (argc != 2) {
		cout << "Usage: pwm [rising/falling/sine/constant/blink]" << endl;
		return -1;
	}

	while (time_to_complete <= 0) {
		cout << "Input How Long To Run (in seconds)" << endl;
		cin >> time_to_complete;
	}

	GPIOClass* out1 = new GPIOClass("4");
	GPIOClass* in2 = new GPIOClass("17");

	out1->export_gpio();
	in2->export_gpio();

	out1->setdir_gpio("out");
	in2->setdir_gpio("in");

	cout << "Pins are setup." << endl;
	// avoiding flickering will be at 100hz
	// aka turn on and off 100 times a sec
	// a cycle of 0 is off
	// a cycle of 100 is on

	if (type == "rising") {
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		double t = time_to_complete;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			t -= 1;
			//Pulse(out1, sin((2PI/2) * abs(1/t)));
			//Wait(sin((PI/2) * abs(1/t)));
			Pulse(out1, sin((2*PI) * abs(1/t)));
			Wait(sin((2*PI) * abs(1/t)));
		}
	}
	if (type == "falling") {

	}
	if (type == "sine") {

	}
	if (type == "constant") {
		out1->setval_gpio("1"); // turn the pin on
		Wait(time_to_complete); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		out1->setval_gpio("0"); // turn the pin off
	}
	if (type == "blink") { // aka. TESTR
		clock_t finish = clock() + time_to_complete * CLOCKS_PER_SEC;
		while (clock() < finish) {
			// pulse for however long we need to to achieve brightness.
			Pulse(out1, 1/resolution);
			Wait(4/resolution);
		}
	}
	cout << "Done." << endl;
}

//1 cycle is 1/100th of a second
//100 cycles is 1 sec
void Pulse(GPIOClass* pin, double cycles) {
	bool running = true;
	while (running) {
		pin->setval_gpio("1"); // turn the pin on
		Wait(cycles / resolution); // sleep for number of cycles / 1/100 sec
		//cout << "Waiting during pulse" << endl;
		pin->setval_gpio("0"); // turn the pin off
		running = false; // this is unnessesary but could be useful if modified a bit.
	}
}

void Wait ( double seconds )
{
	clock_t endwait;
	endwait = clock () + seconds * CLOCKS_PER_SEC ;
	while (clock() < endwait) {}
}
<|endoftext|>