Exemplo n.º 1
0
int main(int argc, const char* argv[])
{
    SuperLogger logger;

    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    global_logger().add_target(&logger.get_log_target());

    // Construct the schema filename.
    const filesystem::path schema_path =
          filesystem::path(Application::get_root_path())
        / "schemas/project.xsd";

    // Load the input project from disk.
    ProjectFileReader reader;
    auto_release_ptr<Project> project(
        reader.read(
            cl.m_filename.values()[0].c_str(),
            schema_path.file_string().c_str()));

    // Bail out if the project couldn't be loaded.
    if (project.get() == 0)
        return 1;

    // Write the project back to disk.
    return ProjectFileWriter::write(project.ref()) ? 0 : 1;
}
Exemplo n.º 2
0
int main(int argc, const char* argv[])
{
    // Initialize the logger that will be used throughout the program.
    SuperLogger logger;

    // Make sure appleseed is correctly installed.
    Application::check_installation(logger);

    // Parse the command line.
    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Load an apply settings from the settings file.
    Dictionary settings;
    Application::load_settings("appleseed.tools.xml", settings, logger);
    logger.configure_from_settings(settings);

    // Apply command line arguments.
    cl.apply(logger);

    // Configure the renderer's global logger.
    // Must be done after settings have been loaded and the command line
    // has been parsed, because these two operations may replace the log
    // target of the global logger.
    global_logger().initialize_from(logger);

    // Retrieve the command line arguments.
    const string& input_filepath = cl.m_filenames.values()[0];
    const string& output_filepath = cl.m_filenames.values()[1];
    const FluffParams params(cl);

    // Construct the schema file path.
    const bf::path schema_filepath =
          bf::path(Application::get_root_path())
        / "schemas"
        / "project.xsd";

    // Read the input project from disk.
    ProjectFileReader reader;
    auto_release_ptr<Project> project(
        reader.read(
            input_filepath.c_str(),
            schema_filepath.string().c_str()));

    // Bail out if the project couldn't be loaded.
    if (project.get() == 0)
        return 1;

    // Fluffify the project.
    make_fluffy(project.ref(), params);

    // Write the project back to disk.
    const bool success =
        ProjectFileWriter::write(
            project.ref(),
            output_filepath.c_str());

    return success ? 0 : 1;
}
Exemplo n.º 3
0
int main(int argc, const char* argv[])
{
    SuperLogger logger;
    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    dump_metadata(cl.m_format.value(), logger);

    return 0;
}
Exemplo n.º 4
0
int main(int argc, char* argv[])
{
    start_memory_tracking();

    // Our message handler must be set before the construction of QApplication.
    g_previous_message_handler = qInstallMsgHandler(message_handler);

    QApplication application(argc, argv);
    QApplication::setOrganizationName("appleseedhq");
    QApplication::setOrganizationDomain("appleseedhq.net");
    QApplication::setApplicationName("appleseed.studio");
    QApplication::setApplicationVersion(Appleseed::get_lib_version());
    QApplication::setWindowIcon(QIcon(make_app_path("icons/appleseed.png")));

    // The locale must be set after the construction of QApplication.
    QLocale::setDefault(QLocale::C);
    setlocale(LC_ALL, "C");

    check_installation();

    // Parse the command line.
    SuperLogger logger;
#ifdef _WIN32
    logger.set_log_target(create_string_log_target());
#endif
    CommandLineHandler cl;
    cl.parse(argc, const_cast<const char**>(argv), logger);

    configure_application(application);

    appleseed::studio::MainWindow window;

    if (!cl.m_filename.values().empty())
    {
        const QString filename = QString::fromStdString(cl.m_filename.value());

        if (cl.m_render.is_set())
        {
            const QString configuration = QString::fromStdString(cl.m_render.value());
            window.open_and_render_project(filename, configuration);
        }
        else
        {
            window.open_project(filename);
        }
    }

    window.show();

    return application.exec();
}
Exemplo n.º 5
0
int main(int argc, const char* argv[])
{
    SuperLogger logger;
    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Initialize the renderer's logger.
    global_logger().add_target(&logger.get_log_target());

    // Retrieve the input file path.
    const string& input_filepath = cl.m_filename.value();

    // Construct the schema file path.
    const filesystem::path schema_filepath =
          filesystem::path(Application::get_root_path())
        / "schemas"
        / "project.xsd";

    // Read the input project from disk.
    // Note: it is crucial that we read mesh files as well, so that we can collect
    // material slots declared by objects. Material slots are required by the project
    // file updater, for instance when migrating projects from rev. 7 to rev. 8.
    ProjectFileReader reader;
    auto_release_ptr<Project> project(
        reader.read(
            input_filepath.c_str(),
            schema_filepath.string().c_str(),
            ProjectFileReader::OmitProjectFileUpdate));

    // Bail out if the project couldn't be loaded.
    if (project.get() == 0)
        return 1;

    // Update the project file to the desired revision.
    ProjectFileUpdater updater;
    if (cl.m_to_revision.is_set())
        updater.update(project.ref(), cl.m_to_revision.value());
    else updater.update(project.ref());

    // Write the project back to disk.
    const bool success =
        ProjectFileWriter::write(
            project.ref(),
            project->get_path(),
            ProjectFileWriter::OmitWritingGeometryFiles | ProjectFileWriter::OmitBringingAssets);

    return success ? 0 : 1;
}
Exemplo n.º 6
0
int main(int argc, const char* argv[])
{
    SuperLogger logger;

    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    global_logger().add_target(&logger.get_log_target());

    // Retrieve the input file path.
    const string& input_filepath = cl.m_filename.values()[0];

    // Construct the schema file path.
    const string schema_filepath =
        (filesystem::path(Application::get_root_path())
        / "schemas" / "project.xsd").string();

    // Load the input project from disk.
    ProjectFileReader reader;
    auto_release_ptr<Project> project(
        reader.read(
            input_filepath.c_str(),
            schema_filepath.c_str(),
            ProjectFileReader::OmitReadingMeshFiles | ProjectFileReader::OmitProjectFileUpdate));

    // Bail out if the project couldn't be loaded.
    if (project.get() == 0)
        return 1;

    // Update the project file to the desired revision.
    ProjectFileUpdater updater;
    if (cl.m_to_revision.is_set())
        updater.update(project.ref(), cl.m_to_revision.values()[0]);
    else updater.update(project.ref());

    // Write the project back to disk.
    const bool success =
        ProjectFileWriter::write(
            project.ref(),
            project->get_path(),
            ProjectFileWriter::OmitWritingMeshFiles | ProjectFileWriter::OmitCopyingAssets);

    return success ? 0 : 1;
}
Exemplo n.º 7
0
int main(int argc, const char* argv[])
{
    SuperLogger logger;
    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Initialize the renderer's logger.
    global_logger().add_target(&logger.get_log_target());

    // Retrieve the command line arguments.
    const string& input_filepath = cl.m_filenames.values()[0];
    const string& output_filepath = cl.m_filenames.values()[1];
    const FluffParams params(cl);

    // Construct the schema file path.
    const filesystem::path schema_filepath =
          filesystem::path(Application::get_root_path())
        / "schemas"
        / "project.xsd";

    // Read the input project from disk.
    ProjectFileReader reader;
    auto_release_ptr<Project> project(
        reader.read(
            input_filepath.c_str(),
            schema_filepath.string().c_str()));

    // Bail out if the project couldn't be loaded.
    if (project.get() == 0)
        return 1;

    // Fluffify the project.
    make_fluffy(project.ref(), params);

    // Write the project back to disk.
    const bool success =
        ProjectFileWriter::write(
            project.ref(),
            output_filepath.c_str());

    return success ? 0 : 1;
}
Exemplo n.º 8
0
int main(int argc, const char* argv[])
{
    // Initialize the logger that will be used throughout the program.
    SuperLogger logger;

    // Make sure appleseed is correctly installed.
    Application::check_installation(logger);

    // Parse the command line.
    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Load an apply settings from the settings file.
    Dictionary settings;
    Application::load_settings("appleseed.tools.xml", settings, logger);
    logger.configure_from_settings(settings);

    // Apply command line arguments.
    cl.apply(logger);

    dump_metadata(cl.m_format.value(), logger);

    return 0;
}
Exemplo n.º 9
0
int main(int argc, char *argv[])
{
    /*
     * On X11, Tiled uses the 'raster' graphics system by default, because the
     * X11 native graphics system has performance problems with drawing the
     * tile grid.
     */
#ifdef Q_WS_X11
    QApplication::setGraphicsSystem(QLatin1String("raster"));
#endif

    TiledApplication a(argc, argv);

    a.setOrganizationDomain(QLatin1String("mapeditor.org"));
    a.setApplicationName(QLatin1String("Kodable Level Editor"));
#ifdef BUILD_INFO_VERSION
    a.setApplicationVersion(QLatin1String(AS_STRING(BUILD_INFO_VERSION)));
#else
    a.setApplicationVersion(QLatin1String("1.0"));
#endif

#ifdef Q_OS_MAC
    a.setAttribute(Qt::AA_DontShowIconsInMenus);
#endif

#if QT_VERSION >= 0x050100
    // Enable support for highres images (added in Qt 5.1, but off by default)
    a.setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

#ifndef Q_OS_WIN
    QString baseName = QApplication::style()->objectName();
    if (baseName == QLatin1String("windows")) {
        // Avoid Windows 95 style at all cost
        if (QStyleFactory::keys().contains(QLatin1String("Fusion"))) {
            baseName = QLatin1String("fusion"); // Qt5
        } else { // Qt4
            // e.g. if we are running on a KDE4 desktop
            QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
            if (desktopEnvironment == "kde")
                baseName = QLatin1String("plastique");
            else
                baseName = QLatin1String("cleanlooks");
        }
        a.setStyle(QStyleFactory::create(baseName));
    }
#endif

    LanguageManager *languageManager = LanguageManager::instance();
    languageManager->installTranslators();

    CommandLineHandler commandLine;

    if (!commandLine.parse(QCoreApplication::arguments()))
        return 0;
    if (commandLine.quit)
        return 0;
    if (commandLine.disableOpenGL)
        Preferences::instance()->setUseOpenGL(false);

    MainWindow w;
    w.show();

    QObject::connect(&a, SIGNAL(fileOpenRequest(QString)),
                     &w, SLOT(openFile(QString)));

    if (!commandLine.filesToOpen().isEmpty()) {
        foreach (const QString &fileName, commandLine.filesToOpen())
            w.openFile(fileName);
    } else {
Exemplo n.º 10
0
int main(int argc, char *argv[])
{
    /*
     * On X11, Tiled uses the 'raster' graphics system by default, because the
     * X11 native graphics system has performance problems with drawing the
     * tile grid.
     */
#ifdef Q_WS_X11
    QApplication::setGraphicsSystem(QLatin1String("raster"));
#endif

    TiledApplication a(argc, argv);

    a.setOrganizationDomain(QLatin1String("mapeditor.org"));
    a.setApplicationName(QLatin1String("Tiled - Sydoria Map Editor"));
#ifdef BUILD_INFO_VERSION
    a.setApplicationVersion(QLatin1String(AS_STRING(BUILD_INFO_VERSION)));
#else
    a.setApplicationVersion(QLatin1String("0.11.0"));
#endif

#ifdef Q_OS_MAC
    a.setAttribute(Qt::AA_DontShowIconsInMenus);
#endif

#if QT_VERSION >= 0x050100
    // Enable support for highres images (added in Qt 5.1, but off by default)
    a.setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

#ifndef Q_OS_WIN
    QString baseName = QApplication::style()->objectName();
    if (baseName == QLatin1String("windows")) {
        // Avoid Windows 95 style at all cost
        if (QStyleFactory::keys().contains(QLatin1String("Fusion"))) {
            baseName = QLatin1String("fusion"); // Qt5
        } else { // Qt4
            // e.g. if we are running on a KDE4 desktop
            QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
            if (desktopEnvironment == "kde")
                baseName = QLatin1String("plastique");
            else
                baseName = QLatin1String("cleanlooks");
        }
        a.setStyle(QStyleFactory::create(baseName));
    }
#endif

    LanguageManager *languageManager = LanguageManager::instance();
    languageManager->installTranslators();

    CommandLineHandler commandLine;

    if (!commandLine.parse(QCoreApplication::arguments()))
        return 0;
    if (commandLine.quit)
        return 0;
    if (commandLine.disableOpenGL)
        Preferences::instance()->setUseOpenGL(false);

    PluginManager::instance()->loadPlugins();

    if (commandLine.exportMap) {
        // Get the path to the source file and target file
        if (commandLine.filesToOpen().length() < 2) {
            qWarning() << qPrintable(QCoreApplication::translate("Command line",
                                                                 "Export syntax is --export-map [format] <tmx file> <target file>"));
            return 1;
        }
        int index = 0;
        const QString *filter = commandLine.filesToOpen().length() > 2 ? &commandLine.filesToOpen().at(index++) : 0;
        const QString &sourceFile = commandLine.filesToOpen().at(index++);
        const QString &targetFile = commandLine.filesToOpen().at(index++);

        // Find the map writer interface for the target file
        Tiled::MapWriterInterface *chosenWriter = 0;
        QString suffix = QFileInfo(targetFile).completeSuffix();
        QList<Tiled::MapWriterInterface*> writers = PluginManager::instance()->interfaces<Tiled::MapWriterInterface>();
        foreach (Tiled::MapWriterInterface *writer, writers) {
            if (filter) {
                if (writer->nameFilters().contains(*filter, Qt::CaseInsensitive)) {
                    chosenWriter = writer;
                }
            }
            else if (!writer->nameFilters().filter(suffix, Qt::CaseInsensitive).isEmpty()) {
                if (chosenWriter) {
                    qWarning() << qPrintable(QCoreApplication::translate("Command line",
                                                                         "Non-unique file extension. Can't determine correct export format."));
                    return 1;
                }
                chosenWriter = writer;
            }
        }
        if (!chosenWriter) {
            qWarning() << qPrintable(QCoreApplication::translate("Command line",
                                                                 "No exporter found for target file."));
            return 1;
        }

        // Load the source file
        Tiled::MapReader reader;
        Tiled::Map *map = reader.readMap(sourceFile);
        if (!map) {
            qWarning() << qPrintable(QCoreApplication::translate("Command line",
                                                                 "Failed to load source map."));
            return 1;
        }

        // Write out the file
        bool success = chosenWriter->write(map, targetFile);

        qDeleteAll(map->tilesets());
        delete map;

        if (!success) {
            qWarning() << qPrintable(QCoreApplication::translate("Command line",
                                                                 "Failed to export map to target file."));
            return 1;
        }
        return 0;
    }

    MainWindow w;
    w.show();

    QObject::connect(&a, SIGNAL(fileOpenRequest(QString)),
                     &w, SLOT(openFile(QString)));

    if (!commandLine.filesToOpen().isEmpty()) {
        foreach (const QString &fileName, commandLine.filesToOpen())
            w.openFile(fileName);
    } else {
Exemplo n.º 11
0
int main(int argc, const char* argv[])
{
    SuperLogger logger;

    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Retrieve the tile size.
    size_t tile_width = 32;
    size_t tile_height = 32;
    if (cl.m_tile_size.is_set())
    {
        const int tw = cl.m_tile_size.values()[0];
        const int th = cl.m_tile_size.values()[1];
        if (tw > 0 && th > 0)
        {
            tile_width = static_cast<size_t>(tw);
            tile_height = static_cast<size_t>(th);
        }
        else
        {
            LOG_ERROR(
                logger,
                "invalid tile size, using default size %dx%d pixels.",
                tile_width,
                tile_height);
        }
    }

    try
    {
        // Open the input file.
        GenericProgressiveImageFileReader reader(&logger, tile_width, tile_height);
        reader.open(cl.m_filenames.values()[0].c_str());

        // Read canvas properties from the input file.
        CanvasProperties props;
        reader.read_canvas_properties(props);

        // Read image attributes from the input file.
        ImageAttributes attrs;
        reader.read_image_attributes(attrs);

        // Open the output file.
        ProgressiveEXRImageFileWriter writer(&logger);
        writer.open(cl.m_filenames.values()[1].c_str(), props, attrs);

        // Copy the tiles.
        for (size_t y = 0; y < props.m_tile_count_y; ++y)
        {
            // Print a progress message.
            if (cl.m_progress_messages.is_set())
            {
                LOG_INFO(
                    logger,
                    "processing tile row " FMT_SIZE_T "/" FMT_SIZE_T "...",
                    y + 1,
                    props.m_tile_count_y);
            }

            for (size_t x = 0; x < props.m_tile_count_x; ++x)
            {
                // Read the tile.
                auto_release_ptr<Tile> tile(reader.read_tile(x, y));

                // Write the tile.
                writer.write_tile(*tile.get(), x, y);
            }
        }

        // Close the files.
        writer.close();
        reader.close();
    }
    catch (const StringException& e)
    {
        LOG_FATAL(logger, "%s: %s", e.what(), e.string());
        return 1;
    }
    catch (const Exception& e)
    {
        LOG_FATAL(logger, "%s", e.what());
        return 1;
    }

    return 0;
}
Exemplo n.º 12
0
int main(int argc, char* argv[])
{
    // Enable memory tracking immediately as to catch as many leaks as possible.
    start_memory_tracking();

    // Our message handler must be set before the construction of QApplication.
    g_previous_message_handler = qInstallMsgHandler(message_handler);

    QApplication application(argc, argv);
    QApplication::setOrganizationName("appleseedhq");
    QApplication::setOrganizationDomain("appleseedhq.net");
    QApplication::setApplicationName("appleseed.studio");
    QApplication::setApplicationVersion(Appleseed::get_lib_version());
    QApplication::setWindowIcon(QIcon(make_app_path("icons/appleseed.png")));
    application.setAttribute(Qt::AA_DontUseNativeMenuBar, true);

    // The locale must be set after the construction of QApplication.
    QLocale::setDefault(QLocale::C);

    // QApplication sets C locale to the user's locale, we need to fix this.
    std::setlocale(LC_ALL, "C");

    // QT changes locale when loading image from disk for the very first time.
    // The problem was tracked for both QImage and QPixmap.
    // Both classes in their `load()` function call `QImageReader.read()`
    // which results in change of the locale back to system settings.
    // This is a dirty fix which loads any image at the very beginning and
    // resets the locale right after, thus preventing the `QImageReader.read()`
    // to change it again (as it happens only on the very first `read`).
    // Issue reported and tracked on GitHub under reference #1435.
    QImageReader(make_app_path("icons/icon.png")).read();   // any image

    // Make sure this build can run on this host.
    check_compatibility();

    // Make sure appleseed is correctly installed.
    check_installation();

    // Parse the command line.
    SuperLogger logger;
#ifdef _WIN32
    // On Windows, we will display command line arguments in a message box
    // so we need to capture CommandLineHandler's output into a string.
    logger.set_log_target(create_string_log_target());
#endif
    CommandLineHandler cl;
    cl.parse(argc, const_cast<const char**>(argv), logger);

    // Configure the application to use our default stylesheet file.
    set_default_stylesheet(application);

    // Create the application's main window.
    appleseed::studio::MainWindow window;

    // Initialize the python interpreter and load plugins.
    PythonInterpreter::instance().set_main_window(&window);
    PythonInterpreter::instance().load_plugins();

    // If a project file was specified on the command line, open it and optionally start rendering.
    if (!cl.m_filename.values().empty())
    {
        const QString filename = QString::fromStdString(cl.m_filename.value());

        if (cl.m_render.is_set())
        {
            const QString configuration = QString::fromStdString(cl.m_render.value());
            window.open_and_render_project(filename, configuration);
        }
        else
        {
            window.open_project_async(filename);
        }
    }

    window.show();

    return application.exec();
}
Exemplo n.º 13
0
int main(int argc, char* argv[])
{
    // Enable memory tracking immediately as to catch as many leaks as possible.
    start_memory_tracking();

    // Our message handler must be set before the construction of QApplication.
    g_previous_message_handler = qInstallMessageHandler(message_handler);

    QApplication application(argc, argv);
    QApplication::setOrganizationName("appleseedhq");
    QApplication::setOrganizationDomain("appleseedhq.net");
    QApplication::setApplicationName("appleseed.studio");
    QApplication::setApplicationVersion(Appleseed::get_lib_version());
    QApplication::setWindowIcon(QIcon(make_app_path("icons/appleseed.png")));
    application.setAttribute(Qt::AA_DontUseNativeMenuBar, true);

    // The locale must be set after the construction of QApplication.
    QLocale::setDefault(QLocale::C);

    // Qt changes the locale when loading images from disk for the very first time.
    // The problem was tracked for both `QImage` and `QPixmap`: in their `load()`
    // functions, both classes call `QImageReader::read()` which causes the locale
    // to be changed to the system's one. The line that follows is a dirty fix
    // that consists in loading an image (any image) at the very beginning and
    // resetting the locale right after, thus preventing `QImageReader::read()`
    // from changing it again (as it happens only on the very first `read()`).
    // Issue reported and tracked on GitHub under reference #1435.
    QImageReader(make_app_path("icons/icon.png")).read();   // any image

    // Make sure this build can run on this host.
    check_compatibility();

    // Make sure appleseed is correctly installed.
    check_installation();

    // Configure the embedded Python interpreter.
    configure_python();

    // Parse the command line.
    CommandLineHandler cl;
    cl.parse(argc, argv);

    // Configure the application to use our default stylesheet file.
    set_default_stylesheet(application);

    // Create the application's main window.
    appleseed::studio::MainWindow window;

    // QApplication and QMainWindow set C locale to the user's locale, we need to fix this.
    std::setlocale(LC_ALL, "C");

    // Initialize the python interpreter and load plugins.
    PythonInterpreter::instance().set_main_window(&window);
    PythonInterpreter::instance().load_plugins();

    // If a project file was specified on the command line, open it and optionally start rendering.
    if (!cl.m_filename.values().empty())
    {
        const QString filename = QString::fromStdString(cl.m_filename.value());

        if (cl.m_render.is_set())
        {
            const QString configuration = QString::fromStdString(cl.m_render.value());
            window.open_and_render_project(filename, configuration);
        }
        else
        {
            window.open_project_async(filename);
        }
    }

    window.show();

    return application.exec();
}
Exemplo n.º 14
0
int main(int argc, const char* argv[])
{
    // Initialize the logger that will be used throughout the program.
    SuperLogger logger;

    // Make sure appleseed is correctly installed.
    Application::check_installation(logger);

    // Parse the command line.
    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Load an apply settings from the settings file.
    Dictionary settings;
    Application::load_settings("appleseed.tools.xml", settings, logger);
    logger.configure_from_settings(settings);

    // Apply command line arguments.
    cl.apply(logger);

    // Configure the renderer's global logger.
    // Must be done after settings have been loaded and the command line
    // has been parsed, because these two operations may replace the log
    // target of the global logger.
    global_logger().initialize_from(logger);

    // Retrieve the input file path.
    const string& input_filepath = cl.m_filename.value();

    // Construct the schema file path.
    const bf::path schema_filepath =
          bf::path(Application::get_root_path())
        / "schemas"
        / "project.xsd";

    // Read the input project from disk.
    // Note: it is crucial that we read mesh files as well, so that we can collect
    // material slots declared by objects. Material slots are required by the project
    // file updater, for instance when migrating projects from rev. 7 to rev. 8.
    ProjectFileReader reader;
    auto_release_ptr<Project> project(
        reader.read(
            input_filepath.c_str(),
            schema_filepath.string().c_str(),
            ProjectFileReader::OmitProjectFileUpdate));

    // Bail out if the project couldn't be loaded.
    if (project.get() == 0)
        return 1;

    // Update the project file to the desired revision.
    ProjectFileUpdater updater;
    if (cl.m_to_revision.is_set())
        updater.update(project.ref(), cl.m_to_revision.value());
    else updater.update(project.ref());

    // Write the project back to disk.
    const bool success =
        ProjectFileWriter::write(
            project.ref(),
            project->get_path(),
            ProjectFileWriter::OmitWritingGeometryFiles | ProjectFileWriter::OmitHandlingAssetFiles);

    return success ? 0 : 1;
}