
/******************************************************************************
* MODULE     : command.cpp
* DESCRIPTION: Abstract dynamic commands
* COPYRIGHT  : (C) 1999  Joris van der Hoeven
*******************************************************************************
* This software falls under the GNU general public license version 3 or later.
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
******************************************************************************/

#include "command.hpp"
#include "scheme.hpp"

/******************************************************************************
* default implementation of command application with arguments
******************************************************************************/

void
command_rep::apply (object args) {
  (void) args;
  apply ();
}

void
command::operator () (object args) {
  rep->apply (args);
}

void
apply (command cmd, object args) {
  cmd (args);
}

/******************************************************************************
* standard commands without arguments
******************************************************************************/

class std_command_rep: public command_rep {
  void (*routine) (void);
public:
  std_command_rep (void (*routine) (void));
  void apply ();
  tm_ostream& print (tm_ostream& out) {
    return out << "<command std>"; }
};

std_command_rep::std_command_rep (void (*routine2) (void)):
  routine (routine2) {}
void std_command_rep::apply () { routine (); }

command::command (void (*routine) (void)) :
  rep (tm_new<std_command_rep> (routine)) { INC_COUNT(rep); }


/******************************************************************************
* callbacks
******************************************************************************/

class generic_command_rep: public command_rep {
  void (*callback) (void*, void*); // callback
  void *obj; // argument for callback
  void *info; // additional info
  
public:
  generic_command_rep (void (*_callback) (void*, void*),
                       void *_obj, void *_info):
    callback (_callback), obj (_obj), info (_info) {}
  void apply () { if (callback) callback (obj, info); }
  tm_ostream& print (tm_ostream& out) {
    return out << "<command generic>"; }
};

command::command (void (*_callback) (void*, void*), void *_obj, void *_info) :
  rep (tm_new<generic_command_rep> (_callback, _obj, _info)) { INC_COUNT(rep); }
