blob: 38538f4c799d3b9599d2242d69e8b104e21d9b76 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if defined(ENABLE_DEBUG_CONSOLE)
#include "cobalt/debug/debug_hub.h"
#include <set>
#include "base/compiler_specific.h"
#include "cobalt/base/c_val.h"
#include "cobalt/base/console_commands.h"
#include "cobalt/base/source_location.h"
namespace cobalt {
namespace debug {
namespace {
class ScopedSetter {
public:
explicit ScopedSetter(bool* to_set) : to_set_(to_set) {
DCHECK(to_set_);
*to_set_ = true;
}
~ScopedSetter() { *to_set_ = false; }
private:
bool* to_set_;
};
} // namespace
DebugHub::DebugHub(
const GetHudModeCallback& get_hud_mode_callback,
const Debugger::GetDebugServerCallback& get_debug_server_callback)
: message_loop_(MessageLoop::current()),
get_hud_mode_callback_(get_hud_mode_callback),
debugger_(new Debugger(get_debug_server_callback)),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
weak_ptr_(weak_ptr_factory_.GetWeakPtr()),
is_logging_(false) {
// Get log output while still making it available elsewhere.
const base::LogMessageHandler::OnLogMessageCallback on_log_message_callback =
base::Bind(&DebugHub::OnLogMessage, base::Unretained(this));
log_message_handler_callback_id_ =
base::LogMessageHandler::GetInstance()->AddCallback(
on_log_message_callback);
}
DebugHub::~DebugHub() {
base::LogMessageHandler::GetInstance()->RemoveCallback(
log_message_handler_callback_id_);
}
void DebugHub::TraceMembers(script::Tracer* tracer) {
tracer->Trace(debugger_);
}
bool DebugHub::OnLogMessage(int severity, const char* file, int line,
size_t message_start, const std::string& str) {
// Don't run recursively.
if (MessageLoop::current() == message_loop_ && is_logging_) {
return false;
}
message_loop_->PostTask(FROM_HERE,
base::Bind(&DebugHub::OnLogMessageInternal, weak_ptr_,
severity, file, line, message_start, str));
// Don't suppress the log message.
return false;
}
void DebugHub::OnLogMessageInternal(int severity, const char* file, int line,
size_t message_start,
const std::string& str) {
DCHECK(this);
DCHECK_EQ(MessageLoop::current(), message_loop_);
if (log_message_callback_) {
ScopedSetter scoped_setter(&is_logging_);
log_message_callback_->value().Run(severity, file, line, message_start,
str);
}
}
void DebugHub::SetLogMessageCallback(const LogMessageCallbackArg& callback) {
DCHECK(MessageLoop::current() == message_loop_);
log_message_callback_.reset(
new LogMessageCallbackArg::Reference(this, callback));
}
// TODO: This function should be modified to return an array of strings instead
// of a single space-separated string, once the bindings support return of a
// string array.
std::string DebugHub::GetConsoleValueNames() const {
std::string ret = "";
base::CValManager* cvm = base::CValManager::GetInstance();
DCHECK(cvm);
if (cvm) {
std::set<std::string> names = cvm->GetOrderedCValNames();
for (std::set<std::string>::const_iterator it = names.begin();
it != names.end(); ++it) {
ret += (*it);
std::set<std::string>::const_iterator next = it;
++next;
if (next != names.end()) {
ret += " ";
}
}
}
return ret;
}
std::string DebugHub::GetConsoleValue(const std::string& name) const {
std::string ret = "<undefined>";
base::CValManager* cvm = base::CValManager::GetInstance();
DCHECK(cvm);
if (cvm) {
base::optional<std::string> result = cvm->GetValueAsPrettyString(name);
if (result) {
return *result;
}
}
return ret;
}
int DebugHub::GetDebugConsoleMode() const {
return get_hud_mode_callback_.Run();
}
// TODO: This function should be modified to return an array of strings instead
// of a single space-separated string, once the bindings support return of a
// string array.
std::string DebugHub::GetCommandChannels() const {
std::string result = "";
base::ConsoleCommandManager* command_mananger =
base::ConsoleCommandManager::GetInstance();
DCHECK(command_mananger);
if (command_mananger) {
std::set<std::string> channels = command_mananger->GetRegisteredChannels();
for (std::set<std::string>::const_iterator it = channels.begin();
it != channels.end(); ++it) {
result += (*it);
std::set<std::string>::const_iterator next = it;
++next;
if (next != channels.end()) {
result += " ";
}
}
}
return result;
}
std::string DebugHub::GetCommandChannelShortHelp(
const std::string& channel) const {
std::string result = "<undefined>";
base::ConsoleCommandManager* command_mananger =
base::ConsoleCommandManager::GetInstance();
DCHECK(command_mananger);
if (command_mananger) {
result = command_mananger->GetShortHelp(channel);
}
return result;
}
std::string DebugHub::GetCommandChannelLongHelp(
const std::string& channel) const {
std::string result = "<undefined>";
base::ConsoleCommandManager* command_mananger =
base::ConsoleCommandManager::GetInstance();
DCHECK(command_mananger);
if (command_mananger) {
result = command_mananger->GetLongHelp(channel);
}
return result;
}
void DebugHub::SendCommand(const std::string& channel,
const std::string& message) {
base::ConsoleCommandManager* console_command_manager =
base::ConsoleCommandManager::GetInstance();
DCHECK(console_command_manager);
console_command_manager->HandleCommand(channel, message);
}
} // namespace debug
} // namespace cobalt
#endif // ENABLE_DEBUG_CONSOLE