Fixed reactivation problems
This commit is contained in:
215
src/modules/stream/road_lines_editor.cpp
Normal file
215
src/modules/stream/road_lines_editor.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#undef NDEBUG
|
||||
#include <cassert>
|
||||
#include <scene/main/viewport.h>
|
||||
#include <scene/gui/item_list.h>
|
||||
#include <scene/3d/immediate_geometry.h>
|
||||
#include <core/io/config_file.h>
|
||||
#include <core/os/file_access.h>
|
||||
#include <core/io/json.h>
|
||||
#include "world_editor.h"
|
||||
#include "from_string.h"
|
||||
#include "road_lines_editor.h"
|
||||
|
||||
struct road_line {
|
||||
std::vector<Transform> points;
|
||||
std::vector<int> indices;
|
||||
int lanes;
|
||||
int pattern;
|
||||
int flags;
|
||||
};
|
||||
static HashMap<String, struct road_line> lines;
|
||||
static ImmediateGeometry *line_im = nullptr;
|
||||
static Ref<Material> debug_material;
|
||||
|
||||
#define __evhandler(vname, mtype) \
|
||||
template <class T> class GDEventHandler_##vname : public Object { \
|
||||
GDCLASS(GDEventHandler_##vname, Object) \
|
||||
T *obj; \
|
||||
\
|
||||
public: \
|
||||
GDEventHandler_##vname(T *obj) \
|
||||
: Object() \
|
||||
, obj(obj) \
|
||||
{ \
|
||||
} \
|
||||
virtual ~GDEventHandler_##vname() \
|
||||
{ \
|
||||
} \
|
||||
bool connect(Object *obj, const String &signal) \
|
||||
{ \
|
||||
return obj->connect(signal, this, "handler"); \
|
||||
} \
|
||||
void disconnect(Object *obj, const String &signal) \
|
||||
{ \
|
||||
obj->disconnect(signal, this, "handler"); \
|
||||
} \
|
||||
\
|
||||
protected: \
|
||||
void handler(const String &event, const Array &args) \
|
||||
{ \
|
||||
obj->vname(event, args); \
|
||||
} \
|
||||
static void _bind_methods() \
|
||||
{ \
|
||||
ClassDB::bind_method( \
|
||||
D_METHOD("handler", "args"), \
|
||||
&GDEventHandler_##vname::handler); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define __evhandler_type(vname, mtype) GDEventHandler_##vname<mtype>
|
||||
|
||||
__evhandler(editor_event, RoadLinesEditor);
|
||||
static __evhandler_type(editor_event, RoadLinesEditor) * gd_editor_event;
|
||||
|
||||
RoadLinesEditor::RoadLinesEditor(WorldEditor *editor)
|
||||
: active(false)
|
||||
, editor(editor)
|
||||
{
|
||||
}
|
||||
|
||||
RoadLinesEditor::~RoadLinesEditor()
|
||||
{
|
||||
if (active && editor->is_inside_tree())
|
||||
deactivate();
|
||||
}
|
||||
|
||||
void RoadLinesEditor::update(float delta)
|
||||
{
|
||||
if (!active)
|
||||
activate();
|
||||
print_line("road_lines_editor");
|
||||
}
|
||||
|
||||
void RoadLinesEditor::exit()
|
||||
{
|
||||
if (active)
|
||||
deactivate();
|
||||
}
|
||||
|
||||
void RoadLinesEditor::editor_command(const String &command, const Array &args)
|
||||
{
|
||||
print_line("command: " + command);
|
||||
}
|
||||
|
||||
void RoadLinesEditor::editor_event(const String &event, const Array &args)
|
||||
{
|
||||
print_line("event: " + event);
|
||||
}
|
||||
|
||||
void RoadLinesEditor::update_ui()
|
||||
{
|
||||
Node *lines_list_node =
|
||||
editor->get_tree()->get_current_scene()->get_node(
|
||||
NodePath("%lines_list"));
|
||||
ItemList *lines_list = Object::cast_to<ItemList>(lines_list_node);
|
||||
assert(lines_list);
|
||||
List<String> line_keys;
|
||||
lines.get_key_list(&line_keys);
|
||||
List<String>::Element *e = line_keys.front();
|
||||
lines_list->clear();
|
||||
while (e) {
|
||||
String key = e->get();
|
||||
lines_list->add_item(key);
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
|
||||
void RoadLinesEditor::activate()
|
||||
{
|
||||
assert(!active);
|
||||
load_data();
|
||||
print_line("activate::update UI");
|
||||
update_ui();
|
||||
if (!line_im) {
|
||||
line_im = memnew(ImmediateGeometry);
|
||||
editor->get_viewport()->add_child(line_im);
|
||||
}
|
||||
Ref<SpatialMaterial> tmpmat;
|
||||
tmpmat.instance();
|
||||
tmpmat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
|
||||
tmpmat->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, true);
|
||||
tmpmat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
|
||||
debug_material = tmpmat;
|
||||
line_im->begin(Mesh::PRIMITIVE_LINES);
|
||||
line_im->set_color(Color(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
line_im->add_vertex(Vector3(0.0f, -100.0f, 0.0f));
|
||||
line_im->add_vertex(Vector3(0.0f, 100.0f, 0.0f));
|
||||
line_im->end();
|
||||
if (!gd_editor_event)
|
||||
gd_editor_event = memnew(
|
||||
__evhandler_type(editor_event, RoadLinesEditor)(this));
|
||||
gd_editor_event->connect(editor, "editor_event");
|
||||
|
||||
active = true;
|
||||
}
|
||||
|
||||
void RoadLinesEditor::deactivate()
|
||||
{
|
||||
Node *lines_list_node =
|
||||
editor->get_tree()->get_current_scene()->get_node(
|
||||
NodePath("%lines_list"));
|
||||
ItemList *lines_list = Object::cast_to<ItemList>(lines_list_node);
|
||||
lines_list->clear();
|
||||
lines.clear();
|
||||
if (line_im) {
|
||||
line_im->queue_delete();
|
||||
line_im = nullptr;
|
||||
}
|
||||
gd_editor_event->disconnect(editor, "editor_event");
|
||||
if (debug_material.is_valid())
|
||||
debug_material.unref();
|
||||
if (gd_editor_event) {
|
||||
memdelete(gd_editor_event);
|
||||
gd_editor_event = nullptr;
|
||||
}
|
||||
active = false;
|
||||
}
|
||||
|
||||
void RoadLinesEditor::load_data()
|
||||
{
|
||||
int i;
|
||||
ConfigFile config;
|
||||
Error result = config.load("res://config/stream.conf");
|
||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||
String road_lines_path = config.get_value("road", "road_lines_path");
|
||||
String road_lines_json =
|
||||
FileAccess::get_file_as_string(road_lines_path);
|
||||
Variant json_v;
|
||||
String es;
|
||||
int eline;
|
||||
Error status = JSON::parse(road_lines_json, json_v, es, eline);
|
||||
ERR_FAIL_COND_MSG(status != OK, "Can't parse json: " + es +
|
||||
" at line: " + itos(eline));
|
||||
|
||||
Dictionary json = json_v;
|
||||
List<Variant> keys;
|
||||
json.get_key_list(&keys);
|
||||
List<Variant>::Element *e = keys.front();
|
||||
while (e) {
|
||||
String key = e->get();
|
||||
struct road_line rline;
|
||||
Dictionary entry = json.get(key, Dictionary());
|
||||
Array points = entry.get("points", Array());
|
||||
Array indices;
|
||||
if (entry.has("indices"))
|
||||
indices = entry.get("indices", Array());
|
||||
int lanes = entry.get("lanes", -1);
|
||||
int pattern = entry.get("pattern", -1);
|
||||
rline.pattern = pattern;
|
||||
rline.points.resize(points.size());
|
||||
rline.indices.resize(indices.size());
|
||||
for (i = 0; i < (int)points.size(); i++) {
|
||||
String point_s = points[i];
|
||||
rline.points[i] = from_string<Transform>(point_s);
|
||||
}
|
||||
for (i = 0; i < (int)indices.size(); i++) {
|
||||
int index = indices[i];
|
||||
rline.indices[i] = index;
|
||||
}
|
||||
// TODO: wtf is flags?
|
||||
rline.lanes = lanes;
|
||||
lines[key] = rline;
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user