Explorar el Código

device: add help command

Daniele Bartolini hace 5 años
padre
commit
d8f21c61a4
Se han modificado 4 ficheros con 73 adiciones y 28 borrados
  1. 1 0
      docs/changelog.rst
  2. 62 21
      src/device/console_server.cpp
  3. 4 1
      src/device/console_server.h
  4. 6 6
      src/device/device.cpp

+ 1 - 0
docs/changelog.rst

@@ -7,6 +7,7 @@ Changelog
 
 **Runtime**
 
+* Added "help" command
 * Core primitives now include UV, tangent and bitangent data
 * Fixed a crash when multiple clients were connected to the Console Server
 * Fixed a crash when reloading lua scripts that haden't been loaded previously

+ 62 - 21
src/device/console_server.cpp

@@ -14,31 +14,68 @@
 #include "core/strings/string_stream.inl"
 #include "device/console_server.h"
 
+LOG_SYSTEM(CONSOLE_SERVER, "console_server")
+
 namespace crown
 {
-static void console_server_command(ConsoleServer& cs, TCPSocket& client, const char* json, void* /*user_data*/)
+namespace console_server_internal
 {
-	TempAllocator4096 ta;
-	JsonObject obj(ta);
-	JsonArray args(ta);
+	static void message_command(ConsoleServer& cs, TCPSocket& client, const char* json, void* /*user_data*/)
+	{
+		TempAllocator4096 ta;
+		JsonObject obj(ta);
+		JsonArray args(ta);
 
-	sjson::parse(obj, json);
-	sjson::parse_array(args, obj["args"]);
+		sjson::parse(obj, json);
+		sjson::parse_array(args, obj["args"]);
 
-	DynamicString command_name(ta);
-	sjson::parse_string(command_name, args[0]);
+		DynamicString command_name(ta);
+		sjson::parse_string(command_name, args[0]);
 
-	ConsoleServer::CommandData cmd;
-	cmd.command_function = NULL;
-	cmd.user_data = NULL;
-	cmd = hash_map::get(cs._commands, command_name.to_string_id(), cmd);
+		ConsoleServer::CommandData cmd;
+		cmd.command_function = NULL;
+		cmd.user_data = NULL;
+		cmd = hash_map::get(cs._commands, command_name.to_string_id(), cmd);
 
-	if (cmd.command_function != NULL)
-		cmd.command_function(cs, client, args, cmd.user_data);
-}
+		if (cmd.command_function != NULL)
+			cmd.command_function(cs, client, args, cmd.user_data);
+	}
+
+	static void command_help(ConsoleServer& cs, TCPSocket& client, JsonArray& args, void* /*user_data*/)
+	{
+		if (array::size(args) != 1)
+		{
+			cs.error(client, "Usage: help");
+			return;
+		}
+
+		u32 longest = 0;
+
+		auto cur = hash_map::begin(cs._commands);
+		auto end = hash_map::end(cs._commands);
+		for (; cur != end; ++cur)
+		{
+			HASH_MAP_SKIP_HOLE(cs._commands, cur);
+
+			if (longest < strlen32(cur->second.name))
+				longest = strlen32(cur->second.name);
+		}
+
+		cur = hash_map::begin(cs._commands);
+		end = hash_map::end(cs._commands);
+		for (; cur != end; ++cur)
+		{
+			HASH_MAP_SKIP_HOLE(cs._commands, cur);
+
+			logi(CONSOLE_SERVER, "%s%*s%s"
+				, cur->second.name
+				, longest - strlen32(cur->second.name) + 2
+				, " "
+				, cur->second.brief
+				);
+		}
+	}
 
-namespace console_server_internal
-{
 	static u32 add_client(ConsoleServer& cs, TCPSocket& socket)
 	{
 		const u32 id = cs._next_client_id++;
@@ -75,7 +112,8 @@ ConsoleServer::ConsoleServer(Allocator& a)
 	, _messages(a)
 	, _commands(a)
 {
-	this->register_message_type("command", console_server_command, this);
+	this->register_message_type("command", console_server_internal::message_command, this);
+	this->register_command_name("help", "List all commands", console_server_internal::command_help, this);
 }
 
 void ConsoleServer::listen(u16 port, bool wait)
@@ -217,15 +255,18 @@ void ConsoleServer::update()
 		console_server_internal::remove_client(*this, to_remove[ii]);
 }
 
-void ConsoleServer::register_command_type(const char* type, CommandTypeFunction function, void* user_data)
+void ConsoleServer::register_command_name(const char* name, const char* brief, CommandTypeFunction function, void* user_data)
 {
-	CE_ENSURE(NULL != type);
+	CE_ENSURE(NULL != name);
+	CE_ENSURE(NULL != brief);
 	CE_ENSURE(NULL != function);
 
 	CommandData cmd;
 	cmd.command_function = function;
 	cmd.user_data = user_data;
-	hash_map::set(_commands, StringId32(type), cmd);
+	strncpy(cmd.name, name, sizeof(cmd.name)-1);
+	strncpy(cmd.brief, brief, sizeof(cmd.brief)-1);
+	hash_map::set(_commands, StringId32(name), cmd);
 }
 
 void ConsoleServer::register_message_type(const char* type, MessageTypeFunction function, void* user_data)

+ 4 - 1
src/device/console_server.h

@@ -28,7 +28,10 @@ struct ConsoleServer
 			CommandTypeFunction command_function;
 			MessageTypeFunction message_function;
 		};
+
 		void* user_data;
+		char name[32];
+		char brief[128];
 	};
 
 	struct Client
@@ -69,7 +72,7 @@ struct ConsoleServer
 	void log(LogSeverity::Enum sev, const char* system, const char* msg);
 
 	// Registers the command @a type.
-	void register_command_type(const char* type, CommandTypeFunction cmd, void* user_data);
+	void register_command_name(const char* name, const char* brief, CommandTypeFunction cmd, void* user_data);
 
 	/// Registers the message @a type.
 	void register_message_type(const char* type, MessageTypeFunction cmd, void* user_data);

+ 6 - 6
src/device/device.cpp

@@ -169,17 +169,17 @@ struct BgfxAllocator : public bx::AllocatorI
 	}
 };
 
-static void command_device_pause(ConsoleServer& /*cs*/, TCPSocket& /*client*/, JsonArray& /*args*/, void* /*user_data*/)
+static void device_command_pause(ConsoleServer& /*cs*/, TCPSocket& /*client*/, JsonArray& /*args*/, void* /*user_data*/)
 {
 	device()->pause();
 }
 
-static void command_device_unpause(ConsoleServer& /*cs*/, TCPSocket& /*client*/, JsonArray& /*args*/, void* /*user_data*/)
+static void device_command_unpause(ConsoleServer& /*cs*/, TCPSocket& /*client*/, JsonArray& /*args*/, void* /*user_data*/)
 {
 	device()->unpause();
 }
 
-static void command_device_refresh(ConsoleServer& /*cs*/, TCPSocket& /*client*/, JsonArray& /*args*/, void* /*user_data*/)
+static void device_command_refresh(ConsoleServer& /*cs*/, TCPSocket& /*client*/, JsonArray& /*args*/, void* /*user_data*/)
 {
 	device()->refresh();
 }
@@ -268,9 +268,9 @@ void Device::run()
 {
 	s64 run_t0 = time::now();
 
-	_console_server->register_command_type("pause", command_device_pause, this);
-	_console_server->register_command_type("unpause", command_device_unpause, this);
-	_console_server->register_command_type("refresh", command_device_refresh, this);
+	_console_server->register_command_name("pause", "Pause the engine", device_command_pause, this);
+	_console_server->register_command_name("unpause", "Resume the engine", device_command_unpause, this);
+	_console_server->register_command_name("refresh", "Reload all changed resources", device_command_refresh, this);
 
 	_console_server->listen(_options._console_port, _options._wait_console);