<commit_before>/**
 ** \file runner/runner.cc
 ** \brief Implementation of runner::Runner.
 */

//#define ENABLE_DEBUG_TRACES
#include "libport/compiler.hh"

#include <sstream>
#include <libport/foreach.hh>
#include <libport/symbol.hh>

#include "kernel/uconnection.hh"

#include "ast/clone.hh"
#include "object/atom.hh"
#include "object/urbi-exception.hh"
#include "object/idelegate.hh"
#include "runner/runner.hh"

namespace runner
{

/// Address of \a Runner seen as a \c Job (Runner has multiple inheritance).
#define JOB(Runner) static_cast<scheduler::Job*> (Runner)

/// Address of \c this seen as a \c Job (Runner has multiple inheritance).
#define ME JOB (this)

#define AST(Ast) "{{{" << Ast << "}}}"

/// Job echo.
#define JECHO(Title, Ast)                                       \
  ECHO ("job " << ME << ", " Title ": " << AST(Ast))

/** Call this macro at the very beginning of the evaluation of an AST
 * node.  Nodes that should yield are that doing something useful.  For
 * instance in "1;2" we have 3 nodes: two values in a Semicolon.  The
 * Semicolon does not do anything useful, it simply recurses in its
 * left hand side.  However, the "1" does something useful: it calculates
 * a value (even though calculating the constant "1" is somewhat trivial),
 * so it should most probably start with a YIELD.
 *
 * The Ast is expected to be named "e".  */
#define YIELD()                                 \
  do                                            \
  {                                             \
    ECHO ("job " << ME << " yielding on AST: "  \
          << &e << ' ' << AST(e));              \
    yield ();                                   \
  } while (0)

#define CATCH_FLOW_EXCEPTION(Type, Keyword, Error)              \
  catch (Type flow_exception)                                   \
  {                                                             \
    if (e.toplevel_get ())                                      \
    {                                                           \
      object::PrimitiveError error(Keyword, Error);             \
      error.location_set(flow_exception.location_get());        \
      raise_error_(error);                                      \
      continue;                                                 \
    }                                                           \
    else                                                        \
      throw;                                                    \
  }

  void
  Runner::raise_error_ (const object::UrbiException& ue)
  {
    std::ostringstream o;
    o << "!!! " << ue.location_get () << ": " << ue.what ();
    send_message_ ("error", o.str ());
    foreach(ast::Call* c, call_stack_)
    {
      o.str("");
      o << "!!!    called from: " << c->location_get () << ": "
	<< c->name_get ();
      send_message_ ("error", o.str ());
    }
    // Reset the current value: there was an error so whatever value it has,
    // it must not be used.
    current_.reset ();
  }

  void
  Runner::send_message_ (const std::string& tag, const std::string& msg)
  {
    UConnection& c = lobby_->value_get().connection;
    c << UConnection::send (msg.c_str(), tag.c_str()) << UConnection::endl;
  }

  void
  Runner::work ()
  {
    assert (ast_);

    ECHO ("job " << ME << " starting evaluation of AST: " << ast_
          << ' ' << AST(*ast_));
    operator() (*ast_);
  }

  /*---------------------.
  | Regular operator().  |
  `---------------------*/

  void
  Runner::operator() (ast::And& e)
  {
    // lhs will be evaluated in another Runner, while rhs will be evaluated
    // in this one.

    JECHO ("lhs", e.lhs_get ());
    Runner lhs (*this);
    lhs.ast_ = &e.lhs_get ();
    lhs.start_job ();

    PING ();

    JECHO ("rhs", e.rhs_get ());

    eval (e.rhs_get ());

    // Wait for lhs to terminate
    yield_until_terminated (lhs);

    PING ();

    current_ = object::void_class;
  }

  // Apply a function written in Urbi
  object::rObject
  Runner::apply_urbi (rObject scope, const rObject& func,
		      const object::objects_type& args)
  {
    // The called function.
    ast::Function* fn;
    // Effective (evaluated) argument iterator.
    object::objects_type::const_iterator ei;
    // Formal argument iterator.
    ast::symbols_type::const_iterator fi;

    PING ();
    // Create a new object to store the arguments unless a scope has been
    // given for this purpose.
    rObject bound_args;
    if (scope != object::nil_class)
      bound_args = scope;
    else
    {
      bound_args = new object::Object;
      bound_args->locals_set(true);
    }

    // Fetch the called function.
    fn = &func.cast<object::Code> ()->value_get ();

    // Check the arity.
    object::check_arg_count (fn->formals_get().size(), args.size() - 1,
			     "");

    // Bind formal and effective arguments if the caller has not provided
    // a scope. If a scope has been given, it is up to the caller to set
    // it up.
    ei = args.begin();
    if (scope == object::nil_class)
    {
      bound_args->slot_set (libport::Symbol("self"), *ei);
      // self is also the proto of the function outer scope, so that
      // we look for non-local identifiers in the target itself.
      bound_args->proto_add (*ei);
    }

    // Now bind the non-target arguments.
    ++ei;
    for (fi = fn->formals_get().begin();
	 fi != fn->formals_get().end() && ei != args.end();
	 ++fi, ++ei)
      bound_args->slot_set (**fi, *ei);
    ECHO("bound args: " << *bound_args);
    // Change the current context and call. But before, yield() so that
    // an infinite recursion gets a better chance to be detected.
    std::swap(bound_args, locals_);
    YIELD ();

    try {
      current_ = eval (*fn->body_get());
    }
    catch (ast::BreakException& be)
    {
      object::PrimitiveError error("break", "outside a loop");
      error.location_set(be.location_get());
      raise_error_(error);
    }
    catch (ast::ReturnException& re)
    {
      current_ = re.result_get();
    }
    catch (object::UrbiException& ue)
    {
      std::swap(bound_args, locals_);
      throw ue;
    };
    std::swap(bound_args, locals_);

    return current_;
  }

  object::rObject
  Runner::apply (rObject scope, const rObject& func,
                 const object::objects_type& args)
  {
    {
      // Check if any argument is void
      bool first = true;
      BOOST_FOREACH(rObject arg, args)
      {
	if (!first && arg == object::void_class)
	  throw object::WrongArgumentType ("");
	first = false;
      }
    }

    switch (func->kind_get ())
    {
      case object::Object::kind_primitive:
        PING ();
        current_ = func.cast<object::Primitive>()->value_get()(*this, args);
	break;
      case object::Object::kind_delegate:
        PING();
        current_ = func.cast<object::Delegate>()->value_get()
          ->operator()(*this, args);
	break;
      case object::Object::kind_code:
        PING ();
	current_ = apply_urbi (scope, func, args);
	break;
      default:
        PING ();
        current_ = func;
	break;
    }

    return current_;
  }

  void
  Runner::operator() (ast::Call& e)
  {
    /*-------------------------.
    | Evaluate the arguments.  |
    `-------------------------*/
    PING ();

    // Iterate over arguments, with a special case for the target.
    ast::exps_type::const_iterator i, i_end;
    i = e.args_get ().begin ();
    i_end = e.args_get ().end ();

    rObject tgt;
    tgt = target(*i);

    // No target?  Abort the call.  This can happen (for instance) when you
    // do a.b () and a does not exist (lookup error).
    if (!tgt)
      return;

    // Gather the arguments, including the target.
    object::objects_type args;
    args.push_back (tgt);
    PING ();
    for (++i; i != i_end; ++i)
    {
      eval (**i);
      passert ("argument without a value: " << **i, current_);
      if (current_ == object::void_class)
      {
	object::WrongArgumentType wt("");
	wt.location_set((*i)->location_get());
	throw wt;
      }
      PING ();
      args.push_back (current_);
    }

    /*---------------------.
    | Decode the message.  |
    `---------------------*/

    rObject val;

    // We may have to run a primitive, or some code.
    try {
      // Ask the target for the handler of the message.
      val = tgt->slot_get (e.name_get ());
    }
    catch (object::UrbiException& ue)
    {
      ue.location_set (e.location_get ());
      raise_error_ (ue);
      current_.reset ();
      return;
    }
    // FIXME: Do we need to issue an error message here?
    if (!val)
      return;
    call_stack_.push_front(&e);
    try {
      apply (object::nil_class, val, args);
    }
    catch (object::UrbiException& ue)
    {
      ue.location_set (e.location_get ());
      throw;
    };
    call_stack_.pop_front();

    // Because while returns 0, we can't have a call that returns 0
    // (a function that runs a while for instance).
    // passert ("no value: " << e, current_);
    ECHO (AST(e) << " result: " << *current_);
  }

  void
  Runner::operator() (ast::Float& e)
  {
    YIELD ();

    current_ = new object::Float (e.value_get());
    ECHO ("result: " << *current_);
  }

  void
  Runner::operator() (ast::Function& e)
  {
    YIELD ();

    PING ();
    current_ = new object::Code (*ast::clone(e));
  }

  void
  Runner::operator() (ast::If& e)
  {
    // Evaluate the test.
    JECHO ("test", e.test_get ());
    operator() (e.test_get());

    YIELD();

    if (IS_TRUE(current_))
    {
      JECHO ("then", e.thenclause_get ());
      operator() (e.thenclause_get());
    }
    else
    {
      JECHO ("else", e.elseclause_get ());
      operator() (e.elseclause_get());
    }
  }

  void
  Runner::operator() (ast::List& e)
  {
    typedef std::list<object::rObject> objects;
    typedef std::list<ast::Exp*> exps;
    // list values
    objects values;
    exps::const_iterator i;
    YIELD ();

    PING ();
    // Evaluate every expression in the list
    // FIXME: parallelized?
    for (i = e.value_get ().begin ();
         i != e.value_get ().end ();
         ++i)
    {
      operator() (**i);
      values.push_back(current_);
    }
    current_ = new object::List (values);
    ECHO ("result: " << *current_);
  }

  void
  Runner::operator() (ast::Nary& e)
  {
    // FIXME: other flavor support.
    ast::exec_exps_type::iterator i;
    current_ = object::void_class;
    for (i = e.children_get().begin(); i != e.children_get().end(); ++i)
    {
      current_.reset ();
      JECHO ("child", *i);
      try {
        operator() (*i);
      }
      catch (object::UrbiException& ue)
      {
        raise_error_ (ue);
        continue;
      }
      CATCH_FLOW_EXCEPTION(ast::BreakException, "break", "outside a loop")
        CATCH_FLOW_EXCEPTION(ast::ReturnException, "return",
                             "outside a function");

      if (e.toplevel_get () && current_.get ())
      {
        ECHO ("toplevel: returning a result to the connection.");
        lobby_->value_get ().connection.new_result (current_);
        current_.reset ();
      }

      /* Allow some time to pass before we execute what follows.  If
         we don't do this, the ;-operator would act almost like the
         |-operator because it would always start to execute its RHS
         immediately.  */
      YIELD ();
    }

    // FIXME: I am very afraid that because of the YIELD above, some
    // command are added right before this clear().  Hence the assert.
    assert (i == e.children_get().end());
    if (e.toplevel_get ())
      e.clear();
  }

  void
  Runner::operator() (ast::Noop&)
  {
    current_.reset ();
  }

  void
  Runner::operator() (ast::Pipe& e)
  {
    // lhs
    JECHO ("lhs", e.lhs_get ());
    operator() (e.lhs_get());

    // rhs:  start the execution immediately.
    JECHO ("rhs", e.rhs_get ());
    operator() (e.rhs_get());
  }

  void
  Runner::operator() (ast::Scope& e)
  {
    // To each scope corresponds a "locals" object which stores the
    // local variables.  It points to the previous current scope to
    // implement lexical scoping.
    rObject locals;
    rObject target;
    locals = new object::Object;
    locals->locals_set(true);
    // FIXME: is this the correct order? depends on getSlot algorithm.
    locals->proto_add (locals_);
    if (e.target_get())
    {
      target = eval(*e.target_get());
      // Be safe, do not inherit from VisibilityScope but copy the slots.
      rObject vscope = object::object_class->slot_get("VisibilityScope");
      locals->slot_set("setSlot", vscope->slot_get("setSlot"));
      locals->slot_set("updateSlot", vscope->slot_get("updateSlot"));
      locals->slot_set("self", target);
      locals->slot_set("__target", target);
      locals->proto_add(target);
    }

    std::swap(locals, locals_);
    super_type::operator()(e.body_get());
    std::swap(locals, locals_);
  }

  void
  Runner::operator() (ast::String& e)
  {
    YIELD ();

    PING ();
    current_ = new object::String(e.value_get());
    ECHO ("result: " << *current_);
  }

  void
  Runner::operator() (ast::Tag&)
  {
    // FIXME: Some code is missing here.
  }

  void
  Runner::operator() (ast::While& e)
  {
    bool broken;

    // Evaluate the test.
    while (true)
    {
      // FIXME: YIELD if second iteration for "while;".

      JECHO ("while test", e.test_get ());
      operator() (e.test_get());
      if (!IS_TRUE(current_))
        break;

      if (e.flavor_get() == ast::flavor_semicolon)
        YIELD();

      JECHO ("while body", e.body_get ());

      broken = false;
      try {
        operator() (e.body_get());
      }
      catch (ast::BreakException&)
      {
        // FIXME: Fix for flavor "," and "&".
        if (e.flavor_get() == ast::flavor_semicolon ||
            e.flavor_get() == ast::flavor_pipe)
          broken = true;
      };
      if (broken)
        break;
    }
    // As far as I know, `while' doesn't return a value in URBI.
    current_.reset ();
  }

  void
  Runner::operator() (ast::Throw& e)
  {
    if (e.kind_get() == ast::break_exception)
      throw ast::BreakException(e.location_get());
    else if (e.kind_get() == ast::return_exception)
    {
      if (e.value_get())
        operator() (*e.value_get());
      else
        current_.reset();
      throw ast::ReturnException(e.location_get(), current_);
    }
  }

  void
  Runner::operator() (ast::Stmt& e)
  {
    JECHO ("expression", e.expression_get ());
    operator() (e.expression_get());
  }

  void
  Runner::operator() (ast::Message& e)
  {
    send_message_(e.tag_get(), e.text_get());
  }

} // namespace runner
<commit_msg>Use foreach instead of BOOST_FOREACH<commit_after>/**
 ** \file runner/runner.cc
 ** \brief Implementation of runner::Runner.
 */

//#define ENABLE_DEBUG_TRACES
#include "libport/compiler.hh"

#include <sstream>
#include <libport/foreach.hh>
#include <libport/symbol.hh>

#include "kernel/uconnection.hh"

#include "ast/clone.hh"
#include "object/atom.hh"
#include "object/urbi-exception.hh"
#include "object/idelegate.hh"
#include "runner/runner.hh"

namespace runner
{

/// Address of \a Runner seen as a \c Job (Runner has multiple inheritance).
#define JOB(Runner) static_cast<scheduler::Job*> (Runner)

/// Address of \c this seen as a \c Job (Runner has multiple inheritance).
#define ME JOB (this)

#define AST(Ast) "{{{" << Ast << "}}}"

/// Job echo.
#define JECHO(Title, Ast)                                       \
  ECHO ("job " << ME << ", " Title ": " << AST(Ast))

/** Call this macro at the very beginning of the evaluation of an AST
 * node.  Nodes that should yield are that doing something useful.  For
 * instance in "1;2" we have 3 nodes: two values in a Semicolon.  The
 * Semicolon does not do anything useful, it simply recurses in its
 * left hand side.  However, the "1" does something useful: it calculates
 * a value (even though calculating the constant "1" is somewhat trivial),
 * so it should most probably start with a YIELD.
 *
 * The Ast is expected to be named "e".  */
#define YIELD()                                 \
  do                                            \
  {                                             \
    ECHO ("job " << ME << " yielding on AST: "  \
          << &e << ' ' << AST(e));              \
    yield ();                                   \
  } while (0)

#define CATCH_FLOW_EXCEPTION(Type, Keyword, Error)              \
  catch (Type flow_exception)                                   \
  {                                                             \
    if (e.toplevel_get ())                                      \
    {                                                           \
      object::PrimitiveError error(Keyword, Error);             \
      error.location_set(flow_exception.location_get());        \
      raise_error_(error);                                      \
      continue;                                                 \
    }                                                           \
    else                                                        \
      throw;                                                    \
  }

  void
  Runner::raise_error_ (const object::UrbiException& ue)
  {
    std::ostringstream o;
    o << "!!! " << ue.location_get () << ": " << ue.what ();
    send_message_ ("error", o.str ());
    foreach(ast::Call* c, call_stack_)
    {
      o.str("");
      o << "!!!    called from: " << c->location_get () << ": "
	<< c->name_get ();
      send_message_ ("error", o.str ());
    }
    // Reset the current value: there was an error so whatever value it has,
    // it must not be used.
    current_.reset ();
  }

  void
  Runner::send_message_ (const std::string& tag, const std::string& msg)
  {
    UConnection& c = lobby_->value_get().connection;
    c << UConnection::send (msg.c_str(), tag.c_str()) << UConnection::endl;
  }

  void
  Runner::work ()
  {
    assert (ast_);

    ECHO ("job " << ME << " starting evaluation of AST: " << ast_
          << ' ' << AST(*ast_));
    operator() (*ast_);
  }

  /*---------------------.
  | Regular operator().  |
  `---------------------*/

  void
  Runner::operator() (ast::And& e)
  {
    // lhs will be evaluated in another Runner, while rhs will be evaluated
    // in this one.

    JECHO ("lhs", e.lhs_get ());
    Runner lhs (*this);
    lhs.ast_ = &e.lhs_get ();
    lhs.start_job ();

    PING ();

    JECHO ("rhs", e.rhs_get ());

    eval (e.rhs_get ());

    // Wait for lhs to terminate
    yield_until_terminated (lhs);

    PING ();

    current_ = object::void_class;
  }

  // Apply a function written in Urbi
  object::rObject
  Runner::apply_urbi (rObject scope, const rObject& func,
		      const object::objects_type& args)
  {
    // The called function.
    ast::Function* fn;
    // Effective (evaluated) argument iterator.
    object::objects_type::const_iterator ei;
    // Formal argument iterator.
    ast::symbols_type::const_iterator fi;

    PING ();
    // Create a new object to store the arguments unless a scope has been
    // given for this purpose.
    rObject bound_args;
    if (scope != object::nil_class)
      bound_args = scope;
    else
    {
      bound_args = new object::Object;
      bound_args->locals_set(true);
    }

    // Fetch the called function.
    fn = &func.cast<object::Code> ()->value_get ();

    // Check the arity.
    object::check_arg_count (fn->formals_get().size(), args.size() - 1,
			     "");

    // Bind formal and effective arguments if the caller has not provided
    // a scope. If a scope has been given, it is up to the caller to set
    // it up.
    ei = args.begin();
    if (scope == object::nil_class)
    {
      bound_args->slot_set (libport::Symbol("self"), *ei);
      // self is also the proto of the function outer scope, so that
      // we look for non-local identifiers in the target itself.
      bound_args->proto_add (*ei);
    }

    // Now bind the non-target arguments.
    ++ei;
    for (fi = fn->formals_get().begin();
	 fi != fn->formals_get().end() && ei != args.end();
	 ++fi, ++ei)
      bound_args->slot_set (**fi, *ei);
    ECHO("bound args: " << *bound_args);
    // Change the current context and call. But before, yield() so that
    // an infinite recursion gets a better chance to be detected.
    std::swap(bound_args, locals_);
    YIELD ();

    try {
      current_ = eval (*fn->body_get());
    }
    catch (ast::BreakException& be)
    {
      object::PrimitiveError error("break", "outside a loop");
      error.location_set(be.location_get());
      raise_error_(error);
    }
    catch (ast::ReturnException& re)
    {
      current_ = re.result_get();
    }
    catch (object::UrbiException& ue)
    {
      std::swap(bound_args, locals_);
      throw ue;
    };
    std::swap(bound_args, locals_);

    return current_;
  }

  object::rObject
  Runner::apply (rObject scope, const rObject& func,
                 const object::objects_type& args)
  {
    {
      // Check if any argument is void
      bool first = true;
      foreach (rObject arg, args)
      {
	if (!first && arg == object::void_class)
	  throw object::WrongArgumentType ("");
	first = false;
      }
    }

    switch (func->kind_get ())
    {
      case object::Object::kind_primitive:
        PING ();
        current_ = func.cast<object::Primitive>()->value_get()(*this, args);
	break;
      case object::Object::kind_delegate:
        PING();
        current_ = func.cast<object::Delegate>()->value_get()
          ->operator()(*this, args);
	break;
      case object::Object::kind_code:
        PING ();
	current_ = apply_urbi (scope, func, args);
	break;
      default:
        PING ();
        current_ = func;
	break;
    }

    return current_;
  }

  void
  Runner::operator() (ast::Call& e)
  {
    /*-------------------------.
    | Evaluate the arguments.  |
    `-------------------------*/
    PING ();

    // Iterate over arguments, with a special case for the target.
    ast::exps_type::const_iterator i, i_end;
    i = e.args_get ().begin ();
    i_end = e.args_get ().end ();

    rObject tgt;
    tgt = target(*i);

    // No target?  Abort the call.  This can happen (for instance) when you
    // do a.b () and a does not exist (lookup error).
    if (!tgt)
      return;

    // Gather the arguments, including the target.
    object::objects_type args;
    args.push_back (tgt);
    PING ();
    for (++i; i != i_end; ++i)
    {
      eval (**i);
      passert ("argument without a value: " << **i, current_);
      if (current_ == object::void_class)
      {
	object::WrongArgumentType wt("");
	wt.location_set((*i)->location_get());
	throw wt;
      }
      PING ();
      args.push_back (current_);
    }

    /*---------------------.
    | Decode the message.  |
    `---------------------*/

    rObject val;

    // We may have to run a primitive, or some code.
    try {
      // Ask the target for the handler of the message.
      val = tgt->slot_get (e.name_get ());
    }
    catch (object::UrbiException& ue)
    {
      ue.location_set (e.location_get ());
      raise_error_ (ue);
      current_.reset ();
      return;
    }
    // FIXME: Do we need to issue an error message here?
    if (!val)
      return;
    call_stack_.push_front(&e);
    try {
      apply (object::nil_class, val, args);
    }
    catch (object::UrbiException& ue)
    {
      ue.location_set (e.location_get ());
      throw;
    };
    call_stack_.pop_front();

    // Because while returns 0, we can't have a call that returns 0
    // (a function that runs a while for instance).
    // passert ("no value: " << e, current_);
    ECHO (AST(e) << " result: " << *current_);
  }

  void
  Runner::operator() (ast::Float& e)
  {
    YIELD ();

    current_ = new object::Float (e.value_get());
    ECHO ("result: " << *current_);
  }

  void
  Runner::operator() (ast::Function& e)
  {
    YIELD ();

    PING ();
    current_ = new object::Code (*ast::clone(e));
  }

  void
  Runner::operator() (ast::If& e)
  {
    // Evaluate the test.
    JECHO ("test", e.test_get ());
    operator() (e.test_get());

    YIELD();

    if (IS_TRUE(current_))
    {
      JECHO ("then", e.thenclause_get ());
      operator() (e.thenclause_get());
    }
    else
    {
      JECHO ("else", e.elseclause_get ());
      operator() (e.elseclause_get());
    }
  }

  void
  Runner::operator() (ast::List& e)
  {
    typedef std::list<object::rObject> objects;
    typedef std::list<ast::Exp*> exps;
    // list values
    objects values;
    exps::const_iterator i;
    YIELD ();

    PING ();
    // Evaluate every expression in the list
    // FIXME: parallelized?
    for (i = e.value_get ().begin ();
         i != e.value_get ().end ();
         ++i)
    {
      operator() (**i);
      values.push_back(current_);
    }
    current_ = new object::List (values);
    ECHO ("result: " << *current_);
  }

  void
  Runner::operator() (ast::Nary& e)
  {
    // FIXME: other flavor support.
    ast::exec_exps_type::iterator i;
    current_ = object::void_class;
    for (i = e.children_get().begin(); i != e.children_get().end(); ++i)
    {
      current_.reset ();
      JECHO ("child", *i);
      try {
        operator() (*i);
      }
      catch (object::UrbiException& ue)
      {
        raise_error_ (ue);
        continue;
      }
      CATCH_FLOW_EXCEPTION(ast::BreakException, "break", "outside a loop")
        CATCH_FLOW_EXCEPTION(ast::ReturnException, "return",
                             "outside a function");

      if (e.toplevel_get () && current_.get ())
      {
        ECHO ("toplevel: returning a result to the connection.");
        lobby_->value_get ().connection.new_result (current_);
        current_.reset ();
      }

      /* Allow some time to pass before we execute what follows.  If
         we don't do this, the ;-operator would act almost like the
         |-operator because it would always start to execute its RHS
         immediately.  */
      YIELD ();
    }

    // FIXME: I am very afraid that because of the YIELD above, some
    // command are added right before this clear().  Hence the assert.
    assert (i == e.children_get().end());
    if (e.toplevel_get ())
      e.clear();
  }

  void
  Runner::operator() (ast::Noop&)
  {
    current_.reset ();
  }

  void
  Runner::operator() (ast::Pipe& e)
  {
    // lhs
    JECHO ("lhs", e.lhs_get ());
    operator() (e.lhs_get());

    // rhs:  start the execution immediately.
    JECHO ("rhs", e.rhs_get ());
    operator() (e.rhs_get());
  }

  void
  Runner::operator() (ast::Scope& e)
  {
    // To each scope corresponds a "locals" object which stores the
    // local variables.  It points to the previous current scope to
    // implement lexical scoping.
    rObject locals;
    rObject target;
    locals = new object::Object;
    locals->locals_set(true);
    // FIXME: is this the correct order? depends on getSlot algorithm.
    locals->proto_add (locals_);
    if (e.target_get())
    {
      target = eval(*e.target_get());
      // Be safe, do not inherit from VisibilityScope but copy the slots.
      rObject vscope = object::object_class->slot_get("VisibilityScope");
      locals->slot_set("setSlot", vscope->slot_get("setSlot"));
      locals->slot_set("updateSlot", vscope->slot_get("updateSlot"));
      locals->slot_set("self", target);
      locals->slot_set("__target", target);
      locals->proto_add(target);
    }

    std::swap(locals, locals_);
    super_type::operator()(e.body_get());
    std::swap(locals, locals_);
  }

  void
  Runner::operator() (ast::String& e)
  {
    YIELD ();

    PING ();
    current_ = new object::String(e.value_get());
    ECHO ("result: " << *current_);
  }

  void
  Runner::operator() (ast::Tag&)
  {
    // FIXME: Some code is missing here.
  }

  void
  Runner::operator() (ast::While& e)
  {
    bool broken;

    // Evaluate the test.
    while (true)
    {
      // FIXME: YIELD if second iteration for "while;".

      JECHO ("while test", e.test_get ());
      operator() (e.test_get());
      if (!IS_TRUE(current_))
        break;

      if (e.flavor_get() == ast::flavor_semicolon)
        YIELD();

      JECHO ("while body", e.body_get ());

      broken = false;
      try {
        operator() (e.body_get());
      }
      catch (ast::BreakException&)
      {
        // FIXME: Fix for flavor "," and "&".
        if (e.flavor_get() == ast::flavor_semicolon ||
            e.flavor_get() == ast::flavor_pipe)
          broken = true;
      };
      if (broken)
        break;
    }
    // As far as I know, `while' doesn't return a value in URBI.
    current_.reset ();
  }

  void
  Runner::operator() (ast::Throw& e)
  {
    if (e.kind_get() == ast::break_exception)
      throw ast::BreakException(e.location_get());
    else if (e.kind_get() == ast::return_exception)
    {
      if (e.value_get())
        operator() (*e.value_get());
      else
        current_.reset();
      throw ast::ReturnException(e.location_get(), current_);
    }
  }

  void
  Runner::operator() (ast::Stmt& e)
  {
    JECHO ("expression", e.expression_get ());
    operator() (e.expression_get());
  }

  void
  Runner::operator() (ast::Message& e)
  {
    send_message_(e.tag_get(), e.text_get());
  }

} // namespace runner
<|endoftext|>


<commit_before>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
//                     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 Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constant.h"
#include "llvm/GlobalValue.h"
#include "llvm/Support/LeakDetector.h"
#include <algorithm>
#include <iostream>
using namespace llvm;

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, unsigned scid, const std::string &name)
  : SubclassID(scid), Ty(checkType(ty)), UseList(0), Name(name) {
  if (!isa<Constant>(this) && !isa<BasicBlock>(this))
    assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
           isa<OpaqueType>(ty)) &&
           "Cannot create non-first-class values except for constants!");
  if (ty == Type::VoidTy)
    assert(name.empty() && "Cannot have named void values!");
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (use_begin() != use_end()) {
    std::cerr << "While deleting: " << *Ty << " %" << Name << "\n";
    for (use_iterator I = use_begin(), E = use_end(); I != E; ++I)
      std::cerr << "Use still stuck around after Def is destroyed:"
                << **I << "\n";
  }
#endif
  assert(use_begin() == use_end() && "Uses remain when a value is destroyed!");

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

/// hasNUses - Return true if this Value has exactly N users.
///
bool Value::hasNUses(unsigned N) const {
  use_const_iterator UI = use_begin(), E = use_end();

  for (; N; --N, ++UI)
    if (UI == E) return false;  // Too few.
  return UI == E;
}

/// getNumUses - This method computes the number of uses of this Value.  This
/// is a linear time operation.  Use hasOneUse or hasNUses to check for specific
/// values.
unsigned Value::getNumUses() const {
  return (unsigned)std::distance(use_begin(), use_end());
}

// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith,
// except that it doesn't have all of the asserts.  The asserts fail because we
// are half-way done resolving types, which causes some types to exist as two
// different Type*'s at the same time.  This is a sledgehammer to work around
// this problem.
//
void Value::uncheckedReplaceAllUsesWith(Value *New) {
  while (!use_empty()) {
    Use &U = *UseList;
    // Must handle Constants specially, we cannot call replaceUsesOfWith on a
    // constant!
    if (Constant *C = dyn_cast<Constant>(U.getUser())) {
      if (!isa<GlobalValue>(C))
        C->replaceUsesOfWithOnConstant(this, New, true);
      else
        U.set(New);
    } else {
      U.set(New);
    }
  }
}

void Value::replaceAllUsesWith(Value *New) {
  assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
  assert(New->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");

  uncheckedReplaceAllUsesWith(New);
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  assert(!isa<Constant>(this) || isa<GlobalValue>(this) &&
         "Cannot call User::replaceUsesofWith on a constant!");

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

<commit_msg>Initialize new field.<commit_after>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
//                     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 Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constant.h"
#include "llvm/GlobalValue.h"
#include "llvm/Support/LeakDetector.h"
#include <algorithm>
#include <iostream>
using namespace llvm;

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, unsigned scid, const std::string &name)
  : SubclassID(scid), SubclassData(0), Ty(checkType(ty)),
    UseList(0), Name(name) {
  if (!isa<Constant>(this) && !isa<BasicBlock>(this))
    assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
           isa<OpaqueType>(ty)) &&
           "Cannot create non-first-class values except for constants!");
  if (ty == Type::VoidTy)
    assert(name.empty() && "Cannot have named void values!");
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (use_begin() != use_end()) {
    std::cerr << "While deleting: " << *Ty << " %" << Name << "\n";
    for (use_iterator I = use_begin(), E = use_end(); I != E; ++I)
      std::cerr << "Use still stuck around after Def is destroyed:"
                << **I << "\n";
  }
#endif
  assert(use_begin() == use_end() && "Uses remain when a value is destroyed!");

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

/// hasNUses - Return true if this Value has exactly N users.
///
bool Value::hasNUses(unsigned N) const {
  use_const_iterator UI = use_begin(), E = use_end();

  for (; N; --N, ++UI)
    if (UI == E) return false;  // Too few.
  return UI == E;
}

/// getNumUses - This method computes the number of uses of this Value.  This
/// is a linear time operation.  Use hasOneUse or hasNUses to check for specific
/// values.
unsigned Value::getNumUses() const {
  return (unsigned)std::distance(use_begin(), use_end());
}

// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith,
// except that it doesn't have all of the asserts.  The asserts fail because we
// are half-way done resolving types, which causes some types to exist as two
// different Type*'s at the same time.  This is a sledgehammer to work around
// this problem.
//
void Value::uncheckedReplaceAllUsesWith(Value *New) {
  while (!use_empty()) {
    Use &U = *UseList;
    // Must handle Constants specially, we cannot call replaceUsesOfWith on a
    // constant!
    if (Constant *C = dyn_cast<Constant>(U.getUser())) {
      if (!isa<GlobalValue>(C))
        C->replaceUsesOfWithOnConstant(this, New, true);
      else
        U.set(New);
    } else {
      U.set(New);
    }
  }
}

void Value::replaceAllUsesWith(Value *New) {
  assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
  assert(New->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");

  uncheckedReplaceAllUsesWith(New);
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  assert(!isa<Constant>(this) || isa<GlobalValue>(this) &&
         "Cannot call User::replaceUsesofWith on a constant!");

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

<|endoftext|>


<commit_before>/*
 * Qt4 bitcoin GUI.
 *
 * W.J. van der Laan 2011-2012
 * The Bitcoin Developers 2011-2013
 */
#include "walletframe.h"
#include "bitcoingui.h"
#include "walletstack.h"

#include <QHBoxLayout>
#include <QMessageBox>

WalletFrame::WalletFrame(BitcoinGUI *_gui) :
    QFrame(_gui)
{
    // Leave HBox hook for adding a list view later
    QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
    setContentsMargins(0,0,0,0);
    walletStack = new WalletStack(this);
    walletStack->setBitcoinGUI(_gui);
    walletFrameLayout->setContentsMargins(0,0,0,0);
    walletFrameLayout->addWidget(walletStack);
}

WalletFrame::~WalletFrame()
{
}

void WalletFrame::setClientModel(ClientModel *clientModel)
{
    if (clientModel)
        walletStack->setClientModel(clientModel);
}

bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
{
    return walletStack->addWallet(name, walletModel);
}

bool WalletFrame::setCurrentWallet(const QString& name)
{
    // TODO: Check if valid name
    return walletStack->setCurrentWallet(name);
}

void WalletFrame::removeAllWallets()
{
    walletStack->removeAllWallets();
}

bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
{
    return walletStack->handlePaymentRequest(recipient);
}

void WalletFrame::showOutOfSyncWarning(bool fShow)
{
    if (!walletStack) {
        QMessageBox box;
        box.setText("walletStack is null");
        box.exec();
        return;
    }
    walletStack->showOutOfSyncWarning(fShow);
}

void WalletFrame::gotoOverviewPage()
{
    walletStack->gotoOverviewPage();
}

void WalletFrame::gotoHistoryPage()
{
    walletStack->gotoHistoryPage();
}

void WalletFrame::gotoAddressBookPage()
{
    walletStack->gotoAddressBookPage();
}

void WalletFrame::gotoReceiveCoinsPage()
{
    walletStack->gotoReceiveCoinsPage();
}

void WalletFrame::gotoSendCoinsPage(QString addr)
{
    walletStack->gotoSendCoinsPage(addr);
}

void WalletFrame::gotoSignMessageTab(QString addr)
{
    walletStack->gotoSignMessageTab(addr);
}

void WalletFrame::gotoVerifyMessageTab(QString addr)
{
    walletStack->gotoSignMessageTab(addr);
}

void WalletFrame::encryptWallet(bool status)
{
    walletStack->encryptWallet(status);
}

void WalletFrame::backupWallet()
{
    walletStack->backupWallet();
}

void WalletFrame::changePassphrase()
{
    walletStack->changePassphrase();
}

void WalletFrame::unlockWallet()
{
    walletStack->unlockWallet();
}

void WalletFrame::setEncryptionStatus()
{
    walletStack->setEncryptionStatus();
}
<commit_msg>Bitcoin-Qt: add missing change from branch Qt_misc<commit_after>/*
 * Qt4 bitcoin GUI.
 *
 * W.J. van der Laan 2011-2012
 * The Bitcoin Developers 2011-2013
 */
#include "walletframe.h"
#include "bitcoingui.h"
#include "walletstack.h"

#include <QHBoxLayout>
#include <QMessageBox>

WalletFrame::WalletFrame(BitcoinGUI *_gui) :
    QFrame(_gui)
{
    // Leave HBox hook for adding a list view later
    QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
    setContentsMargins(0,0,0,0);
    walletStack = new WalletStack(this);
    walletStack->setBitcoinGUI(_gui);
    walletFrameLayout->setContentsMargins(0,0,0,0);
    walletFrameLayout->addWidget(walletStack);
}

WalletFrame::~WalletFrame()
{
}

void WalletFrame::setClientModel(ClientModel *clientModel)
{
    if (clientModel)
        walletStack->setClientModel(clientModel);
}

bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
{
    return walletStack->addWallet(name, walletModel);
}

bool WalletFrame::setCurrentWallet(const QString& name)
{
    // TODO: Check if valid name
    return walletStack->setCurrentWallet(name);
}

void WalletFrame::removeAllWallets()
{
    walletStack->removeAllWallets();
}

bool WalletFrame::handlePaymentRequest(const SendCoinsRecipient &recipient)
{
    return walletStack->handlePaymentRequest(recipient);
}

void WalletFrame::showOutOfSyncWarning(bool fShow)
{
    if (!walletStack)
        return;

    walletStack->showOutOfSyncWarning(fShow);
}

void WalletFrame::gotoOverviewPage()
{
    walletStack->gotoOverviewPage();
}

void WalletFrame::gotoHistoryPage()
{
    walletStack->gotoHistoryPage();
}

void WalletFrame::gotoAddressBookPage()
{
    walletStack->gotoAddressBookPage();
}

void WalletFrame::gotoReceiveCoinsPage()
{
    walletStack->gotoReceiveCoinsPage();
}

void WalletFrame::gotoSendCoinsPage(QString addr)
{
    walletStack->gotoSendCoinsPage(addr);
}

void WalletFrame::gotoSignMessageTab(QString addr)
{
    walletStack->gotoSignMessageTab(addr);
}

void WalletFrame::gotoVerifyMessageTab(QString addr)
{
    walletStack->gotoSignMessageTab(addr);
}

void WalletFrame::encryptWallet(bool status)
{
    walletStack->encryptWallet(status);
}

void WalletFrame::backupWallet()
{
    walletStack->backupWallet();
}

void WalletFrame::changePassphrase()
{
    walletStack->changePassphrase();
}

void WalletFrame::unlockWallet()
{
    walletStack->unlockWallet();
}

void WalletFrame::setEncryptionStatus()
{
    walletStack->setEncryptionStatus();
}
<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/sdl/sdlinput.hpp"

#include "guichan/exception.hpp"

namespace gcn
{
    SDLInput::SDLInput()
    {
        mMouseInWindow = true;
        mMouseDown = false;
    }

    bool SDLInput::isKeyQueueEmpty()
    {
        return mKeyInputQueue.empty();
    }

    KeyInput SDLInput::dequeueKeyInput()
    {
        KeyInput keyInput;

        if (mKeyInputQueue.empty())
        {
            throw GCN_EXCEPTION("The queue is empty.");
        }

        keyInput = mKeyInputQueue.front();
        mKeyInputQueue.pop();

        return keyInput;
    }

    bool SDLInput::isMouseQueueEmpty()
    {
        return mMouseInputQueue.empty();
    }

    MouseInput SDLInput::dequeueMouseInput()
    {
        MouseInput mouseInput;

        if (mMouseInputQueue.empty())
        {
            throw GCN_EXCEPTION("The queue is empty.");
        }

        mouseInput = mMouseInputQueue.front();
        mMouseInputQueue.pop();

        return mouseInput;
    }

    void SDLInput::pushInput(SDL_Event event)
    {
        KeyInput keyInput;
        MouseInput mouseInput;

        switch (event.type)
        {
          case SDL_KEYDOWN:
              keyInput.setKey(convertKeyCharacter(event.key.keysym));
              keyInput.setType(KeyInput::PRESS);
              mKeyInputQueue.push(keyInput);
              break;

          case SDL_KEYUP:
              keyInput.setKey(convertKeyCharacter(event.key.keysym));
              keyInput.setType(KeyInput::RELEASE);
              mKeyInputQueue.push(keyInput);
              break;

          case SDL_MOUSEBUTTONDOWN:
              mMouseDown = true;
              mouseInput.x = event.button.x;
              mouseInput.y = event.button.y;
              mouseInput.setButton(convertMouseButton(event.button.button));
              mouseInput.setType(MouseInput::PRESS);
              mouseInput.setTimeStamp(SDL_GetTicks());
              mMouseInputQueue.push(mouseInput);
              break;

          case SDL_MOUSEBUTTONUP:
              mMouseDown = false;
              mouseInput.x = event.button.x;
              mouseInput.y = event.button.y;
              mouseInput.setButton(convertMouseButton(event.button.button));
              mouseInput.setType(MouseInput::RELEASE);
              mouseInput.setTimeStamp(SDL_GetTicks());
              mMouseInputQueue.push(mouseInput);
              break;

          case SDL_MOUSEMOTION:
              mouseInput.x = event.button.x;
              mouseInput.y = event.button.y;
              mouseInput.setButton(MouseInput::EMPTY);
              mouseInput.setType(MouseInput::MOTION);
              mouseInput.setTimeStamp(SDL_GetTicks());
              mMouseInputQueue.push(mouseInput);
              break;

          case SDL_ACTIVEEVENT:
              /*
               * This occurs when the mouse leaves the window and the Gui-chan
               * application loses its mousefocus.
               */
              if ((event.active.state & SDL_APPMOUSEFOCUS)
                  && !event.active.gain)
              {
                  mMouseInWindow = false;

                  if (!mMouseDown)
                  {
                      mouseInput.x = -1;
                      mouseInput.y = -1;
                      mouseInput.setButton(MouseInput::EMPTY);
                      mouseInput.setType(MouseInput::MOTION);
                      mMouseInputQueue.push(mouseInput);
                  }
              }

              if ((event.active.state & SDL_APPMOUSEFOCUS)
                  && event.active.gain)
              {
                  mMouseInWindow = true;
              }
              break;

        } // end switch
    }

    int SDLInput::convertMouseButton(int button)
    {
        switch (button)
        {
          case SDL_BUTTON_LEFT:
              return MouseInput::LEFT;
              break;
          case SDL_BUTTON_RIGHT:
              return MouseInput::RIGHT;
              break;
          case SDL_BUTTON_MIDDLE:
              return MouseInput::MIDDLE;
              break;
          case SDL_BUTTON_WHEELUP:
              return MouseInput::WHEEL_UP;
              break;
          case SDL_BUTTON_WHEELDOWN:
              return MouseInput::WHEEL_DOWN;
              break;
        }

        throw GCN_EXCEPTION("Unknown SDL mouse type.");

        return 0;
    }

    Key SDLInput::convertKeyCharacter(SDL_keysym keysym)
    {
        int value = 0;
        Key key;

        if (keysym.unicode < 255)
        {
            value = (int)keysym.unicode;
        }

        switch (keysym.sym)
        {
          case SDLK_TAB:
              value = Key::TAB;
              break;
          case SDLK_LALT:
              value = Key::LEFT_ALT;
              break;
          case SDLK_RALT:
              value = Key::RIGHT_ALT;
              break;
          case SDLK_LSHIFT:
              value = Key::LEFT_SHIFT;
              break;
          case SDLK_RSHIFT:
              value = Key::RIGHT_SHIFT;
              break;
          case SDLK_LCTRL:
              value = Key::LEFT_CONTROL;
              break;
          case SDLK_RCTRL:
              value = Key::RIGHT_CONTROL;
              break;
          case SDLK_BACKSPACE:
              value = Key::BACKSPACE;
              break;
          case SDLK_PAUSE:
              value = Key::PAUSE;
              break;
          case SDLK_SPACE:
              value = Key::SPACE;
              break;
          case SDLK_ESCAPE:
              value = Key::ESCAPE;
              break;
          case SDLK_DELETE:
              value = Key::DELETE;
              break;
          case SDLK_INSERT:
              value = Key::INSERT;
              break;
          case SDLK_HOME:
              value = Key::HOME;
              break;
          case SDLK_END:
              value = Key::END;
              break;
          case SDLK_PAGEUP:
              value = Key::PAGE_UP;
              break;
          case SDLK_PRINT:
              value = Key::PRINT_SCREEN;
              break;
          case SDLK_PAGEDOWN:
              value = Key::PAGE_DOWN;
              break;
          case SDLK_F1:
              value = Key::F1;
              break;
          case SDLK_F2:
              value = Key::F2;
              break;
          case SDLK_F3:
              value = Key::F3;
              break;
          case SDLK_F4:
              value = Key::F4;
              break;
          case SDLK_F5:
              value = Key::F5;
              break;
          case SDLK_F6:
              value = Key::F6;
              break;
          case SDLK_F7:
              value = Key::F7;
              break;
          case SDLK_F8:
              value = Key::F8;
              break;
          case SDLK_F9:
              value = Key::F9;
              break;
          case SDLK_F10:
              value = Key::F10;
              break;
          case SDLK_F11:
              value = Key::F11;
              break;
          case SDLK_F12:
              value = Key::F12;
              break;
          case SDLK_F13:
              value = Key::F13;
              break;
          case SDLK_F14:
              value = Key::F14;
              break;
          case SDLK_F15:
              value = Key::F15;
              break;
          case SDLK_NUMLOCK:
              value = Key::NUM_LOCK;
              break;
          case SDLK_CAPSLOCK:
              value = Key::CAPS_LOCK;
              break;
          case SDLK_SCROLLOCK:
              value = Key::SCROLL_LOCK;
              break;
          case SDLK_RMETA:
              value = Key::RIGHT_META;
              break;
          case SDLK_LMETA:
              value = Key::LEFT_META;
              break;
          case SDLK_LSUPER:
              value = Key::LEFT_SUPER;
              break;
          case SDLK_RSUPER:
              value = Key::RIGHT_SUPER;
              break;
          case SDLK_MODE:
              value = Key::ALT_GR;
              break;
          case SDLK_UP:
              value = Key::UP;
              break;
          case SDLK_DOWN:
              value = Key::DOWN;
              break;
          case SDLK_LEFT:
              value = Key::LEFT;
              break;
          case SDLK_RIGHT:
              value = Key::RIGHT;
              break;
          case SDLK_RETURN:
              value = Key::ENTER;
              break;
          case SDLK_KP_ENTER:
              value = Key::ENTER;
              break;

          default:
              break;
        }

        if (!(keysym.mod & KMOD_NUM))
        {
            switch (keysym.sym)
            {
              case SDLK_KP0:
                  value = Key::INSERT;
                  break;
              case SDLK_KP1:
                  value = Key::END;
                  break;
              case SDLK_KP2:
                  value = Key::DOWN;
                  break;
              case SDLK_KP3:
                  value = Key::PAGE_DOWN;
                  break;
              case SDLK_KP4:
                  value = Key::LEFT;
                  break;
              case SDLK_KP5:
                  value = 0;
                  break;
              case SDLK_KP6:
                  value = Key::RIGHT;
                  break;
              case SDLK_KP7:
                  value = Key::HOME;
                  break;
              case SDLK_KP8:
                  value = Key::UP;
                  break;
              case SDLK_KP9:
                  value = Key::PAGE_UP;
                  break;
              default:
                  break;
            }
        }

        key.setValue(value);
        key.setShiftPressed(keysym.mod & KMOD_SHIFT);
        key.setControlPressed(keysym.mod & KMOD_CTRL);
        key.setAltPressed(keysym.mod & KMOD_ALT);
        key.setMetaPressed(keysym.mod & KMOD_META);

        if (keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS)
        {
            key.setNumericPad(true);
        }

        return key;
    }
}
<commit_msg>Unkown SDL mouse types has been changed to be ignored.<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005, 2006 Olof Naessn and Per Larsson
 *
 *                                                         Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/sdl/sdlinput.hpp"

#include "guichan/exception.hpp"

namespace gcn
{
    SDLInput::SDLInput()
    {
        mMouseInWindow = true;
        mMouseDown = false;
    }

    bool SDLInput::isKeyQueueEmpty()
    {
        return mKeyInputQueue.empty();
    }

    KeyInput SDLInput::dequeueKeyInput()
    {
        KeyInput keyInput;

        if (mKeyInputQueue.empty())
        {
            throw GCN_EXCEPTION("The queue is empty.");
        }

        keyInput = mKeyInputQueue.front();
        mKeyInputQueue.pop();

        return keyInput;
    }

    bool SDLInput::isMouseQueueEmpty()
    {
        return mMouseInputQueue.empty();
    }

    MouseInput SDLInput::dequeueMouseInput()
    {
        MouseInput mouseInput;

        if (mMouseInputQueue.empty())
        {
            throw GCN_EXCEPTION("The queue is empty.");
        }

        mouseInput = mMouseInputQueue.front();
        mMouseInputQueue.pop();

        return mouseInput;
    }

    void SDLInput::pushInput(SDL_Event event)
    {
        KeyInput keyInput;
        MouseInput mouseInput;

        switch (event.type)
        {
          case SDL_KEYDOWN:
              keyInput.setKey(convertKeyCharacter(event.key.keysym));
              keyInput.setType(KeyInput::PRESS);
              mKeyInputQueue.push(keyInput);
              break;

          case SDL_KEYUP:
              keyInput.setKey(convertKeyCharacter(event.key.keysym));
              keyInput.setType(KeyInput::RELEASE);
              mKeyInputQueue.push(keyInput);
              break;

          case SDL_MOUSEBUTTONDOWN:
              mMouseDown = true;
              mouseInput.x = event.button.x;
              mouseInput.y = event.button.y;
              mouseInput.setButton(convertMouseButton(event.button.button));
              mouseInput.setType(MouseInput::PRESS);
              mouseInput.setTimeStamp(SDL_GetTicks());
              mMouseInputQueue.push(mouseInput);
              break;

          case SDL_MOUSEBUTTONUP:
              mMouseDown = false;
              mouseInput.x = event.button.x;
              mouseInput.y = event.button.y;
              mouseInput.setButton(convertMouseButton(event.button.button));
              mouseInput.setType(MouseInput::RELEASE);
              mouseInput.setTimeStamp(SDL_GetTicks());
              mMouseInputQueue.push(mouseInput);
              break;

          case SDL_MOUSEMOTION:
              mouseInput.x = event.button.x;
              mouseInput.y = event.button.y;
              mouseInput.setButton(MouseInput::EMPTY);
              mouseInput.setType(MouseInput::MOTION);
              mouseInput.setTimeStamp(SDL_GetTicks());
              mMouseInputQueue.push(mouseInput);
              break;

          case SDL_ACTIVEEVENT:
              /*
               * This occurs when the mouse leaves the window and the Gui-chan
               * application loses its mousefocus.
               */
              if ((event.active.state & SDL_APPMOUSEFOCUS)
                  && !event.active.gain)
              {
                  mMouseInWindow = false;

                  if (!mMouseDown)
                  {
                      mouseInput.x = -1;
                      mouseInput.y = -1;
                      mouseInput.setButton(MouseInput::EMPTY);
                      mouseInput.setType(MouseInput::MOTION);
                      mMouseInputQueue.push(mouseInput);
                  }
              }

              if ((event.active.state & SDL_APPMOUSEFOCUS)
                  && event.active.gain)
              {
                  mMouseInWindow = true;
              }
              break;

        } // end switch
    }

    int SDLInput::convertMouseButton(int button)
    {
        switch (button)
        {
          case SDL_BUTTON_LEFT:
              return MouseInput::LEFT;
              break;
          case SDL_BUTTON_RIGHT:
              return MouseInput::RIGHT;
              break;
          case SDL_BUTTON_MIDDLE:
              return MouseInput::MIDDLE;
              break;
          case SDL_BUTTON_WHEELUP:
              return MouseInput::WHEEL_UP;
              break;
          case SDL_BUTTON_WHEELDOWN:
              return MouseInput::WHEEL_DOWN;
              break;
        }

        // We have an unknown mouse type which is ignored.
        return button;
    }

    Key SDLInput::convertKeyCharacter(SDL_keysym keysym)
    {
        int value = 0;
        Key key;

        if (keysym.unicode < 255)
        {
            value = (int)keysym.unicode;
        }

        switch (keysym.sym)
        {
          case SDLK_TAB:
              value = Key::TAB;
              break;
          case SDLK_LALT:
              value = Key::LEFT_ALT;
              break;
          case SDLK_RALT:
              value = Key::RIGHT_ALT;
              break;
          case SDLK_LSHIFT:
              value = Key::LEFT_SHIFT;
              break;
          case SDLK_RSHIFT:
              value = Key::RIGHT_SHIFT;
              break;
          case SDLK_LCTRL:
              value = Key::LEFT_CONTROL;
              break;
          case SDLK_RCTRL:
              value = Key::RIGHT_CONTROL;
              break;
          case SDLK_BACKSPACE:
              value = Key::BACKSPACE;
              break;
          case SDLK_PAUSE:
              value = Key::PAUSE;
              break;
          case SDLK_SPACE:
              value = Key::SPACE;
              break;
          case SDLK_ESCAPE:
              value = Key::ESCAPE;
              break;
          case SDLK_DELETE:
              value = Key::DELETE;
              break;
          case SDLK_INSERT:
              value = Key::INSERT;
              break;
          case SDLK_HOME:
              value = Key::HOME;
              break;
          case SDLK_END:
              value = Key::END;
              break;
          case SDLK_PAGEUP:
              value = Key::PAGE_UP;
              break;
          case SDLK_PRINT:
              value = Key::PRINT_SCREEN;
              break;
          case SDLK_PAGEDOWN:
              value = Key::PAGE_DOWN;
              break;
          case SDLK_F1:
              value = Key::F1;
              break;
          case SDLK_F2:
              value = Key::F2;
              break;
          case SDLK_F3:
              value = Key::F3;
              break;
          case SDLK_F4:
              value = Key::F4;
              break;
          case SDLK_F5:
              value = Key::F5;
              break;
          case SDLK_F6:
              value = Key::F6;
              break;
          case SDLK_F7:
              value = Key::F7;
              break;
          case SDLK_F8:
              value = Key::F8;
              break;
          case SDLK_F9:
              value = Key::F9;
              break;
          case SDLK_F10:
              value = Key::F10;
              break;
          case SDLK_F11:
              value = Key::F11;
              break;
          case SDLK_F12:
              value = Key::F12;
              break;
          case SDLK_F13:
              value = Key::F13;
              break;
          case SDLK_F14:
              value = Key::F14;
              break;
          case SDLK_F15:
              value = Key::F15;
              break;
          case SDLK_NUMLOCK:
              value = Key::NUM_LOCK;
              break;
          case SDLK_CAPSLOCK:
              value = Key::CAPS_LOCK;
              break;
          case SDLK_SCROLLOCK:
              value = Key::SCROLL_LOCK;
              break;
          case SDLK_RMETA:
              value = Key::RIGHT_META;
              break;
          case SDLK_LMETA:
              value = Key::LEFT_META;
              break;
          case SDLK_LSUPER:
              value = Key::LEFT_SUPER;
              break;
          case SDLK_RSUPER:
              value = Key::RIGHT_SUPER;
              break;
          case SDLK_MODE:
              value = Key::ALT_GR;
              break;
          case SDLK_UP:
              value = Key::UP;
              break;
          case SDLK_DOWN:
              value = Key::DOWN;
              break;
          case SDLK_LEFT:
              value = Key::LEFT;
              break;
          case SDLK_RIGHT:
              value = Key::RIGHT;
              break;
          case SDLK_RETURN:
              value = Key::ENTER;
              break;
          case SDLK_KP_ENTER:
              value = Key::ENTER;
              break;

          default:
              break;
        }

        if (!(keysym.mod & KMOD_NUM))
        {
            switch (keysym.sym)
            {
              case SDLK_KP0:
                  value = Key::INSERT;
                  break;
              case SDLK_KP1:
                  value = Key::END;
                  break;
              case SDLK_KP2:
                  value = Key::DOWN;
                  break;
              case SDLK_KP3:
                  value = Key::PAGE_DOWN;
                  break;
              case SDLK_KP4:
                  value = Key::LEFT;
                  break;
              case SDLK_KP5:
                  value = 0;
                  break;
              case SDLK_KP6:
                  value = Key::RIGHT;
                  break;
              case SDLK_KP7:
                  value = Key::HOME;
                  break;
              case SDLK_KP8:
                  value = Key::UP;
                  break;
              case SDLK_KP9:
                  value = Key::PAGE_UP;
                  break;
              default:
                  break;
            }
        }

        key.setValue(value);
        key.setShiftPressed(keysym.mod & KMOD_SHIFT);
        key.setControlPressed(keysym.mod & KMOD_CTRL);
        key.setAltPressed(keysym.mod & KMOD_ALT);
        key.setMetaPressed(keysym.mod & KMOD_META);

        if (keysym.sym >= SDLK_KP0 && keysym.sym <= SDLK_KP_EQUALS)
        {
            key.setNumericPad(true);
        }

        return key;
    }
}
<|endoftext|>


<commit_before>/*
 * File: RSTNode.hpp
 * Author: Joshua Yuen cs100vbc
 * Author: Jay Dey cs100vaj
 */

#ifndef RSTNODE_HPP
#define RSTNODE_HPP
#include "BSTNode.hpp"

template <typename Data>
class RSTNode : public BSTNode<Data>
{
public:
  //TODO: implement this constructor
  RSTNode(Data const & d) : BSTNode<Data>(d)
  {

  }

};

#endif // RSTNODE_HPP
<commit_msg>added protected priority var<commit_after>/*
 * File: RSTNode.hpp
 * Author: Joshua Yuen cs100vbc
 * Author: Jay Dey cs100vaj
 */

#ifndef RSTNODE_HPP
#define RSTNODE_HPP
#include "BSTNode.hpp"
#include <stdlib.h>

template <typename Data>
class RSTNode : public BSTNode<Data>
{

protected:

  unsigned int priority;

public:
  //TODO: implement this constructor
  RSTNode(Data const & d) : BSTNode<Data>(d)
  {
    priority = rand();
  }

};

#endif // RSTNODE_HPP
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
///
/// \file main.cpp
/// \brief Main file for testing different system classes
///        and functionality.
/// Author: Andrew Watson, Jonathan Ulrich
/// Created: 1/22/13
/// Email: watsontandrew@gmail.com, JonGUlrich@gmail.com
///
////////////////////////////////////////////////////////////////////////////////
#include "hokuyo.hpp"
#include "dynamixel.hpp"
#include <time.h>
#include <wiringPi.h>
#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using namespace std;
timespec diff(timespec start, timespec end);
//#define TESTHOKUYO
#ifdef TESTHOKUYO
class ExampleLaserCallback : public Laser::Callback
{
public:
    ExampleLaserCallback(){}
    ~ExampleLaserCallback(){}
    virtual void ProcessLaserData(const std::vector<CvPoint3D64f>& scan,
                                  const time_t& timestamp)
    {
        mLaserScan = scan;
        mTimeStamp = timestamp;
    }
    std::vector<CvPoint3D64f> mLaserScan;
    time_t mTimeStamp;
};

double MiddleScanDistanceInches (const std::vector<CvPoint3D64f>& scan)
{
    if(scan.size() > 0)
        return scan.at(scan.size() / 2.).x * 1000. / 25.4;
    else
        return 0;
}

int main()
{
    Laser::Hokuyo* laser = new Laser::Hokuyo();
    ExampleLaserCallback callback;
    laser->RegisterCallback(&callback);
    if(laser->Initialize())
    {
        if(laser->StartCaptureThread())
        {
            while (1)
            {
                std::cout << MiddleScanDistanceInches(callback.mLaserScan)
                          << std::endl;
                boost::this_thread::sleep(boost::posix_time::millisec(10));
            }
            laser->Shutdown();
            delete laser;
        }
    }

    return 0;
}
#endif

//#define TESTDYNAMIXELSPEED
#ifdef TESTDYNAMIXELSPEED

int main()
{
    Motor::Dynamixel* motor = new Motor::Dynamixel();
    double rpm = 0.0;
    int dir;
    bool clockwise = true;
    if(motor->Initialize())
    {
        motor->SetSpeedRpm(rpm, clockwise);
        while (1)
        {
            cout << "Input Speed in RPM (0-114): " << endl;
            cin >> rpm;
            cout << "Input direction (0 = CCW, 1 = CW): " << endl;
            cin >> dir;
            if(dir)
                clockwise = true;
            else
                clockwise = false;
            motor->SetSpeedRpm(rpm, clockwise);
        }
    }
   return 0;
}
#endif

//#define TESTDYNAMIXELFEEDBACK
#ifdef TESTDYNAMIXELFEEDBACK

int main()
{
    Motor::Dynamixel* motor = new Motor::Dynamixel();
    double rpm = 10.0;
    if(motor->Initialize())
    {
        motor->SetSpeedRpm(rpm, true);
        while (1)
        {
            cout << motor->GetPositionDegrees() << endl;
            usleep(10000);
        }
    }
   return 0;
}
#endif

/** This test tells the motor to move at 10 RPM and sets a timer at the
    start of the sequence, upon 1 revolution it will print the time
    elapsed. Theoretically it should be 6 seconds exactly given 10 RPM.*/
#define TESTDYNAMIXELSPEEDACCURACY
#ifdef TESTDYNAMIXELSPEEDACCURACY

int main()
{
    Motor::Dynamixel* motor = new Motor::Dynamixel();
    double rpm = 10.0; // 10 RPM / 60 = .16667 Hz ^ -1 = 6 secs
    double degrees = 0;
    double lowthres = 0;
    double hghthres = 0;
    double difseconds = 0;
    double curpos = 0;
    timespec t1, t2, dif;
    if(motor->Initialize())
    {
        delayMicroseconds(250000);
        motor->SetSpeedRpm(0, true);
        delayMicroseconds(750000);
        degrees = motor->GetPositionDegrees();
        lowthres = degrees - 0.3;
        hghthres = degrees + 0.3;
        motor->SetSpeedRpm(rpm, true);
        delayMicroseconds(40000);
        clock_gettime(CLOCK_MONOTONIC, &t1);
        while (1)
        {
            curpos = motor->GetPositionDegrees();
            if(curpos >= lowthres && curpos <= hghthres)
            {
                clock_gettime(CLOCK_MONOTONIC, &t2);
                dif = diff(t1, t2);
                double decimalsecs = (double) dif.tv_nsec;
                decimalsecs /= 1000000000.;
                difseconds = dif.tv_sec + decimalsecs;
                cout << setprecision(7) << difseconds << endl;
                motor->SetSpeedRpm(0, true);
                delayMicroseconds(250000);
                break;
            }
        }
    }
   return 0;
}
#endif

//#define TESTTIMING
#ifdef TESTTIMING
int main()
{
    timespec t1, t2;
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t1);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t2);
    unsigned int i = 0;
    while(1)
    {
        if(diff(t1, t2).tv_sec >= 1)
        {
            i++;
            std::cout << diff(t1, t2).tv_nsec <<" Sec Elapsed" << std::endl;
            clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t1);
            clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t2);
        }
        else
        {
            clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t2);
        }
    }
    return 0;
}

#endif

//#define TESTSERVER
#ifdef TESTSERVER
//http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/iostreams/
//Requires SUDO to run in order to bind to port
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
  using namespace std; // For time_t, time and ctime;
  time_t now = time(0);
  return ctime(&now);
}

int main()
{
  try
  {
    boost::asio::io_service io_service;

    tcp::endpoint endpoint(tcp::v4(), 13);
    tcp::acceptor acceptor(io_service, endpoint);

    for (;;)
    {
      tcp::iostream stream;
      acceptor.accept(*stream.rdbuf());
      stream << make_daytime_string();
    }
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

#endif

//#define TESTISR
#ifdef TESTISR

#define BUTTON_PIN 0
volatile int eventCounter = 0;
void myInterrupt(void) {eventCounter++;}

int main()
{

    if (wiringPiSetup () < 0) {
          fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno));
          return 1;
      }

      // set Pin 17/0 generate an interrupt on high-to-low transitions
      // and attach myInterrupt() to the interrupt
      if ( wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0 ) {
          fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno));
          return 1;
      }

      // display counter value every second.
      while ( 1 ) {
        printf( "%d\n", eventCounter );
        eventCounter = 0;
        delay( 1000 ); // wait 1 second
      }

      return 0;
}

#endif

//#define TESTIMAGEGENERATION
#ifdef TESTIMAGEGENERATION
int main()
{

   return 0;
}
#endif

timespec diff(timespec start, timespec end)
{
    timespec temp;
    if((end.tv_nsec - start.tv_nsec) < 0)
    {
        temp.tv_sec = end.tv_sec - start.tv_sec - 1;
        temp.tv_nsec = 1000000000L + end.tv_nsec - start.tv_nsec;
    }
    else
    {
        temp.tv_sec = end.tv_sec - start.tv_sec;
        temp.tv_nsec = end.tv_nsec - start.tv_nsec;
    }
    return temp;
}

/** End of File */
<commit_msg>New TCP Server with Sockets<commit_after>////////////////////////////////////////////////////////////////////////////////
///
/// \file main.cpp
/// \brief Main file for testing different system classes
///        and functionality.
/// Author: Andrew Watson, Jonathan Ulrich
/// Created: 1/22/13
/// Email: watsontandrew@gmail.com, JonGUlrich@gmail.com
///
////////////////////////////////////////////////////////////////////////////////
#include "hokuyo.hpp"
#include "dynamixel.hpp"
#include <time.h>
#include <wiringPi.h>
#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using namespace std;
timespec diff(timespec start, timespec end);
//#define TESTHOKUYO
#ifdef TESTHOKUYO
class ExampleLaserCallback : public Laser::Callback
{
public:
    ExampleLaserCallback(){}
    ~ExampleLaserCallback(){}
    virtual void ProcessLaserData(const std::vector<CvPoint3D64f>& scan,
                                  const time_t& timestamp)
    {
        mLaserScan = scan;
        mTimeStamp = timestamp;
    }
    std::vector<CvPoint3D64f> mLaserScan;
    time_t mTimeStamp;
};

double MiddleScanDistanceInches (const std::vector<CvPoint3D64f>& scan)
{
    if(scan.size() > 0)
        return scan.at(scan.size() / 2.).x * 1000. / 25.4;
    else
        return 0;
}

int main()
{
    Laser::Hokuyo* laser = new Laser::Hokuyo();
    ExampleLaserCallback callback;
    laser->RegisterCallback(&callback);
    if(laser->Initialize())
    {
        if(laser->StartCaptureThread())
        {
            while (1)
            {
                std::cout << MiddleScanDistanceInches(callback.mLaserScan)
                          << std::endl;
                boost::this_thread::sleep(boost::posix_time::millisec(10));
            }
            laser->Shutdown();
            delete laser;
        }
    }

    return 0;
}
#endif

//#define TESTDYNAMIXELSPEED
#ifdef TESTDYNAMIXELSPEED

int main()
{
    Motor::Dynamixel* motor = new Motor::Dynamixel();
    double rpm = 0.0;
    int dir;
    bool clockwise = true;
    if(motor->Initialize())
    {
        motor->SetSpeedRpm(rpm, clockwise);
        while (1)
        {
            cout << "Input Speed in RPM (0-114): " << endl;
            cin >> rpm;
            cout << "Input direction (0 = CCW, 1 = CW): " << endl;
            cin >> dir;
            if(dir)
                clockwise = true;
            else
                clockwise = false;
            motor->SetSpeedRpm(rpm, clockwise);
        }
    }
   return 0;
}
#endif

//#define TESTDYNAMIXELFEEDBACK
#ifdef TESTDYNAMIXELFEEDBACK

int main()
{
    Motor::Dynamixel* motor = new Motor::Dynamixel();
    double rpm = 10.0;
    if(motor->Initialize())
    {
        motor->SetSpeedRpm(rpm, true);
        while (1)
        {
            cout << motor->GetPositionDegrees() << endl;
            usleep(10000);
        }
    }
   return 0;
}
#endif

/** This test tells the motor to move at 10 RPM and sets a timer at the
    start of the sequence, upon 1 revolution it will print the time
    elapsed. Theoretically it should be 6 seconds exactly given 10 RPM.*/
#define TESTDYNAMIXELSPEEDACCURACY
#ifdef TESTDYNAMIXELSPEEDACCURACY

int main()
{
    Motor::Dynamixel* motor = new Motor::Dynamixel();
    double rpm = 10.0; // 10 RPM / 60 = .16667 Hz ^ -1 = 6 secs
    double degrees = 0;
    double lowthres = 0;
    double hghthres = 0;
    double difseconds = 0;
    double curpos = 0;
    timespec t1, t2, dif;
    if(motor->Initialize())
    {
        delayMicroseconds(250000);
        motor->SetSpeedRpm(0, true);
        delayMicroseconds(750000);
        degrees = motor->GetPositionDegrees();
        lowthres = degrees - 0.3;
        hghthres = degrees + 0.3;
        motor->SetSpeedRpm(rpm, true);
        delayMicroseconds(40000);
        clock_gettime(CLOCK_MONOTONIC, &t1);
        while (1)
        {
            curpos = motor->GetPositionDegrees();
            if(curpos >= lowthres && curpos <= hghthres)
            {
                clock_gettime(CLOCK_MONOTONIC, &t2);
                dif = diff(t1, t2);
                double decimalsecs = (double) dif.tv_nsec;
                decimalsecs /= 1000000000.;
                difseconds = dif.tv_sec + decimalsecs;
                cout << setprecision(7) << difseconds << endl;
                motor->SetSpeedRpm(0, true);
                delayMicroseconds(250000);
                break;
            }
        }
    }
   return 0;
}
#endif

//#define TESTTIMING
#ifdef TESTTIMING
int main()
{
    timespec t1, t2;
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t1);
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t2);
    unsigned int i = 0;
    while(1)
    {
        if(diff(t1, t2).tv_sec >= 1)
        {
            i++;
            std::cout << diff(t1, t2).tv_nsec <<" Sec Elapsed" << std::endl;
            clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t1);
            clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t2);
        }
        else
        {
            clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t2);
        }
    }
    return 0;
}

#endif

//#define TESTSERVER
#ifdef TESTSERVER
/**
 *  http://julien.boucaron.free.fr/wordpress/?p=178
 */

#include <iostream>
#include <fstream>
#include <string>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

int main()
{
  try
  {
        //double xyz[] = {-1000,45,987};
        int size = 16384;
        //create random data
        double *xyz= new double[size];
        for(int i = 0;i<size;i++)
            xyz[i] = i;

    const unsigned int port = 10000; //port the server listen
    const unsigned int buff_size = 16384; //size of the send buffer

    boost::asio::io_service io_service; //main asio object
    tcp::endpoint endpoint(tcp::v4(), port); //endpoint
    tcp::acceptor acceptor(io_service, endpoint);  //we accept connection there

    //server loop
    while(1) {
        std::cout<<"Server Listening"<<std::endl;
      tcp::socket socket(io_service);  //create a socket
      acceptor.accept(socket); //attach to the acceptor
      //we have got a new connection !
      std::cout<<"Got a connection!"<<std::endl;
      std::cout << " Remote @:port  " << socket.remote_endpoint().address() << " : "
        << socket.remote_endpoint().port() << std::endl;

      char* buff = new char[buff_size]; //creating the buffer
      unsigned int count = 0; //counter
      std::cout << "Sending" << std::endl;

     for(int i = 0;i<1;i++){
        //memset(buff,0,buff_size); //cleanup the buffer

       // const char * px = reinterpret_cast<const char*>(&xyz);
          const char * px = reinterpret_cast<const char*>(xyz);
        boost::system::error_code ignored_error;
        unsigned int len = sizeof(xyz);
        boost::asio::write(socket, boost::asio::buffer(px,sizeof(double)*size),
                   boost::asio::transfer_all(), ignored_error); //send
        count+=len; //increment counter
     }

      delete(buff);  //delete buffer
      std::cout << "Finished" << std::endl;
      std::cout << "Sent "  << count << " bytes" << std::endl;
    }

  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
#endif

//#define TESTISR
#ifdef TESTISR

#define BUTTON_PIN 0
volatile int eventCounter = 0;
void myInterrupt(void) {eventCounter++;}

int main()
{

    if (wiringPiSetup () < 0) {
          fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno));
          return 1;
      }

      // set Pin 17/0 generate an interrupt on high-to-low transitions
      // and attach myInterrupt() to the interrupt
      if ( wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0 ) {
          fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno));
          return 1;
      }

      // display counter value every second.
      while ( 1 ) {
        printf( "%d\n", eventCounter );
        eventCounter = 0;
        delay( 1000 ); // wait 1 second
      }

      return 0;
}

#endif

//#define TESTIMAGEGENERATION
#ifdef TESTIMAGEGENERATION
int main()
{

   return 0;
}
#endif

timespec diff(timespec start, timespec end)
{
    timespec temp;
    if((end.tv_nsec - start.tv_nsec) < 0)
    {
        temp.tv_sec = end.tv_sec - start.tv_sec - 1;
        temp.tv_nsec = 1000000000L + end.tv_nsec - start.tv_nsec;
    }
    else
    {
        temp.tv_sec = end.tv_sec - start.tv_sec;
        temp.tv_nsec = end.tv_nsec - start.tv_nsec;
    }
    return temp;
}

/** End of File */
<|endoftext|>


<commit_before>/*************************************
** Tsunagari Tile Engine            **
** pack.cpp                         **
** Copyright 2016-2017 Paul Merrill **
*************************************/

// **********
// 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.
// **********

#include "resources/pack.h"

#include <limits>
#include <mutex>

#include "core/formatter.h"
#include "core/log.h"
#include "core/measure.h"

#include "data/data-world.h"

Resources& Resources::instance() {
    static auto globalResources = new PackResources;
    return *globalResources;
}

PackResource::PackResource(void* data, size_t size)
    : _data(static_cast<char*>(data)), _size(size) {}

const void* PackResource::data() const {
    return _data;
}

size_t PackResource::size() const {
    return _size;
}

PackResources::PackResources() {
    const std::string& path = DataWorld::instance().datafile;

    pack = PackReader::fromFile(path);
    if (!pack) {
        Log::fatal("PackResources",
                   Formatter("%: could not open archive") % path);
    }
}

Unique<Resource> PackResources::load(const std::string& path) {
    std::lock_guard<std::mutex> lock(mutex);

    TimeMeasure m("Mapped " + path);

    const std::string fullPath = DataWorld::instance().datafile + "/" + path;

    PackReader::BlobIndex index = pack->findIndex(path);

    if (index == PackReader::BLOB_NOT_FOUND) {
        Log::err("PackResources", Formatter("%: file missing") % fullPath);
        return Unique<Resource>();
    }

    uint64_t blobSize = pack->getBlobSize(index);

    // Will it fit in memory?
    if (blobSize > std::numeric_limits<size_t>::max()) {
        Log::err("PackResources", Formatter("%: file too large") % fullPath);
        return Unique<Resource>();;
    }

    void* blobData = pack->getBlobData(index);

    return Unique<Resource>(new PackResource(blobData, blobSize));
}
<commit_msg>resources/pack: Remove measure<commit_after>/*************************************
** Tsunagari Tile Engine            **
** pack.cpp                         **
** Copyright 2016-2017 Paul Merrill **
*************************************/

// **********
// 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.
// **********

#include "resources/pack.h"

#include <limits>
#include <mutex>

#include "core/formatter.h"
#include "core/log.h"
#include "core/measure.h"

#include "data/data-world.h"

Resources& Resources::instance() {
    static auto globalResources = new PackResources;
    return *globalResources;
}

PackResource::PackResource(void* data, size_t size)
    : _data(static_cast<char*>(data)), _size(size) {}

const void* PackResource::data() const {
    return _data;
}

size_t PackResource::size() const {
    return _size;
}

PackResources::PackResources() {
    const std::string& path = DataWorld::instance().datafile;

    pack = PackReader::fromFile(path);
    if (!pack) {
        Log::fatal("PackResources",
                   Formatter("%: could not open archive") % path);
    }
}

Unique<Resource> PackResources::load(const std::string& path) {
    std::lock_guard<std::mutex> lock(mutex);

    //TimeMeasure m("Mapped " + path);

    const std::string fullPath = DataWorld::instance().datafile + "/" + path;

    PackReader::BlobIndex index = pack->findIndex(path);

    if (index == PackReader::BLOB_NOT_FOUND) {
        Log::err("PackResources", Formatter("%: file missing") % fullPath);
        return Unique<Resource>();
    }

    uint64_t blobSize = pack->getBlobSize(index);

    // Will it fit in memory?
    if (blobSize > std::numeric_limits<size_t>::max()) {
        Log::err("PackResources", Formatter("%: file too large") % fullPath);
        return Unique<Resource>();;
    }

    void* blobData = pack->getBlobData(index);

    return Unique<Resource>(new PackResource(blobData, blobSize));
}
<|endoftext|>