virtualx-engine/core/script_debugger_remote.h
Pedro J. Estébanez 18fbdbb456 Reimplement Mutex with C++'s <mutex>
Main:
- It's now implemented thanks to `<mutex>`. No more platform-specific implementations.
- `BinaryMutex` (non-recursive) is added, as an alternative for special cases.
- Doesn't need allocation/deallocation anymore. It can live in the stack and be part of other classes.
- Because of that, it's methods are now `const` and the inner mutex is `mutable` so it can be easily used in `const` contexts.
- A no-op implementation is provided if `NO_THREADS` is defined. No more need to add `#ifdef NO_THREADS` just for this.
- `MutexLock` now takes a reference. At this point the cases of null `Mutex`es are rare. If you ever need that, just don't use `MutexLock`.
- Thread-safe utilities are therefore simpler now.

Misc.:
- `ScopedMutexLock` is dropped and replaced by `MutexLock`, because they were pretty much the same.
- Every case of lock, do-something, unlock is replaced by `MutexLock` (complex cases where it's not straightfoward are kept as as explicit lock and unlock).
- `ShaderRD` contained an `std::mutex`, which has been replaced by `Mutex`.
2020-02-26 20:40:10 +01:00

316 lines
8.4 KiB
C++

/*************************************************************************/
/* script_debugger_remote.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef SCRIPT_DEBUGGER_REMOTE_H
#define SCRIPT_DEBUGGER_REMOTE_H
#include "core/io/packet_peer.h"
#include "core/io/stream_peer_tcp.h"
#include "core/list.h"
#include "core/os/os.h"
#include "core/script_language.h"
class ScriptDebuggerRemote : public ScriptDebugger {
public:
class ResourceInfo {
public:
String path;
String format;
String type;
RID id;
int vram;
bool operator<(const ResourceInfo &p_img) const { return vram == p_img.vram ? id < p_img.id : vram > p_img.vram; }
ResourceInfo() {
vram = 0;
}
};
class ResourceUsage {
public:
List<ResourceInfo> infos;
Array serialize();
bool deserialize(const Array &p_arr);
};
class FrameInfo {
public:
StringName name;
float self_time;
float total_time;
FrameInfo() {
self_time = 0;
total_time = 0;
}
};
class FrameFunction {
public:
int sig_id;
int call_count;
StringName name;
float self_time;
float total_time;
FrameFunction() {
sig_id = -1;
call_count = 0;
self_time = 0;
total_time = 0;
}
};
class ScriptStackVariable {
public:
String name;
Variant value;
int type;
ScriptStackVariable() {
type = -1;
}
Array serialize(int max_size = 1 << 20); // 1 MiB default.
bool deserialize(const Array &p_arr);
};
class ScriptStackDump {
public:
List<ScriptLanguage::StackInfo> frames;
ScriptStackDump() {}
Array serialize();
bool deserialize(const Array &p_arr);
};
class Message {
public:
String message;
Array data;
Message() {}
};
class OutputError {
public:
int hr;
int min;
int sec;
int msec;
String source_file;
String source_func;
int source_line;
String error;
String error_descr;
bool warning;
Vector<ScriptLanguage::StackInfo> callstack;
OutputError() {
hr = -1;
min = -1;
sec = -1;
msec = -1;
source_line = -1;
warning = false;
}
Array serialize();
bool deserialize(const Array &p_arr);
};
struct FrameData {
StringName name;
Array data;
};
class ProfilerSignature {
public:
StringName name;
int id;
Array serialize();
bool deserialize(const Array &p_arr);
ProfilerSignature() {
id = -1;
};
};
class ProfilerFrame {
public:
int frame_number;
float frame_time;
float idle_time;
float physics_time;
float physics_frame_time;
float script_time;
Vector<FrameData> frames_data;
Vector<FrameFunction> frame_functions;
ProfilerFrame() {
frame_number = 0;
frame_time = 0;
idle_time = 0;
physics_time = 0;
physics_frame_time = 0;
}
Array serialize();
bool deserialize(const Array &p_arr);
};
class NetworkProfilerFrame {
public:
Vector<MultiplayerAPI::ProfilingInfo> infos;
Array serialize();
bool deserialize(const Array &p_arr);
NetworkProfilerFrame(){};
};
protected:
struct ProfileInfoSort {
bool operator()(ScriptLanguage::ProfilingInfo *A, ScriptLanguage::ProfilingInfo *B) const {
return A->total_time < B->total_time;
}
};
Vector<ScriptLanguage::ProfilingInfo> profile_info;
Vector<ScriptLanguage::ProfilingInfo *> profile_info_ptrs;
Vector<MultiplayerAPI::ProfilingInfo> network_profile_info;
Map<StringName, int> profiler_function_signature_map;
float frame_time, idle_time, physics_time, physics_frame_time;
bool profiling;
bool visual_profiling;
bool network_profiling;
int max_frame_functions;
bool skip_profile_frame;
bool reload_all_scripts;
Ref<StreamPeerTCP> tcp_client;
Ref<PacketPeerStream> packet_peer_stream;
uint64_t last_perf_time;
uint64_t last_net_prof_time;
uint64_t last_net_bandwidth_time;
Object *performance;
bool requested_quit;
Mutex mutex;
List<String> output_strings;
List<Message> messages;
int max_messages_per_frame;
int n_messages_dropped;
List<OutputError> errors;
int max_errors_per_second;
int max_warnings_per_second;
int n_errors_dropped;
int n_warnings_dropped;
int max_cps;
int char_count;
int err_count;
int warn_count;
uint64_t last_msec;
uint64_t msec_count;
bool locking; //hack to avoid a deadloop
static void _print_handler(void *p_this, const String &p_string, bool p_error);
PrintHandlerList phl;
void _get_output();
void _poll_events();
uint32_t poll_every;
void _parse_message(const String p_command, const Array &p_data, ScriptLanguage *p_script = NULL);
void _set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value);
void _send_object_id(ObjectID p_id);
void _send_video_memory();
Ref<MultiplayerAPI> multiplayer;
ErrorHandlerList eh;
static void _err_handler(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
void _put_msg(String p_message, Array p_data);
void _send_profiling_data(bool p_for_frame);
void _send_network_profiling_data();
void _send_network_bandwidth_usage();
Vector<FrameData> profile_frame_data;
bool skip_breakpoints;
public:
typedef void (*ResourceUsageFunc)(ResourceUsage *);
typedef Error (*ParseMessageFunc)(const String &p_name, const Array &p_msg); // Returns true if something was found (stopping propagation).
static ResourceUsageFunc resource_usage_func;
static ParseMessageFunc scene_tree_parse_func; // Could be made into list, extensible...
Error connect_to_host(const String &p_host, uint16_t p_port);
bool is_peer_connected();
virtual void debug(ScriptLanguage *p_script, bool p_can_continue = true, bool p_is_error_breakpoint = false);
virtual void idle_poll();
virtual void line_poll();
virtual bool is_remote() const { return true; }
virtual void request_quit();
virtual void send_message(const String &p_message, const Array &p_args);
virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info);
virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
virtual bool is_profiling() const;
virtual void add_profiling_frame_data(const StringName &p_name, const Array &p_data);
virtual void profiling_start();
virtual void profiling_end();
virtual void profiling_set_frame_times(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time);
virtual void set_skip_breakpoints(bool p_skip_breakpoints);
ScriptDebuggerRemote();
~ScriptDebuggerRemote();
};
#endif // SCRIPT_DEBUGGER_REMOTE_H