/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #pragma once #include #include #include // Qt defines slots, which interferes with the use here. #pragma push_macro("slots") #undef slots #include #include #pragma pop_macro("slots") namespace O3DE::ProjectManager { class PythonBindings : public PythonBindingsInterface::Registrar { public: PythonBindings() = default; PythonBindings(const AZ::IO::PathView& enginePath); ~PythonBindings() override; // PythonBindings overrides bool PythonStarted() override; bool StartPython() override; // Engine AZ::Outcome> GetAllEngineInfos() override; AZ::Outcome GetEngineInfo() override; AZ::Outcome GetEngineInfo(const QString& engineName) override; AZ::Outcome GetProjectEngine(const QString& projectPath) override; DetailedOutcome SetEngineInfo(const EngineInfo& engineInfo, bool force = false) override; // Remote sources bool ValidateRepository(const QString& repoUri) override; // Gem AZ::Outcome CreateGem(const QString& templatePath, const GemInfo& gemInfo, bool registerGem = true) override; AZ::Outcome EditGem(const QString& oldGemName, const GemInfo& newGemInfo) override; AZ::Outcome GetGemInfo(const QString& path, const QString& projectPath = {}) override; AZ::Outcome, AZStd::string> GetAllGemInfos(const QString& projectPath) override; AZ::Outcome, AZStd::string> GetEnabledGems( const QString& projectPath, bool includeDependencies) const override; AZ::Outcome RegisterGem(const QString& gemPath, const QString& projectPath = {}) override; AZ::Outcome UnregisterGem(const QString& gemPath, const QString& projectPath = {}) override; // Project AZ::Outcome CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo, bool registerProject = true) override; AZ::Outcome GetProject(const QString& path) override; AZ::Outcome> GetProjects() override; AZ::Outcome, AZStd::string> GetProjectsForRepo(const QString& repoUri, bool enabledOnly = true) override; AZ::Outcome, AZStd::string> GetProjectsForAllRepos(bool enabledOnly = true) override; DetailedOutcome AddProject(const QString& path, bool force = false) override; DetailedOutcome RemoveProject(const QString& path) override; AZ::Outcome UpdateProject(const ProjectInfo& projectInfo) override; AZ::Outcome GetIncompatibleProjectGems( const QStringList& gemPaths, const QStringList& gemNames, const QString& projectPath) override; AZ::Outcome GetProjectEngineIncompatibleObjects( const QString& projectPath, const QString& enginePath = "") override; DetailedOutcome AddGemsToProject( const QStringList& gemPaths, const QStringList& gemNames, const QString& projectPath, bool force = false) override; AZ::Outcome RemoveGemFromProject(const QString& gemName, const QString& projectPath) override; bool RemoveInvalidProjects() override; // Remote Repos AZ::Outcome RefreshGemRepo(const QString& repoUri, bool downloadMissingOnly = false) override; bool RefreshAllGemRepos(bool downloadMissingOnly = false) override; DetailedOutcome AddGemRepo(const QString& repoUri) override; bool RemoveGemRepo(const QString& repoUri) override; bool SetRepoEnabled(const QString& repoUri, bool enabled) override; AZ::Outcome, AZStd::string> GetAllGemRepoInfos() override; AZ::Outcome, AZStd::string> GetGemInfosForRepo(const QString& repoUri, bool enabledOnly = true) override; AZ::Outcome, AZStd::string> GetGemInfosForAllRepos(const QString& projectPath, bool enabledOnly = true) override; DetailedOutcome DownloadGem( const QString& gemName, const QString& path, std::function gemProgressCallback, bool force = false) override; DetailedOutcome DownloadProject( const QString& projectName, const QString& path, std::function projectProgressCallback, bool force = false) override; DetailedOutcome DownloadTemplate( const QString& templateName, const QString& path, std::function templateProgressCallback, bool force = false) override; void CancelDownload() override; bool IsGemUpdateAvaliable(const QString& gemName, const QString& lastUpdated) override; // Templates AZ::Outcome> GetProjectTemplates() override; AZ::Outcome> GetProjectTemplatesForRepo(const QString& repoUri, bool enabledOnly = true) const override; AZ::Outcome> GetProjectTemplatesForAllRepos(bool enabledOnly = true) const override; AZ::Outcome> GetGemTemplates() override; void AddErrorString(AZStd::string errorString) override; protected: static void OnStdOut(const char* msg); static void OnStdError(const char* msg); private: AZ_DISABLE_COPY_MOVE(PythonBindings); AZ::Outcome ExecuteWithLockErrorHandling(AZStd::function executionCallback) const; bool ExecuteWithLock(AZStd::function executionCallback) const; EngineInfo EngineInfoFromPath(pybind11::handle enginePath); GemInfo GemInfoFromPath(pybind11::handle path, pybind11::handle pyProjectPath); GemRepoInfo GetGemRepoInfo(pybind11::handle repoUri); ProjectInfo ProjectInfoFromPath(pybind11::handle path); ProjectInfo ProjectInfoFromDict(pybind11::handle projectData, const QString& path = {}); ProjectTemplateInfo ProjectTemplateInfoFromPath(pybind11::handle path) const; ProjectTemplateInfo ProjectTemplateInfoFromDict(pybind11::handle templateData, const QString& path = {}) const; TemplateInfo TemplateInfoFromPath(pybind11::handle path) const; TemplateInfo TemplateInfoFromDict(pybind11::handle templateData, const QString& path = {}) const; AZ::Outcome GemRegistration(const QString& gemPath, const QString& projectPath, bool remove = false); bool StopPython(); IPythonBindings::ErrorPair GetErrorPair(); bool ExtendSysPath(const AZStd::vector& extendPaths); bool m_pythonStarted = false; AZ::IO::FixedMaxPath m_enginePath; mutable AZStd::recursive_mutex m_lock; pybind11::handle m_gemProperties; pybind11::handle m_engineTemplate; pybind11::handle m_engineProperties; pybind11::handle m_register; pybind11::handle m_manifest; pybind11::handle m_enableGemProject; pybind11::handle m_disableGemProject; pybind11::handle m_editProjectProperties; pybind11::handle m_projectManagerInterface; pybind11::handle m_download; pybind11::handle m_repo; pybind11::handle m_pathlib; bool m_requestCancelDownload = false; mutable AZStd::vector m_pythonErrorStrings; }; } // namespace O3DE::ProjectManager