Skip to content

Commit da171ae

Browse files
committed
Refactored entity drag and drop to code
1 parent e5ec8c7 commit da171ae

4 files changed

Lines changed: 65 additions & 95 deletions

File tree

editor/util/ProjectUtils.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#include "ProjectUtils.h"
22

3-
#include <fstream>
4-
53
#include "Out.h"
64
#include "Catalog.h"
75
#include "Stream.h"
@@ -61,6 +59,8 @@
6159

6260
using namespace doriax;
6361

62+
static void parseLuaPropertiesTable(lua_State* L, ScriptEntry& entry);
63+
6464
void editor::ProjectUtils::setDefaultSkyTexture(Texture& outTexture) {
6565
TextureData skyBack;
6666
TextureData skyBottom;
@@ -1138,7 +1138,7 @@ void editor::ProjectUtils::loadLuaScriptPropertiesFromString(ScriptEntry& entry,
11381138
parseLuaPropertiesTable(L, entry);
11391139
}
11401140

1141-
void editor::ProjectUtils::parseLuaPropertiesTable(lua_State* L, ScriptEntry& entry) {
1141+
static void parseLuaPropertiesTable(lua_State* L, ScriptEntry& entry) {
11421142

11431143
lua_getfield(L, -1, "properties"); // Stack: script_table, properties_table
11441144

@@ -1195,7 +1195,7 @@ void editor::ProjectUtils::parseLuaPropertiesTable(lua_State* L, ScriptEntry& en
11951195
lua_pop(L, 1);
11961196

11971197
lua_getfield(L, -1, "default");
1198-
prop.defaultValue = ProjectUtils::luaValueToScriptPropertyValue(L, -1, prop.type);
1198+
prop.defaultValue = editor::ProjectUtils::luaValueToScriptPropertyValue(L, -1, prop.type);
11991199
prop.value = prop.defaultValue;
12001200
lua_pop(L, 1);
12011201

editor/util/ProjectUtils.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ class ProjectUtils {
4545
static void loadLuaScriptProperties(ScriptEntry& entry, const std::string& luaPath);
4646
static void loadLuaScriptPropertiesFromString(ScriptEntry& entry, const std::string& scriptContent, const std::string& chunkName);
4747

48-
private:
49-
static void parseLuaPropertiesTable(lua_State* L, ScriptEntry& entry);
50-
51-
public:
5248
static void collectModelEntities(Scene* scene, const ModelComponent& model, std::vector<Entity>& out);
5349

5450
static void collectEntities(const YAML::Node& entityNode, std::vector<Entity>& allEntities);

editor/window/CodeEditor.cpp

Lines changed: 57 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,50 @@ void editor::CodeEditor::updateScriptProperties(const EditorInstance& instance,
231231
}
232232
}
233233

234+
std::string editor::CodeEditor::toCamelCase(const std::string& name) {
235+
std::string result;
236+
bool nextUpper = false;
237+
for (char c : name) {
238+
if (std::isalnum(static_cast<unsigned char>(c))) {
239+
if (result.empty()) {
240+
result += (char)std::tolower(static_cast<unsigned char>(c));
241+
} else if (nextUpper) {
242+
result += (char)std::toupper(static_cast<unsigned char>(c));
243+
nextUpper = false;
244+
} else {
245+
result += c;
246+
}
247+
} else {
248+
if (!result.empty()) nextUpper = true;
249+
}
250+
}
251+
return result.empty() ? "entity" : result;
252+
}
253+
254+
std::string editor::CodeEditor::toDisplayName(const std::string& camelCase) {
255+
std::string result;
256+
for (size_t i = 0; i < camelCase.size(); i++) {
257+
if (i == 0) {
258+
result += (char)std::toupper(static_cast<unsigned char>(camelCase[i]));
259+
} else if (std::isupper(static_cast<unsigned char>(camelCase[i]))) {
260+
result += ' ';
261+
result += camelCase[i];
262+
} else {
263+
result += camelCase[i];
264+
}
265+
}
266+
return result;
267+
}
268+
269+
void editor::CodeEditor::offsetToLineCol(const std::string& text, size_t offset, int& line, int& col) {
270+
line = 0;
271+
col = 0;
272+
for (size_t i = 0; i < offset && i < text.size(); i++) {
273+
if (text[i] == '\n') { line++; col = 0; }
274+
else { col++; }
275+
}
276+
}
277+
234278
void editor::CodeEditor::insertLuaEntityProperty(EditorInstance& instance, Entity entity, uint32_t entitySceneId) {
235279
// Resolve the source scene
236280
SceneProject* sourceSceneProject = project->getScene(entitySceneId);
@@ -243,7 +287,6 @@ void editor::CodeEditor::insertLuaEntityProperty(EditorInstance& instance, Entit
243287
if (!scene->isEntityCreated(entity)) return;
244288

245289
// Get entity info
246-
std::string entityName = scene->getEntityName(entity);
247290
std::string entityType = editor::ProjectUtils::getEntityTypeName(scene, entity);
248291

249292
// Check if the entity has a Lua script — use its className as a more specific type
@@ -257,26 +300,9 @@ void editor::CodeEditor::insertLuaEntityProperty(EditorInstance& instance, Entit
257300
}
258301
}
259302

260-
// Generate variable name: sanitize entity name to camelCase
261-
std::string varName;
262-
bool nextUpper = false;
263-
for (char c : entityName) {
264-
if (std::isalnum(static_cast<unsigned char>(c))) {
265-
if (varName.empty()) {
266-
varName += (char)std::tolower(static_cast<unsigned char>(c));
267-
} else if (nextUpper) {
268-
varName += (char)std::toupper(static_cast<unsigned char>(c));
269-
nextUpper = false;
270-
} else {
271-
varName += c;
272-
}
273-
} else {
274-
if (!varName.empty()) nextUpper = true;
275-
}
276-
}
277-
if (varName.empty()) varName = "entity";
303+
std::string varName = toCamelCase(scene->getEntityName(entity));
278304

279-
// Avoid duplicate property names: check existing text for same variable name
305+
// Avoid duplicate property names
280306
std::string text = instance.editor->GetText();
281307
{
282308
std::string baseName = varName;
@@ -286,18 +312,7 @@ void editor::CodeEditor::insertLuaEntityProperty(EditorInstance& instance, Entit
286312
}
287313
}
288314

289-
// Generate display name from varName
290-
std::string displayName;
291-
for (size_t i = 0; i < varName.size(); i++) {
292-
if (i == 0) {
293-
displayName += (char)std::toupper(static_cast<unsigned char>(varName[i]));
294-
} else if (std::isupper(static_cast<unsigned char>(varName[i]))) {
295-
displayName += ' ';
296-
displayName += varName[i];
297-
} else {
298-
displayName += varName[i];
299-
}
300-
}
315+
std::string displayName = toDisplayName(varName);
301316

302317
// Build the Lua property entry text
303318
std::string propEntry =
@@ -351,11 +366,8 @@ void editor::CodeEditor::insertLuaEntityProperty(EditorInstance& instance, Entit
351366
}
352367

353368
// Insert before the closing brace of properties table using cursor-based insert (preserves undo)
354-
int insertLine = 0, insertCol = 0;
355-
for (size_t i = 0; i < closePos; i++) {
356-
if (text[i] == '\n') { insertLine++; insertCol = 0; }
357-
else { insertCol++; }
358-
}
369+
int insertLine, insertCol;
370+
offsetToLineCol(text, closePos, insertLine, insertCol);
359371
instance.editor->SetCursorPosition(insertLine, insertCol);
360372
instance.editor->InsertText(insertion, false);
361373

@@ -409,7 +421,6 @@ void editor::CodeEditor::insertCppEntityProperty(EditorInstance& instance, Entit
409421
if (!scene->isEntityCreated(entity)) return;
410422

411423
// Get entity info
412-
std::string entityName = scene->getEntityName(entity);
413424
std::string entityType = editor::ProjectUtils::getEntityTypeName(scene, entity);
414425

415426
// Check if the entity has a C++ SUBCLASS script — use its class name as a more specific type
@@ -429,24 +440,7 @@ void editor::CodeEditor::insertCppEntityProperty(EditorInstance& instance, Entit
429440
}
430441
}
431442

432-
// Generate variable name: sanitize entity name to camelCase
433-
std::string varName;
434-
bool nextUpper = false;
435-
for (char c : entityName) {
436-
if (std::isalnum(static_cast<unsigned char>(c))) {
437-
if (varName.empty()) {
438-
varName += (char)std::tolower(static_cast<unsigned char>(c));
439-
} else if (nextUpper) {
440-
varName += (char)std::toupper(static_cast<unsigned char>(c));
441-
nextUpper = false;
442-
} else {
443-
varName += c;
444-
}
445-
} else {
446-
if (!varName.empty()) nextUpper = true;
447-
}
448-
}
449-
if (varName.empty()) varName = "entity";
443+
std::string varName = toCamelCase(scene->getEntityName(entity));
450444

451445
// Determine header path: if currently viewing .cpp, derive .h path
452446
fs::path headerPath = instance.filepath;
@@ -490,18 +484,7 @@ void editor::CodeEditor::insertCppEntityProperty(EditorInstance& instance, Entit
490484
}
491485
}
492486

493-
// Generate display name from varName (camelCase -> "Camel Case")
494-
std::string displayName;
495-
for (size_t i = 0; i < varName.size(); i++) {
496-
if (i == 0) {
497-
displayName += (char)std::toupper(static_cast<unsigned char>(varName[i]));
498-
} else if (std::isupper(static_cast<unsigned char>(varName[i]))) {
499-
displayName += ' ';
500-
displayName += varName[i];
501-
} else {
502-
displayName += varName[i];
503-
}
504-
}
487+
std::string displayName = toDisplayName(varName);
505488

506489
// Build the SPROPERTY + member declaration
507490
std::string typeDecl = isSubclassType ? entityType : ("doriax::" + entityType);
@@ -580,22 +563,16 @@ void editor::CodeEditor::insertCppEntityProperty(EditorInstance& instance, Entit
580563
// Must do #include first so it doesn't shift SPROPERTY position calculation
581564
int includeLineShift = 0;
582565
if (needsInclude && includeInsertPos != std::string::npos) {
583-
int incLine = 0, incCol = 0;
584-
for (size_t i = 0; i < includeInsertPos; i++) {
585-
if (headerText[i] == '\n') { incLine++; incCol = 0; }
586-
else { incCol++; }
587-
}
566+
int incLine, incCol;
567+
offsetToLineCol(headerText, includeInsertPos, incLine, incCol);
588568
headerInstance->editor->SetCursorPosition(incLine, incCol);
589569
headerInstance->editor->InsertText(includeDirective + "\n", false);
590570
includeLineShift = 1; // One extra line added
591571
}
592572

593573
// Now insert SPROPERTY at the adjusted position
594-
int insertLine = 0, insertCol = 0;
595-
for (size_t i = 0; i < insertPos; i++) {
596-
if (headerText[i] == '\n') { insertLine++; insertCol = 0; }
597-
else { insertCol++; }
598-
}
574+
int insertLine, insertCol;
575+
offsetToLineCol(headerText, insertPos, insertLine, insertCol);
599576
// Shift if #include was inserted before this position
600577
if (needsInclude && includeInsertPos != std::string::npos && includeInsertPos <= insertPos) {
601578
insertLine += includeLineShift;
@@ -606,8 +583,6 @@ void editor::CodeEditor::insertCppEntityProperty(EditorInstance& instance, Entit
606583
// Update the properties dynamically parsing the current text, without overwriting the file
607584
headerInstance->isModified = true;
608585
headerInstance->propertyInsertUndoIndex = headerInstance->editor->GetUndoIndex();
609-
std::string finalHeaderText = headerInstance->editor->GetText();
610-
updateScriptProperties(*headerInstance, finalHeaderText);
611586
} else {
612587
// Header not open in editor — build full text and write to disk
613588
// Apply #include first (modifies headerText), then insert SPROPERTY
@@ -636,14 +611,9 @@ void editor::CodeEditor::insertCppEntityProperty(EditorInstance& instance, Entit
636611

637612
uint32_t storedSceneId = (entitySceneId != selectedScene->id) ? entitySceneId : 0;
638613

639-
std::string inMemoryContent = "";
640-
if (headerInstance) {
641-
inMemoryContent = headerInstance->editor->GetText();
642-
} else {
643-
// We already wrote it to disk, but we also can fallback to reading from disk because inMemoryContent is empty
644-
}
614+
std::string inMemoryContent = headerInstance ? headerInstance->editor->GetText() : "";
645615

646-
// First, trigger updateScriptProperties for all entities referencing this header
616+
// Update script properties and link the dropped entity for all entities referencing this header
647617
for (auto& sceneProject : project->getScenes()) {
648618
if (!sceneProject.scene) continue;
649619

editor/window/CodeEditor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ namespace doriax::editor {
5151
void insertLuaEntityProperty(EditorInstance& instance, Entity entity, uint32_t entitySceneId);
5252
void insertCppEntityProperty(EditorInstance& instance, Entity entity, uint32_t entitySceneId);
5353

54+
static std::string toCamelCase(const std::string& name);
55+
static std::string toDisplayName(const std::string& camelCase);
56+
static void offsetToLineCol(const std::string& text, size_t offset, int& line, int& col);
57+
5458
public:
5559
CodeEditor(Project* project);
5660
~CodeEditor();

0 commit comments

Comments
 (0)