Create hybrid authority model for command processing.
This commit is contained in:
parent
dbe6e437ad
commit
a73aa4feaf
@ -5,54 +5,60 @@
|
|||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
|
|
||||||
#include "client_network.h"
|
#include "client_network.h"
|
||||||
|
#include "command_processor.h"
|
||||||
#include "gfx/txt_renderer.h"
|
#include "gfx/txt_renderer.h"
|
||||||
|
#include "vfs_manager.h"
|
||||||
|
#include "vfs.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
Terminal::Terminal(void) {
|
Terminal::Terminal(void) {
|
||||||
/* Placeholder welcome message to history. */
|
/* Placeholder welcome message to history. */
|
||||||
_history.push_back("Welcome to Bettola");
|
_history.push_back("Welcome to Bettola (local mode)");
|
||||||
_network = new ClientNetwork();
|
_network = nullptr; /* No network connection for now. */
|
||||||
if(_network->connect("localhost", 8080)) {
|
|
||||||
_history.push_back("Connection to server Success!");
|
/* Create local file system for the client. */
|
||||||
} else {
|
_local_vfs = vfs_manager::create_root_system();
|
||||||
_history.push_back("Connection to server failed!");
|
_local_cmd_processor = new CommandProcessor(_local_vfs);
|
||||||
}
|
_current_path = get_full_path(_local_cmd_processor->get_current_dir());
|
||||||
_current_path = "/";
|
|
||||||
_scroll_offset = 0;
|
_scroll_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Terminal::~Terminal(void) {
|
Terminal::~Terminal(void) {
|
||||||
delete _network;
|
if(_network) {
|
||||||
|
delete _network;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Terminal::_on_ret_press(void) {
|
void Terminal::_on_ret_press(void) {
|
||||||
|
std::string command = _input_buffer;
|
||||||
/* Add the command to history. */
|
/* Add the command to history. */
|
||||||
_history.push_back("> " + _input_buffer);
|
_history.push_back(_current_path + "> " + command);
|
||||||
|
|
||||||
/* For now, print the commmand clear buffer.
|
std::string response;
|
||||||
* TODO: Parse and execute commands.
|
/*
|
||||||
|
* All commands run locally for now.
|
||||||
|
* TODO: Remote commands.
|
||||||
*/
|
*/
|
||||||
printf("Command entered: %s\n", _input_buffer.c_str());
|
if(command == "clear") {
|
||||||
_network->send_command(_input_buffer.c_str());
|
_history.clear();
|
||||||
std::string response = _network->receive_response();
|
} else {
|
||||||
|
response = _local_cmd_processor->process_command(command);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the response is a new path for the prompt. */
|
/* Check if the response is a new path for the prompt. */
|
||||||
if(response.rfind("/", 0) == 0 && response.find('\n') == std::string::npos) {
|
if(response.rfind("/", 0) == 0) {
|
||||||
_current_path = response;
|
_current_path = response;
|
||||||
} else if(!response.empty()) {
|
} else if(!response.empty()) {
|
||||||
/* Otherwise, it's command out. Split it by newline and add to history. */
|
/* Otherwise, it's command out. Split it by newline and add to history. */
|
||||||
std::stringstream ss(response);
|
std::stringstream ss(response);
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(ss, line, '\n')) {
|
while(std::getline(ss, line, '\n')) {
|
||||||
_history.push_back(line);
|
if(!line.empty()) {
|
||||||
|
_history.push_back(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_input_buffer == "clear") {
|
|
||||||
_history.clear();
|
|
||||||
} else if(_input_buffer == "help") {
|
|
||||||
_history.push_back("Commands: help, clear");
|
|
||||||
}
|
|
||||||
|
|
||||||
_input_buffer.clear();
|
_input_buffer.clear();
|
||||||
/* TODO: Ugly hack. Refactor to pass window height
|
/* TODO: Ugly hack. Refactor to pass window height
|
||||||
* We need the window height to know if we should
|
* We need the window height to know if we should
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "gfx/txt_renderer.h"
|
#include "gfx/txt_renderer.h"
|
||||||
#include "client_network.h"
|
#include "client_network.h"
|
||||||
|
#include "vfs_manager.h"
|
||||||
|
#include "command_processor.h"
|
||||||
|
|
||||||
class Terminal {
|
class Terminal {
|
||||||
public:
|
public:
|
||||||
@ -22,5 +24,7 @@ private:
|
|||||||
std::vector<std::string> _history;
|
std::vector<std::string> _history;
|
||||||
int _scroll_offset;
|
int _scroll_offset;
|
||||||
std::string _current_path;
|
std::string _current_path;
|
||||||
|
vfs_node* _local_vfs;
|
||||||
|
CommandProcessor* _local_cmd_processor;
|
||||||
ClientNetwork* _network;
|
ClientNetwork* _network;
|
||||||
};
|
};
|
||||||
|
|||||||
45
common/src/command_processor.cpp
Normal file
45
common/src/command_processor.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "command_processor.h"
|
||||||
|
#include "vfs.h"
|
||||||
|
|
||||||
|
CommandProcessor::CommandProcessor(vfs_node* starting_dir) {
|
||||||
|
_current_dir = starting_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfs_node* CommandProcessor::get_current_dir(void) {
|
||||||
|
return _current_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CommandProcessor::process_command(const std::string& command) {
|
||||||
|
if(command.rfind("cd ", 0) == 0) {
|
||||||
|
std::string target_dir_name = command.substr(3);
|
||||||
|
if(target_dir_name == "..") {
|
||||||
|
if(_current_dir->parent) {
|
||||||
|
_current_dir = _current_dir->parent;
|
||||||
|
}
|
||||||
|
} else if(_current_dir->children.count(target_dir_name)) {
|
||||||
|
vfs_node* target_node = _current_dir->children[target_dir_name];
|
||||||
|
if(target_node->type == DIR_NODE) {
|
||||||
|
_current_dir = target_node;
|
||||||
|
} else {
|
||||||
|
return "cd: not a directory\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "cd: no such file or directory\n";
|
||||||
|
}
|
||||||
|
return get_full_path(_current_dir);
|
||||||
|
} else if(command == "ls") {
|
||||||
|
std::string response = "";
|
||||||
|
if(_current_dir && _current_dir->type == DIR_NODE) {
|
||||||
|
for(auto const& [name, node] : _current_dir->children) {
|
||||||
|
response += name;
|
||||||
|
if(node->type == DIR_NODE) {
|
||||||
|
response += "/";
|
||||||
|
}
|
||||||
|
response += " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown command: " + command + "\n";
|
||||||
|
}
|
||||||
16
common/src/command_processor.h
Normal file
16
common/src/command_processor.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "vfs.h"
|
||||||
|
|
||||||
|
class CommandProcessor {
|
||||||
|
public:
|
||||||
|
CommandProcessor(vfs_node* starting_dir);
|
||||||
|
|
||||||
|
std::string process_command(const std::string& command);
|
||||||
|
vfs_node* get_current_dir(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
vfs_node* _current_dir;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user