OXYGENHUB
◆ main openmsx / src / commands / TclCallback.cc
2.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "TclCallback.hh"
2
3
#include "CommandController.hh"
4
#include "CommandException.hh"
5
#include "GlobalCommandController.hh"
6
7
#include "CliComm.hh"
8
#include "Reactor.hh"
9
10
#include "checked_cast.hh"
11
12
#include <iostream>
13
#include <memory>
14
15
namespace openmsx {
16
17
TclCallback::TclCallback(
18
		CommandController& controller,
19
		std::string_view name,
20
		static_string_view description,
21
		std::string_view defaultValue,
22
		Setting::Save saveSetting,
23
		bool isMessageCallback_)
24
	: callbackSetting2(std::in_place,
25
		controller, name, description, defaultValue,
26
		saveSetting)
27
	, callbackSetting(*callbackSetting2)
28
	, isMessageCallback(isMessageCallback_)
29
{
30
}
31
32
TclCallback::TclCallback(StringSetting& setting)
33
	: callbackSetting(setting)
34
	, isMessageCallback(false)
35
{
36
}
37
38
TclObject TclCallback::getValue() const
39
{
40
	return getSetting().getValue();
41
}
42
43
TclObject TclCallback::execute() const
44
{
45
	const auto& callback = getValue();
46
	if (callback.empty()) return {};
47
48
	auto command = makeTclList(callback);
49
	return executeCommon(command);
50
}
51
52
TclObject TclCallback::execute(int arg1) const
53
{
54
	const auto& callback = getValue();
55
	if (callback.empty()) return {};
56
57
	auto command = makeTclList(callback, arg1);
58
	return executeCommon(command);
59
}
60
61
TclObject TclCallback::execute(int arg1, int arg2) const
62
{
63
	const auto& callback = getValue();
64
	if (callback.empty()) return {};
65
66
	auto command = makeTclList(callback, arg1, arg2);
67
	return executeCommon(command);
68
}
69
70
TclObject TclCallback::execute(int arg1, std::string_view arg2) const
71
{
72
	const auto& callback = getValue();
73
	if (callback.empty()) return {};
74
75
	auto command = makeTclList(callback, arg1, arg2);
76
	return executeCommon(command);
77
}
78
79
TclObject TclCallback::execute(std::string_view arg1, std::string_view arg2) const
80
{
81
	const auto& callback = getValue();
82
	if (callback.empty()) return {};
83
84
	auto command = makeTclList(callback, arg1, arg2);
85
	return executeCommon(command);
86
}
87
88
TclObject TclCallback::executeCommon(TclObject& command) const
89
{
90
	try {
91
		return command.executeCommand(callbackSetting.getInterpreter());
92
	} catch (CommandException& e) {
93
		auto message = strCat(
94
			"Error executing callback function \"",
95
			getSetting().getFullName(), "\": ", e.getMessage());
96
		auto& commandController = getSetting().getCommandController();
97
		if (!isMessageCallback) {
98
			commandController.getCliComm().printWarning(message);
99
		} else {
100
			if (checked_cast<GlobalCommandController&>(commandController).getReactor().isFullyStarted()) {
101
				std::cerr << message << '\n';
102
			} else {
103
				// This is a message callback that cannot be
104
				// executed yet.
105
				// Let the caller deal with this.
106
				throw command;
107
			}
108
		}
109
		return {};
110
	}
111
}
112
113
} // namespace openmsx