Validate layouts

This commit is contained in:
Marcus Huderle 2020-02-11 18:34:08 -06:00
parent 262bd9e4e5
commit 79c74b8814
6 changed files with 96 additions and 19 deletions

View file

@ -52,6 +52,7 @@ public:
QList<QStringList>* getLabelMacros(QList<QStringList>*, QString); QList<QStringList>* getLabelMacros(QList<QStringList>*, QString);
QStringList* getLabelValues(QList<QStringList>*, QString); QStringList* getLabelValues(QList<QStringList>*, QString);
bool tryParseJsonFile(QJsonDocument *out, QString filepath); bool tryParseJsonFile(QJsonDocument *out, QString filepath);
bool ensureFieldsExist(QJsonObject obj, QList<QString> fields);
private: private:
QString root; QString root;

View file

@ -186,7 +186,7 @@ private:
bool setMap(QString, bool scrollTreeView = false); bool setMap(QString, bool scrollTreeView = false);
void redrawMapScene(); void redrawMapScene();
void loadDataStructures(); bool loadDataStructures();
void populateMapList(); void populateMapList();
void sortMapList(); void sortMapList();
QString getExistingDirectory(QString); QString getExistingDirectory(QString);

View file

@ -100,7 +100,7 @@ public:
QMap<QString, bool> getTopLevelMapFields(); QMap<QString, bool> getTopLevelMapFields();
bool loadMapData(Map*); bool loadMapData(Map*);
void readMapLayouts(); bool readMapLayouts();
void loadMapLayout(Map*); void loadMapLayout(Map*);
void loadMapTilesets(Map*); void loadMapTilesets(Map*);
void loadTilesetAssets(Tileset*); void loadTilesetAssets(Tileset*);

View file

@ -410,3 +410,13 @@ bool ParseUtil::tryParseJsonFile(QJsonDocument *out, QString filepath) {
*out = jsonDoc; *out = jsonDoc;
return true; return true;
} }
bool ParseUtil::ensureFieldsExist(QJsonObject obj, QList<QString> fields) {
for (QString field : fields) {
if (!obj.contains(field)) {
logError(QString("JSON object is missing field '%1'.").arg(field));
return false;
}
}
return true;
}

View file

@ -281,17 +281,20 @@ bool MainWindow::openProject(QString dir) {
if (!already_open) { if (!already_open) {
editor->project = new Project; editor->project = new Project;
editor->project->set_root(dir); editor->project->set_root(dir);
setWindowTitle(editor->project->getProjectTitle()); success = loadDataStructures();
loadDataStructures(); if (success) {
populateMapList(); populateMapList();
success = setMap(getDefaultMap(), true); success = setMap(getDefaultMap(), true);
}
} else { } else {
setWindowTitle(editor->project->getProjectTitle()); success = loadDataStructures();
loadDataStructures(); if (success) {
populateMapList(); populateMapList();
}
} }
if (success) { if (success) {
setWindowTitle(editor->project->getProjectTitle());
this->statusBar()->showMessage(QString("Opened project %1").arg(nativeDir)); this->statusBar()->showMessage(QString("Opened project %1").arg(nativeDir));
} else { } else {
this->statusBar()->showMessage(QString("Failed to open project %1").arg(nativeDir)); this->statusBar()->showMessage(QString("Failed to open project %1").arg(nativeDir));
@ -301,8 +304,7 @@ bool MainWindow::openProject(QString dir) {
} }
bool MainWindow::isProjectOpen() { bool MainWindow::isProjectOpen() {
return (editor && editor != nullptr) return editor != nullptr && editor->project != nullptr;
&& (editor->project && editor->project != nullptr);
} }
QString MainWindow::getDefaultMap() { QString MainWindow::getDefaultMap() {
@ -593,9 +595,12 @@ void MainWindow::on_checkBox_AllowEscapeRope_clicked(bool checked)
} }
} }
void MainWindow::loadDataStructures() { bool MainWindow::loadDataStructures() {
Project *project = editor->project; Project *project = editor->project;
project->readMapLayouts(); bool success = project->readMapLayouts();
if (!success) {
return false;
}
project->readRegionMapSections(); project->readRegionMapSections();
project->readItemNames(); project->readItemNames();
project->readFlagNames(); project->readFlagNames();
@ -625,6 +630,7 @@ void MainWindow::loadDataStructures() {
ui->comboBox_Weather->addItems(*project->weatherNames); ui->comboBox_Weather->addItems(*project->weatherNames);
ui->comboBox_BattleScene->addItems(*project->mapBattleScenes); ui->comboBox_BattleScene->addItems(*project->mapBattleScenes);
ui->comboBox_Type->addItems(*project->mapTypes); ui->comboBox_Type->addItems(*project->mapTypes);
return true;
} }
void MainWindow::populateMapList() { void MainWindow::populateMapList() {

View file

@ -404,7 +404,7 @@ void Project::loadMapLayout(Map* map) {
loadMapBorder(map); loadMapBorder(map);
} }
void Project::readMapLayouts() { bool Project::readMapLayouts() {
mapLayouts.clear(); mapLayouts.clear();
mapLayoutsTable.clear(); mapLayoutsTable.clear();
@ -412,24 +412,83 @@ void Project::readMapLayouts() {
QJsonDocument layoutsDoc; QJsonDocument layoutsDoc;
if (!parser.tryParseJsonFile(&layoutsDoc, layoutsFilepath)) { if (!parser.tryParseJsonFile(&layoutsDoc, layoutsFilepath)) {
logError(QString("Failed to read map layouts from %1").arg(layoutsFilepath)); logError(QString("Failed to read map layouts from %1").arg(layoutsFilepath));
return; return false;
} }
QJsonObject layoutsObj = layoutsDoc.object(); QJsonObject layoutsObj = layoutsDoc.object();
layoutsLabel = layoutsObj["layouts_table_label"].toString();
QJsonArray layouts = layoutsObj["layouts"].toArray(); QJsonArray layouts = layoutsObj["layouts"].toArray();
if (layouts.size() == 0) {
logError(QString("'layouts' array is missing from %1.").arg(layoutsFilepath));
return false;
}
layoutsLabel = layoutsObj["layouts_table_label"].toString();
if (layoutsLabel.isNull()) {
layoutsLabel = "gMapLayouts";
logWarn(QString("'layouts_table_label' value is missing from %1. Defaulting to %2")
.arg(layoutsFilepath)
.arg(layoutsLabel));
}
QList<QString> requiredFields = QList<QString>{
"id",
"name",
"width",
"height",
"primary_tileset",
"secondary_tileset",
"border_filepath",
"blockdata_filepath",
};
for (int i = 0; i < layouts.size(); i++) { for (int i = 0; i < layouts.size(); i++) {
QJsonObject layoutObj = layouts[i].toObject(); QJsonObject layoutObj = layouts[i].toObject();
if (!parser.ensureFieldsExist(layoutObj, requiredFields)) {
logError(QString("Layout %1 is missing field(s) in %2.").arg(i).arg(layoutsFilepath));
return false;
}
MapLayout *layout = new MapLayout(); MapLayout *layout = new MapLayout();
layout->id = layoutObj["id"].toString(); layout->id = layoutObj["id"].toString();
if (layout->id.isEmpty()) {
logError(QString("Missing 'id' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
return false;
}
layout->name = layoutObj["name"].toString(); layout->name = layoutObj["name"].toString();
layout->width = QString::number(layoutObj["width"].toInt()); if (layout->name.isEmpty()) {
layout->height = QString::number(layoutObj["height"].toInt()); logError(QString("Missing 'name' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
return false;
}
int lwidth = layoutObj["width"].toInt();
if (lwidth <= 0) {
logError(QString("Invalid layout 'width' value '%1' on layout %2 in %3. Must be greater than 0.").arg(lwidth).arg(i).arg(layoutsFilepath));
return false;
}
layout->width = QString::number(lwidth);
int lheight = layoutObj["height"].toInt();
if (lheight <= 0) {
logError(QString("Invalid layout 'height' value '%1' on layout %2 in %3. Must be greater than 0.").arg(lheight).arg(i).arg(layoutsFilepath));
return false;
}
layout->height = QString::number(lheight);
layout->tileset_primary_label = layoutObj["primary_tileset"].toString(); layout->tileset_primary_label = layoutObj["primary_tileset"].toString();
if (layout->tileset_primary_label.isEmpty()) {
logError(QString("Missing 'primary_tileset' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
return false;
}
layout->tileset_secondary_label = layoutObj["secondary_tileset"].toString(); layout->tileset_secondary_label = layoutObj["secondary_tileset"].toString();
if (layout->tileset_secondary_label.isEmpty()) {
logError(QString("Missing 'secondary_tileset' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
return false;
}
layout->border_path = layoutObj["border_filepath"].toString(); layout->border_path = layoutObj["border_filepath"].toString();
if (layout->border_path.isEmpty()) {
logError(QString("Missing 'border_filepath' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
return false;
}
layout->blockdata_path = layoutObj["blockdata_filepath"].toString(); layout->blockdata_path = layoutObj["blockdata_filepath"].toString();
if (layout->border_path.isEmpty()) {
logError(QString("Missing 'blockdata_filepath' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
return false;
}
mapLayouts.insert(layout->id, layout); mapLayouts.insert(layout->id, layout);
mapLayoutsTable.append(layout->id); mapLayoutsTable.append(layout->id);
} }
@ -439,6 +498,7 @@ void Project::readMapLayouts() {
mapLayoutsMaster.detach(); mapLayoutsMaster.detach();
mapLayoutsTableMaster = mapLayoutsTable; mapLayoutsTableMaster = mapLayoutsTable;
mapLayoutsTableMaster.detach(); mapLayoutsTableMaster.detach();
return true;
} }
void Project::saveMapLayouts() { void Project::saveMapLayouts() {