#include "drivenengine.hpp" Channel::Channel(DrivenEngine *de, int chid, int port, const std::string &target) { driven_ = de; chid_ = chid; sb_in_.reset(new StreamBuffer); sb_out_.reset(new StreamBuffer); port_ = port; closed_ = false; target_ = target; assert(driven_->channels_[chid_] == nullptr); driven_->channels_[chid_] = this; } Channel::~Channel() { assert(driven_->channels_[chid_] == this); driven_->channels_.erase(chid_); if (driven_->recent_channel_ == this) { driven_->recent_channel_ = driven_->stdio_channel_.get(); } } double DrivenEngine::get_clock() { return clock_; } std::unique_ptr DrivenEngine::new_outgoing_channel(const std::string &target) { return std::unique_ptr(new Channel(this, next_channel_id_++, 0, target)); } std::unique_ptr DrivenEngine::new_incoming_channel() { if (accepted_channels_.empty()) { return nullptr; } else { std::unique_ptr result = std::move(accepted_channels_.back()); accepted_channels_.pop_back(); return std::move(result); } } Channel *DrivenEngine::get_stdio_channel() { return stdio_channel_.get(); } util::LuaSourcePtr DrivenEngine::get_lua_source() { return std::move(lua_source_); } void DrivenEngine::rescan_lua_source() { rescan_lua_source_ = true; } void DrivenEngine::stop_driver() { stop_driver_ = true; } void DrivenEngine::drv_logmode_write(const std::string &filename, int64_t maxsize) { // NOT IMPLEMENTED YET, but it's okay as a stub. } void DrivenEngine::drv_logmode_replay(const std::string &filename) { // NOT IMPLEMENTED YET. assert(false); } void DrivenEngine::drv_logmode_none() { // NOT IMPLEMENTED YET, but it's okay as a stub. } Channel *DrivenEngine::get_chid(int chid) { // We cache the most recently used channel. if (recent_channel_->chid_ != chid) { auto iter = channels_.find(chid); assert(iter != channels_.end()); recent_channel_ = iter->second; } return recent_channel_; } void DrivenEngine::drv_list_channels(std::vector &channels) { channels.clear(); for (const auto &p : channels_) { if (!p.second->closed_) { channels.push_back(p.first); } } } const std::string &DrivenEngine::drv_get_target(int chid) { return get_chid(chid)->target_; } void DrivenEngine::drv_peek_outgoing(int chid, int *nbytes, const char **bytes) { Channel *ch = get_chid(chid); *nbytes = ch->sb_out_->fill(); *bytes = ch->sb_out_->data(); } void DrivenEngine::drv_sent_outgoing(int chid, int nbytes) { get_chid(chid)->sb_out_->read_bytes(nbytes); } void DrivenEngine::drv_recv_incoming(int chid, int nbytes, char *bytes) { if (nbytes > 0) { get_chid(chid)->sb_in_->write_bytes(bytes, nbytes); } } void DrivenEngine::drv_notify_close(int chid) { get_chid(chid)->closed_ = true; } int DrivenEngine::drv_notify_accept(int port) { int chid = next_channel_id_++; accepted_channels_.emplace_back(new Channel(this, chid, port, "")); return chid; } void DrivenEngine::drv_set_clock(double t) { clock_ = t; } void DrivenEngine::drv_set_lua_source(util::LuaSourcePtr source) { lua_source_ = std::move(source); rescan_lua_source_ = false; } void DrivenEngine::drv_invoke_event_update() { event_update(); } bool DrivenEngine::drv_get_rescan_lua_source() { return rescan_lua_source_; } bool DrivenEngine::drv_get_stop_driver() { return stop_driver_; } bool DrivenEngine::drv_step_logfile() { // NOT IMPLEMENTED assert(false); return false; } DrivenEngine::DrivenEngine() { next_channel_id_ = 1; stdio_channel_.reset(new Channel(this, 0, 0, "")); recent_channel_ = stdio_channel_.get(); rescan_lua_source_ = true; clock_ = 0.0; stop_driver_ = false; } DrivenEngine::~DrivenEngine() { // Delete the channels that we own. stdio_channel_.reset(); accepted_channels_.clear(); // At this point, all channels should be gone. assert(channels_.empty()); } static DrivenEngine *engine_; void DrivenEngine::set(DrivenEngine *de) { engine_ = de; } DrivenEngine *DrivenEngine::get() { return engine_; }