mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-23 12:26:59 +01:00
176 lines
6.7 KiB
C++
176 lines
6.7 KiB
C++
#ifndef SCENE_SYNCHRONIZER_DEBUGGER_H
|
|
#define SCENE_SYNCHRONIZER_DEBUGGER_H
|
|
|
|
/*************************************************************************/
|
|
/* scene_synchronizer_debugger.h */
|
|
/*************************************************************************/
|
|
/* This file is part of: */
|
|
/* PANDEMONIUM ENGINE */
|
|
/* https://github.com/Relintai/pandemonium_engine */
|
|
/*************************************************************************/
|
|
/* Copyright (c) 2022-present Péter Magyar. */
|
|
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
|
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
|
/* */
|
|
/* 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. */
|
|
/*************************************************************************/
|
|
|
|
#include "scene/main/node.h"
|
|
|
|
#ifdef DEBUG_ENABLED
|
|
|
|
#include "core/containers/oa_hash_map.h"
|
|
|
|
#endif
|
|
|
|
class SceneSynchronizer;
|
|
class SceneTree;
|
|
|
|
class SceneSynchronizerDebugger : public Node {
|
|
GDCLASS(SceneSynchronizerDebugger, Node);
|
|
|
|
static SceneSynchronizerDebugger *the_singleton;
|
|
|
|
public:
|
|
struct TrackedNode {
|
|
Node *node;
|
|
List<PropertyInfo> *properties;
|
|
TrackedNode() = default;
|
|
TrackedNode(Node *p_node) :
|
|
node(p_node) {}
|
|
TrackedNode(Node *p_node, List<PropertyInfo> *p_properties) :
|
|
node(p_node), properties(p_properties) {}
|
|
bool operator==(const TrackedNode &p_t) const { return p_t.node == node; }
|
|
};
|
|
|
|
enum DataBufferDumpMode {
|
|
NONE,
|
|
WRITE,
|
|
READ
|
|
};
|
|
|
|
enum FrameEvent : uint32_t {
|
|
EMPTY = 0,
|
|
CLIENT_DESYNC_DETECTED = 1 << 0,
|
|
CLIENT_DESYNC_DETECTED_SOFT = 1 << 0,
|
|
};
|
|
|
|
public:
|
|
static SceneSynchronizerDebugger *singleton();
|
|
static void _bind_methods();
|
|
|
|
private:
|
|
#ifdef DEBUG_ENABLED
|
|
bool dump_enabled = false;
|
|
LocalVector<StringName> dump_classes;
|
|
bool setup_done = false;
|
|
|
|
uint32_t log_counter = 0;
|
|
SceneTree *scene_tree = nullptr;
|
|
String main_dump_directory_path;
|
|
String dump_name;
|
|
|
|
LocalVector<TrackedNode> tracked_nodes;
|
|
// HaskMap between class name and property list: to avoid fetching the property list per object each frame.
|
|
OAHashMap<StringName, List<PropertyInfo>> classes_property_lists;
|
|
|
|
// Dictionary of dictionary containing nodes info.
|
|
Dictionary frame_dump__begin_state;
|
|
|
|
// Dictionary of dictionary containing nodes info.
|
|
Dictionary frame_dump__end_state;
|
|
|
|
// The dictionary containing the data buffer operations performed by the controllers.
|
|
Dictionary frame_dump__node_log;
|
|
|
|
// The controller name for which the data buffer operations is in progress.
|
|
String frame_dump__data_buffer_name;
|
|
|
|
// A really small description about what happens on this frame.
|
|
FrameEvent frame_dump__frame_events = FrameEvent::EMPTY;
|
|
|
|
// This Array contains all the inputs (stringified) written on the `DataBuffer` from the
|
|
// `_controller_process` function
|
|
Array frame_dump__data_buffer_writes;
|
|
|
|
// This Array contains all the inputs (stringified) read on the `DataBuffer` from the
|
|
// `_controller_process` function
|
|
Array frame_dump__data_buffer_reads;
|
|
|
|
// This Dictionary contains the comparison (`_are_inputs_different`) fetched by this frame, and
|
|
// the result.
|
|
Dictionary frame_dump__are_inputs_different_results;
|
|
|
|
DataBufferDumpMode frame_dump_data_buffer_dump_mode = NONE;
|
|
|
|
bool frame_dump__has_warnings = false;
|
|
bool frame_dump__has_errors = false;
|
|
#endif
|
|
|
|
public:
|
|
SceneSynchronizerDebugger();
|
|
~SceneSynchronizerDebugger();
|
|
|
|
void set_dump_enabled(bool p_dump_enabled);
|
|
bool get_dump_enabled() const;
|
|
|
|
void register_class_for_node_to_dump(Node *p_node);
|
|
void register_class_to_dump(const StringName &p_class);
|
|
void unregister_class_to_dump(const StringName &p_class);
|
|
|
|
void setup_debugger(const String &p_dump_name, int p_peer, SceneTree *p_scene_tree);
|
|
|
|
private:
|
|
void prepare_dumping(int p_peer, SceneTree *p_scene_tree);
|
|
void setup_debugger_python_ui();
|
|
void track_node(Node *p_node, bool p_recursive);
|
|
void on_node_added(Node *p_node);
|
|
void on_node_removed(Node *p_node);
|
|
|
|
public:
|
|
void write_dump(int p_peer, uint32_t p_frame_index);
|
|
void start_new_frame();
|
|
|
|
void scene_sync_process_start(const SceneSynchronizer *p_scene_sync);
|
|
void scene_sync_process_end(const SceneSynchronizer *p_scene_sync);
|
|
|
|
void databuffer_operation_begin_record(Node *p_node, DataBufferDumpMode p_mode);
|
|
void databuffer_operation_end_record();
|
|
void databuffer_write(uint32_t p_data_type, uint32_t p_compression_level, Variant p_variable);
|
|
void databuffer_read(uint32_t p_data_type, uint32_t p_compression_level, Variant p_variable);
|
|
|
|
void notify_input_sent_to_server(Node *p_node, uint32_t p_frame_index, uint32_t p_input_index);
|
|
void notify_are_inputs_different_result(Node *p_node, uint32_t p_other_frame_index, bool p_is_similar);
|
|
|
|
void add_node_message(Node *p_node, const String &p_message);
|
|
void add_node_message_by_path(const String &p_node_path, const String &p_message);
|
|
|
|
void debug_print(Node *p_node, const String &p_message, bool p_silent = false);
|
|
void debug_warning(Node *p_node, const String &p_message, bool p_silent = false);
|
|
void debug_error(Node *p_node, const String &p_message, bool p_silent = false);
|
|
|
|
void notify_event(FrameEvent p_event);
|
|
|
|
private:
|
|
void dump_tracked_objects(const SceneSynchronizer *p_scene_sync, Dictionary &p_dump);
|
|
};
|
|
|
|
#endif
|