Code for logging and replay (doesn't work because of nondet in lua)
This commit is contained in:
@@ -4,10 +4,10 @@
|
||||
|
||||
#include "wrap-string.hpp"
|
||||
#include "wrap-vector.hpp"
|
||||
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <string_view>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include "drivenengine.hpp"
|
||||
|
||||
namespace drv {
|
||||
|
||||
@@ -16,17 +16,116 @@ void split_host_port(std::string_view target, std::string &host, std::string &po
|
||||
std::vector<std::string> parse_control_lst(std::string_view ctrl);
|
||||
|
||||
|
||||
class ReplayRecorder {
|
||||
private:
|
||||
std::ofstream f_;
|
||||
UniqueDrivenEngine e_;
|
||||
bool logging_;
|
||||
|
||||
void flush();
|
||||
public:
|
||||
// Initialization consists of three steps:
|
||||
//
|
||||
// 1. The constructor, which creates an empty ReplayRecorder.
|
||||
// 2. Open the logfile for writing, if desired, using open_logfile.
|
||||
// 3. Make the engine, using create_engine.
|
||||
//
|
||||
// After that, you can use drv_xxx methods to send messages to the
|
||||
// engine. These messages will get logged if the replay log is open.
|
||||
//
|
||||
ReplayRecorder() : logging_(false) {}
|
||||
|
||||
// Write encoded data to a replay log.
|
||||
void wlog_byte(std::ostream &s, uint8_t byte);
|
||||
void wlog_uint16(std::ostream &s, uint16_t v);
|
||||
void wlog_string(std::ostream &s, std::string_view v);
|
||||
// Open the logfile.
|
||||
//
|
||||
// If you're going to open a logfile, you must do so before
|
||||
// creating the engine. Returns false if the logfile couldn't be
|
||||
// opened.
|
||||
//
|
||||
bool open_logfile(const char *fn);
|
||||
|
||||
// Read encoded data from a file.
|
||||
uint8_t rlog_byte(std::istream &s);
|
||||
uint16_t rlog_uint16(std::istream &s);
|
||||
std::string_view rlog_string(std::istream &s, char *buf, size_t buflen);
|
||||
// Create the DrivenEngine.
|
||||
//
|
||||
// Returns false if the DrivenEngine couldn't be created.
|
||||
//
|
||||
bool create_engine(const char *kind);
|
||||
|
||||
}
|
||||
// These don't need to be logged.
|
||||
//
|
||||
const eng::vector<int> &drv_get_listen_ports() const { return e_->drv_get_listen_ports(); }
|
||||
const eng::vector<int> &drv_get_new_outgoing() const { return e_->drv_get_new_outgoing(); }
|
||||
const eng::string &drv_get_target(int chid) const { return e_->drv_get_target(chid); }
|
||||
bool drv_outgoing_empty(int chid) const { return e_->drv_outgoing_empty(chid); }
|
||||
bool drv_get_channel_released(int chid) const { return e_->drv_get_channel_released(chid); }
|
||||
std::string_view drv_peek_outgoing(int chid) const { return e_->drv_peek_outgoing(chid); }
|
||||
bool drv_get_rescan_lua_source() const { return e_->drv_get_rescan_lua_source(); }
|
||||
bool drv_get_stop_driver() const { return e_->drv_get_stop_driver(); }
|
||||
|
||||
// These operations do need to be logged.
|
||||
//
|
||||
void drv_clear_new_outgoing();
|
||||
void drv_sent_outgoing(int chid, int nbytes);
|
||||
void drv_recv_incoming(int chid, std::string_view data);
|
||||
void drv_notify_close(int chid, std::string_view err);
|
||||
int drv_notify_accept(int port);
|
||||
void drv_clear_lua_source();
|
||||
void drv_add_lua_source(std::string_view fn, std::string_view data);
|
||||
void drv_invoke_event_init(int argc, char *argv[]);
|
||||
void drv_invoke_event_update(double clock);
|
||||
};
|
||||
|
||||
class ReplayPlayer {
|
||||
public:
|
||||
enum Error {
|
||||
ERR_NONE,
|
||||
ERR_OPEN_LOGFILE,
|
||||
ERR_LOGFILE_EOF,
|
||||
ERR_LOGFILE_CORRUPT,
|
||||
ERR_NONDERMINISTIC,
|
||||
ERR_CREATE_ENGINE,
|
||||
};
|
||||
private:
|
||||
std::ifstream f_;
|
||||
UniqueDrivenEngine e_;
|
||||
std::unique_ptr<char[]> buf_;
|
||||
Error error_;
|
||||
std::string logfn_;
|
||||
std::string engine_;
|
||||
|
||||
void set_error(Error e);
|
||||
|
||||
void create_engine();
|
||||
void drv_clear_new_outgoing();
|
||||
void drv_sent_outgoing();
|
||||
void drv_recv_incoming();
|
||||
void drv_notify_close();
|
||||
void drv_notify_accept();
|
||||
void drv_clear_lua_source();
|
||||
void drv_add_lua_source();
|
||||
void drv_invoke_event_init();
|
||||
void drv_invoke_event_update();
|
||||
public:
|
||||
ReplayPlayer();
|
||||
|
||||
// Open the logfile for reading.
|
||||
//
|
||||
// Returns false if the logfile can't be opened.
|
||||
//
|
||||
bool open_logfile(const char *fn);
|
||||
|
||||
// Execute a single step from the replay log.
|
||||
//
|
||||
// Returns an error code, which is usually ERR_NONE.
|
||||
// If it's anything else, display an error and stop.
|
||||
//
|
||||
Error step();
|
||||
|
||||
// Print an error message.
|
||||
//
|
||||
// Print a message associated with the most recent error.
|
||||
//
|
||||
void print_error(std::ostream &s);
|
||||
};
|
||||
|
||||
} // namespace drv
|
||||
|
||||
#endif // DRIVER_UTIL_HPP
|
||||
|
||||
Reference in New Issue
Block a user