/* * 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 GemInfo& oldGemInfo, const GemInfo& newGemInfo) override; AZ::Outcome GetGemInfo(const QString& path, const QString& projectPath = {}) override; AZ::Outcome, AZStd::string> GetEngineGemInfos() override; AZ::Outcome, AZStd::string> GetAllGemInfos(const QString& projectPath) override; AZ::Outcome, AZStd::string> GetEnabledGemNames(const QString& projectPath) 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) override; AZ::Outcome, AZStd::string> GetProjectsForAllRepos() override; bool AddProject(const QString& path) override; bool RemoveProject(const QString& path) override; AZ::Outcome UpdateProject(const ProjectInfo& projectInfo) override; AZ::Outcome AddGemToProject(const QString& gemPath, const QString& projectPath) override; AZ::Outcome RemoveGemFromProject(const QString& gemPath, const QString& projectPath) override; bool RemoveInvalidProjects() override; // Gem Repos AZ::Outcome RefreshGemRepo(const QString& repoUri) override; bool RefreshAllGemRepos() override; DetailedOutcome AddGemRepo(const QString& repoUri) override; bool RemoveGemRepo(const QString& repoUri) override; AZ::Outcome, AZStd::string> GetAllGemRepoInfos() override; AZ::Outcome, AZStd::string> GetGemInfosForRepo(const QString& repoUri) override; AZ::Outcome, AZStd::string> GetGemInfosForAllRepos() 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) const override; AZ::Outcome> GetProjectTemplatesForAllRepos() 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); ProjectTemplateInfo ProjectTemplateInfoFromPath(pybind11::handle path) const; TemplateInfo TemplateInfoFromPath(pybind11::handle path) const; AZ::Outcome GemRegistration(const QString& gemPath, const QString& projectPath, bool remove = false); bool StopPython(); IPythonBindings::ErrorPair GetErrorPair(); 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_cmake; pybind11::handle m_register; pybind11::handle m_manifest; pybind11::handle m_enableGemProject; pybind11::handle m_disableGemProject; pybind11::handle m_editProjectProperties; pybind11::handle m_download; pybind11::handle m_repo; pybind11::handle m_pathlib; bool m_requestCancelDownload = false; mutable AZStd::vector m_pythonErrorStrings; }; } // namespace O3DE::ProjectManager