File: rinsideclient.h

package info (click to toggle)
r-cran-rinside 0.2.19-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 668 kB
  • sloc: cpp: 3,310; ansic: 117; xml: 57; ruby: 34; makefile: 2
file content (101 lines) | stat: -rw-r--r-- 2,664 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
 * Copyright (c) 2014 Christian Authmann
 */

#pragma once

#include "common/binarystream.h"
#include "common/constants.h"
#include "common/typeid.h"

#include <stdexcept>
#include <cstdint>
#include <functional>
#include <map>


#include "callback_helper.h"

class RInsideClient {
	public:

		RInsideClient(BinaryStream &stream);
		~RInsideClient();

		void parseEvalQ(const std::string &code) {
			runScript(code, 0);
			can_send_command = true;
		};

		template <typename T> T parseEval(const std::string &code) {
			runScript(code, TYPEID<T>());
			auto result = stream.read<T>();
			can_send_command = true;
			return result;
		};

		template<typename T>
		void setValue(const std::string &name, const T &value) {
			writeCommand(RIS_CMD_SETVALUE);
			stream.write(name);
			stream.write(TYPEID<T>());
			stream.write(value);

			readReply(true, false);
			can_send_command = true;
		};

		template<typename T>
		T getValue(const std::string &name) {
			writeCommand(RIS_CMD_GETVALUE);
			stream.write(name);
			stream.write(TYPEID<T>());

			readReply(false, true);

			auto type = stream.read<int32_t>();
			if (type != TYPEID<T>())
				unrecoverable_error("getValue() returned wrong type");
			auto result = stream.read<T>();
			can_send_command = true;
			return result;
		};

		template<typename R, typename... Params>
		void setCallback(const std::string &name, std::function<R(Params...)> &callback) {
			uint32_t callback_id = next_callback_id++;
			int32_t result_type = TYPEID<R>();
			size_t paramcount = sizeof...(Params);

			writeCommand(RIS_CMD_SETCALLBACK);
			stream.write(name);
			stream.write(callback_id);
			stream.write(result_type);
			stream.write(paramcount);
			// now write the types of the parameters
			callback_helper::send_pack<Params...>::send(stream);

			// remember the callback
			std::function<void(void)> func = std::bind(callback_helper::call<R, Params...>, std::ref(callback), std::ref(stream));
			callbacks[callback_id] = func;
			readReply(true, false);
			can_send_command = true;
		}

		std::string getConsoleOutput();

		void initPlot(uint32_t width=800, uint32_t height=600);
		std::string getPlot();
	private:
		void runScript(const std::string code, int32_t result_typeid);
		void writeCommand(char command);
		char readReply(bool accept_ok = true, bool accept_value = false);

		void unrecoverable_error(const std::string &error);

		BinaryStream stream;
		uint32_t next_callback_id;
		std::map<uint32_t, std::function<void(void)> > callbacks;
		bool had_unrecoverable_error;
		bool can_send_command;
};