/* * 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 #include #include #include #include namespace AZ { class ReflectContext; } namespace ScriptCanvasEditor { using SourceHandle = ScriptCanvas::SourceHandle; AZ_ENUM_CLASS_WITH_UNDERLYING_TYPE(InterpreterStatus, AZ::u8, Waiting, // no configuration Misconfigured, // configuration error Incompatible, // source is incompatible with with interpreter settings Configured, // configuration is good Pending, // waiting for asset readiness Ready, // asset ready Running, // running Stopped // (manually) stopped ); /// This class defines provides source and property configuration for ScriptCanvas graphs, and executes them /// as safely as possible. This can be used while the graph is being actively edited, whether in the O3DE provided editor or in /// another editor. When the graph properties are updated, the interpreter will always present and (attempt to) run the latest version. class Interpreter final : public ScriptCanvasBuilder::DataSystemAssetNotificationsBus::Handler { using Mutex = AZStd::recursive_mutex; using MutexLock = AZStd::lock_guard; public: AZ_TYPE_INFO(Interpreter, "{B77E5BC8-766A-4657-A30F-67797D04D10E}"); AZ_CLASS_ALLOCATOR(Interpreter, AZ::SystemAllocator); static void Reflect(AZ::ReflectContext* context); Interpreter(); ~Interpreter(); AZ::EventHandler ConnectOnStatusChanged(AZStd::function&& function) const; /// /// true iff the script was Executable bool Execute(); const Configuration& GetConfiguration() const; InterpreterStatus GetStatus() const; AZStd::string_view GetStatusString() const; bool IsExecutable() const; Configuration& ModConfiguration(); /// /// Allows a manual refresh of the configuration to update Editor properties. /// void RefreshConfiguration(); /// /// Sets the default user data in the Executable to a pointer to this Interpreter object. /// \note It will not be used until the next execution. /// void ResetUserData(); void SetScript(SourceHandle source); /// /// Stops the execution of the script if it is executable and stoppable. If the script does not require being stopped, does nothing. /// void Stop(); /// /// Sets the user data in the Executable to the input runtimeUserData. /// \note It will not be used until the next execution. /// void TakeUserData(ScriptCanvas::ExecutionUserData&& runtimeUserData); private: Mutex m_mutex; AZ::EventHandler m_handlerPropertiesChanged; AZ::EventHandler m_handlerSourceCompiled; AZ::EventHandler m_handlerSourceFailed; // #scriptcanvas_component_extension... AZ::EventHandler m_handlerUnacceptedComponentScript; mutable AZ::Event m_onStatusChanged; bool m_runtimePropertiesDirty = true; InterpreterStatus m_status = InterpreterStatus::Waiting; Configuration m_configuration; ScriptCanvas::Executor m_executor; bool InitializeExecution(ScriptCanvas::RuntimeAssetPtr asset); void OnAssetNotReady() override; void OnPropertiesChanged(); void OnReady(ScriptCanvas::RuntimeAssetPtr asset) override; void OnSourceCompiled(); void OnSourceFailed(); void OnSourceIncompatible(); void SetSatus(InterpreterStatus status); }; }