[education/rkward] rkward/rbackend: Merge commandFinished() and fetchNextCommand()
Thomas Friedrichsmeier
null at kde.org
Sun Sep 14 19:26:16 BST 2025
Git commit 73c0da297e71dd2fb84269fb5e9c696bde13964a by Thomas Friedrichsmeier.
Committed on 12/09/2025 at 19:43.
Pushed by tfry into branch 'master'.
Merge commandFinished() and fetchNextCommand()
M +21 -31 rkward/rbackend/rkrbackend.cpp
M +5 -4 rkward/rbackend/rkrbackend.h
https://invent.kde.org/education/rkward/-/commit/73c0da297e71dd2fb84269fb5e9c696bde13964a
diff --git a/rkward/rbackend/rkrbackend.cpp b/rkward/rbackend/rkrbackend.cpp
index 4fdab9673..b9b227b4b 100644
--- a/rkward/rbackend/rkrbackend.cpp
+++ b/rkward/rbackend/rkrbackend.cpp
@@ -250,8 +250,7 @@ void RBusy(int);
static void replCommandFinished() {
RKRBackend::repl_status.user_command_status = RKRBackend::RKReplStatus::NoUserCommand;
- RKRBackend::this_pointer->commandFinished();
- RKRBackend::this_pointer->handleDeferredInterrupts();
+ RKRBackend::this_pointer->commandFinished(RKRBackend::FetchNextCommand, RKRBackend::CheckObjectUpdatesNeeded);
}
int RReadConsole(const char *prompt, unsigned char *buf, int buflen, int hist) {
@@ -270,7 +269,7 @@ int RReadConsole(const char *prompt, unsigned char *buf, int buflen, int hist) {
if ((!RKRBackend::repl_status.browser_context) && (RKRBackend::repl_status.eval_depth == 0)) {
while (true) {
if (RKRBackend::this_pointer->isKilled() || (RKRBackend::repl_status.user_command_status == RKRBackend::RKReplStatus::NoUserCommand)) {
- RCommandProxy *command = RKRBackend::this_pointer->fetchNextCommand();
+ RCommandProxy *command = RKRBackend::this_pointer->current_command;
if (!command) {
RK_DEBUG(RBACKEND, DL_DEBUG, "returning from REPL");
return 0; // jumps out of the event loop!
@@ -278,8 +277,7 @@ int RReadConsole(const char *prompt, unsigned char *buf, int buflen, int hist) {
if (!(command->type & RCommand::User)) {
RKRBackend::this_pointer->runCommand(command);
- RKRBackend::this_pointer->commandFinished();
- RKRBackend::this_pointer->handleDeferredInterrupts();
+ RKRBackend::this_pointer->commandFinished(RKRBackend::FetchNextCommand, RKRBackend::CheckObjectUpdatesNeeded);
} else {
// so, we are about to transmit a new user command, which is quite a complex endeavor...
/* Some words about running user commands:
@@ -1323,6 +1321,7 @@ void doPendingPriorityCommands() {
RCommandProxy *command = RKRBackend::this_pointer->pending_priority_command;
RKRBackend::this_pointer->pending_priority_command = nullptr;
if (command) {
+ auto prev_command = RKRBackend::this_pointer->current_command;
RK_DEBUG(RBACKEND, DL_DEBUG, "running priority command %s", qPrintable(command->command));
{
QMutexLocker lock(&RKRBackend::this_pointer->command_flow_mutex);
@@ -1331,15 +1330,11 @@ void doPendingPriorityCommands() {
}
RKRBackend::this_pointer->runCommand(command);
- // TODO: Oh boy, what a mess. Sending notifications should be split from fetchNextCommand() (which is not appropriate, here)
- RCommandProxy *previous_command_backup = RKRBackend::this_pointer->previous_command;
- RKRBackend::this_pointer->commandFinished(false);
- RKRBackend::this_pointer->previous_command = previous_command_backup;
+ RKRBackend::this_pointer->commandFinished(RKRBackend::NoFetchNextCommand, RKRBackend::NoCheckObjectUpdatesNeeded);
+ RKRBackend::this_pointer->current_command = prev_command;
{
- RBackendRequest req(false, RBackendRequest::CommandOut); // NOTE: We do *NOT* want a reply to this one, and in particular, we do *NOT* want to do
- // (recursive) event processing while handling this.
- req.command = command;
- RKRBackend::this_pointer->handleRequest(&req);
+ QMutexLocker lock(&RKRBackend::this_pointer->command_flow_mutex);
+ RKRBackend::this_pointer->current_command = prev_command;
}
}
}
@@ -1389,14 +1384,13 @@ void RKRBackend::printAndClearCapturedMessages(bool with_header) {
void RKRBackend::run(const QString &locale_dir, bool setup) {
RK_TRACE(RBACKEND);
killed = NotKilled;
- previous_command = nullptr;
initialize(locale_dir, setup);
enterEventLoop();
}
-void RKRBackend::commandFinished(bool check_object_updates_needed) {
+RCommandProxy *RKRBackend::commandFinished(FetchCommandMode fetch_next, ObjectUpdateMode check_object_updates_needed) {
RK_TRACE(RBACKEND);
RK_DEBUG(RBACKEND, DL_DEBUG, "done running command %s, status: %d", qPrintable(current_command->command), current_command->status);
@@ -1422,7 +1416,7 @@ void RKRBackend::commandFinished(bool check_object_updates_needed) {
checkObjectUpdatesNeeded(current_command->type & (RCommand::User | RCommand::ObjectListUpdate));
}
- previous_command = current_command;
+ auto previous_command = current_command;
{
QMutexLocker lock(&command_flow_mutex);
@@ -1432,7 +1426,12 @@ void RKRBackend::commandFinished(bool check_object_updates_needed) {
}
all_current_commands.pop_back();
if (!all_current_commands.isEmpty()) current_command = all_current_commands.last();
+ else current_command = nullptr;
}
+
+ RBackendRequest req(fetch_next && !isKilled(), RBackendRequest::CommandOut);
+ req.command = previous_command;
+ return RKRBackend::this_pointer->handleRequest(&req, false);
}
RCommandProxy *RKRBackend::handleRequest(RBackendRequest *request, bool mayHandleSubstack) {
@@ -1483,9 +1482,7 @@ RCommandProxy *RKRBackend::handleRequest2(RBackendRequest *request, bool mayHand
while (command) {
runCommand(command);
- commandFinished(false);
-
- command = fetchNextCommand();
+ command = commandFinished(FetchNextCommand, NoCheckObjectUpdatesNeeded);
};
handleDeferredInterrupts();
@@ -1493,16 +1490,6 @@ RCommandProxy *RKRBackend::handleRequest2(RBackendRequest *request, bool mayHand
return nullptr;
}
-RCommandProxy *RKRBackend::fetchNextCommand() {
- RK_TRACE(RBACKEND);
-
- RBackendRequest req(!isKilled(), RBackendRequest::CommandOut); // when killed, we do *not* actually wait for the reply, before the request is deleted.
- req.command = previous_command;
- previous_command = nullptr;
-
- return (handleRequest(&req, false));
-}
-
GenericRRequestResult RKRBackend::doRCallRequest(const QString &call, const QVariant ¶ms, RequestFlags flags) {
RK_TRACE(RBACKEND);
@@ -1524,7 +1511,10 @@ void RKRBackend::initialize(const QString &locale_dir, bool setup) {
// in RInterface::RInterface() we have created a fake RCommand to capture all the output/errors during startup. Fetch it
repl_status.eval_depth++;
- fetchNextCommand();
+ {
+ RBackendRequest req(true, RBackendRequest::CommandOut); // fetch the first command (a dummy)
+ handleRequest(&req, false);
+ }
RK_ASSERT(current_command);
startR();
@@ -1573,7 +1563,7 @@ void RKRBackend::initialize(const QString &locale_dir, bool setup) {
handleRequest(&req);
RK_ASSERT(current_command);
- commandFinished(); // the fake startup command
+ commandFinished(FetchNextCommand, CheckObjectUpdatesNeeded); // the fake startup command
repl_status.eval_depth--;
}
diff --git a/rkward/rbackend/rkrbackend.h b/rkward/rbackend/rkrbackend.h
index a7f683bce..9b9f77027 100644
--- a/rkward/rbackend/rkrbackend.h
+++ b/rkward/rbackend/rkrbackend.h
@@ -96,7 +96,6 @@ class RKRBackend : public RKROutputBuffer {
/** Sends a request to the frontend and returns the result (empty in case of asynchronous requests). */
GenericRRequestResult doRCallRequest(const QString &call, const QVariant &args, RequestFlags flags);
- RCommandProxy *fetchNextCommand();
/** The command currently being executed. */
RCommandProxy *current_command;
@@ -149,7 +148,11 @@ class RKRBackend : public RKROutputBuffer {
/** holds a copy of the default R_GlobalContext. Needed to find out, when a browser context has been left. */
static void *default_global_context;
- void commandFinished(bool check_object_updates_needed = true);
+ enum FetchCommandMode { NoFetchNextCommand,
+ FetchNextCommand };
+ enum ObjectUpdateMode { NoCheckObjectUpdatesNeeded,
+ CheckObjectUpdatesNeeded };
+ RCommandProxy *commandFinished(FetchCommandMode fetch_next, ObjectUpdateMode check_object_updates_needed = CheckObjectUpdatesNeeded);
/** A list of symbols that have been assigned new values during the current command */
QStringList changed_symbol_names;
/** the main loop. See \ref RKRBackend for a more detailed description */
@@ -202,8 +205,6 @@ class RKRBackend : public RKROutputBuffer {
/** check whether the object list / global environment / individual symbols have changed, and updates them, if needed */
void checkObjectUpdatesNeeded(bool check_list);
friend void doPendingPriorityCommands();
- /** The previously executed command. Only non-zero until a new command has been requested. */
- RCommandProxy *previous_command;
};
#endif
More information about the rkward-tracker
mailing list