/*
* music_message_in_proxy.h
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef MUSIC_MESSAGE_IN_PROXY_H
#define MUSIC_MESSAGE_IN_PROXY_H
#include "config.h"
#ifdef HAVE_MUSIC
#include <vector>
#include <string>
#include "nest.h"
#include "node.h"
#include "communicator.h"
#include "arraydatum.h"
#include "dictutils.h"
#include "mpi.h"
#include "music.hh"
/*BeginDocumentation
Name: music_message_in_proxy - A device which receives message strings from MUSIC.
Description:
A music_message_in_proxy can be used to receive message strings from
remote MUSIC applications in NEST.
It uses the MUSIC library to receive message strings from other
applications. The music_message_in_proxy represents an input port to
which MUSIC can connect a message source. The music_message_in_proxy
can queried using GetStatus to retrieve the messages.
Parameters:
The following properties are available in the status dictionary:
port_name - The name of the MUSIC input port to listen to (default:
message_in)
port_width - The width of the MUSIC input port
data - A sub-dictionary that contains the string messages
in the form of two arrays:
messages - The strings
message_times - The times the messages were sent (ms)
n_messages - The number of messages.
published - A bool indicating if the port has been already published
with MUSIC
The parameter port_name can be set using SetStatus. The field n_messages
can be set to 0 to clear the data arrays.
Examples:
/music_message_in_proxy Create /mmip Set
10 Simulate
mmip GetStatus /data get /messages get 0 get /command Set
(Executing command ') command join ('.) join =
command cvx exec
Author: Jochen Martin Eppler
FirstVersion: July 2010
Availability: Only when compiled with MUSIC
SeeAlso: music_event_out_proxy, music_event_in_proxy, music_cont_in_proxy
*/
namespace nest
{
class MsgHandler : public MUSIC::MessageHandler
{
ArrayDatum messages; //!< The buffer for incoming message
std::vector<double> message_times; //!< The buffer for incoming message
void operator()(double t, void* msg, size_t size)
{
message_times.push_back(t * 1000.0);
messages.push_back(std::string(static_cast<char*>(msg), size));
}
public:
void get_status(DictionaryDatum &d) const
{
DictionaryDatum dict(new Dictionary);
(*dict)["messages"] = messages;
(*dict)["message_times"] = DoubleVectorDatum(new std::vector<double>(message_times));
(*d)["n_messages"] = messages.size();
(*d)["data"] = dict;
}
void clear()
{
message_times.clear();
messages.clear();
}
};
/**
* Emit spikes at times received from another application via a
* MUSIC port. The timestamps of the events also contain offsets,
* which makes it also useful for precise spikes.
*/
class music_message_in_proxy : public Node
{
public:
music_message_in_proxy();
music_message_in_proxy(const music_message_in_proxy&);
bool has_proxies() const {return false;}
bool one_node_per_process() const {return true;}
void get_status(DictionaryDatum &) const;
void set_status(const DictionaryDatum &);
private:
void init_state_(const Node&);
void init_buffers_();
void calibrate();
void update(Time const &, const long_t, const long_t) {}
// ------------------------------------------------------------
struct State_;
struct Parameters_ {
std::string port_name_; //!< the name of MUSIC port to connect to
double acceptable_latency_; //!< the acceptable latency of the port
Parameters_(); //!< Sets default parameter values
Parameters_(const Parameters_&); //!< Recalibrate all times
void get(DictionaryDatum&) const;
/**
* Set values from dicitonary.
*/
void set(const DictionaryDatum&, State_&);
};
// ------------------------------------------------------------
struct State_ {
bool published_; //!< indicates whether this node has been published already with MUSIC
int port_width_; //!< the width of the MUSIC port
State_(); //!< Sets default state value
void get(DictionaryDatum&) const; //!< Store current values in dictionary
void set(const DictionaryDatum&, const Parameters_&); //!< Set values from dicitonary
};
// ------------------------------------------------------------
struct Buffers_ {
MsgHandler message_handler_;
};
// ------------------------------------------------------------
struct Variables_ {
MUSIC::MessageInputPort *MP_; //!< The MUSIC cont port for input of data
};
// ------------------------------------------------------------
Parameters_ P_;
State_ S_;
Buffers_ B_;
Variables_ V_;
};
inline
void music_message_in_proxy::get_status(DictionaryDatum &d) const
{
P_.get(d);
S_.get(d);
B_.message_handler_.get_status(d);
}
inline
void music_message_in_proxy::set_status(const DictionaryDatum &d)
{
Parameters_ ptmp = P_; // temporary copy in case of errors
ptmp.set(d, S_); // throws if BadProperty
State_ stmp = S_;
stmp.set(d, P_); // throws if BadProperty
long_t nm = 0;
if ( updateValue<long_t>(d, "n_messages", nm) )
{
if ( nm == 0 )
B_.message_handler_.clear();
else
throw BadProperty("n_messaged can only be set to 0.");
}
// if we get here, temporaries contain consistent set of properties
P_ = ptmp;
S_ = stmp;
}
} // namespace
#endif
#endif /* #ifndef MUSIC_MESSAGE_IN_PROXY_H */