LUAEditorContext.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Component/Component.h>
  9. #include <AzCore/Math/Crc.h>
  10. #include <AzCore/std/optional.h>
  11. #include <AzCore/std/string/string_view.h>
  12. #include <AzCore/std/parallel/atomic.h>
  13. #include <AzCore/Asset/AssetCommon.h>
  14. #include <AzCore/UserSettings/UserSettings.h>
  15. #include "LUAEditorContextInterface.h"
  16. #include "LUAEditorContextMessages.h"
  17. #include "LUABreakpointTrackerMessages.h"
  18. #include "LUAStackTrackerMessages.h"
  19. #include "LUATargetContextTrackerMessages.h"
  20. #include "LUAWatchesDebuggerMessages.h"
  21. #include "LUAEditorContextMessages.h"
  22. #include "ClassReferencePanel.hxx"
  23. #include "LUAEditorMainWindow.hxx"
  24. #include "LUAEditorStyleMessages.h"
  25. #include <AzToolsFramework/SourceControl/SourceControlAPI.h>
  26. #include <AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkAPI.h>
  27. #include <AzCore/Component/TickBus.h>
  28. #include <AzFramework/Asset/AssetSystemBus.h>
  29. #include <AzFramework/Network/IRemoteTools.h>
  30. #include <AzCore/Script/ScriptTimePoint.h>
  31. #include <QStandardItem>
  32. #pragma once
  33. namespace AZ
  34. {
  35. namespace IO
  36. {
  37. class FileIOBase;
  38. }
  39. }
  40. namespace LUAEditor
  41. {
  42. class ReferenceItem;
  43. class BreakpointSavedState;
  44. //////////////////////////////////////////////////////////////////////////
  45. // Context
  46. // all editor components are responsible for maintaining the list of documents they are responsible for
  47. // and setting up editing facilities on those asset types in that "space".
  48. // editor contexts are components and have component ID's because we will communicate to them via buses.
  49. // this is the non-gui side of lua editing.
  50. // for example, keeping track of assets, opening documents, that sort of thing.
  51. // even though the editor can run headlessly, it always registers its gui stuff, they just never get called
  52. // this is because even headlessly, some GUI stuff (like qtScintilla stufF) might be required to actually parse the resources
  53. // its also harmless to register GUI components because they don't do anything until you send them messages like 'register your GUI stuff'
  54. // in general, the editor component for a particular kind of asset will be the one that registers its GUI stuff.
  55. class Context
  56. : public AZ::Component
  57. , private LegacyFramework::CoreMessageBus::Handler
  58. , private ContextInterface::Handler
  59. , private Context_DocumentManagement::Handler
  60. , private Context_DebuggerManagement::Handler
  61. , private LUABreakpointRequestMessages::Handler
  62. , private LUAWatchesRequestMessages::Handler
  63. , private LUATargetContextRequestMessages::Handler
  64. , private LUAStackRequestMessages::Handler
  65. , private HighlightedWords::Handler
  66. , private AzFramework::AssetSystemInfoBus::Handler
  67. {
  68. friend class ContextFactory;
  69. public:
  70. AZ_COMPONENT(Context, "{8F606ADE-8D29-4239-9DF4-53E5E42D9685}");
  71. Context();
  72. virtual ~Context();
  73. Context(const Context&);
  74. //////////////////////////////////////////////////////////////////////////
  75. // AZ::Component
  76. void Init() override;
  77. void Activate() override;
  78. void Deactivate() override;
  79. //////////////////////////////////////////////////////////////////////////
  80. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
  81. //////////////////////////////////////////////////////////////////////////
  82. // EditorFramework::CoreMessageBus::Handler
  83. void RunAsAnotherInstance() override;
  84. //////////////////////////////////////////////////////////////////////////
  85. //////////////////////////////////////////////////////////////////////////
  86. // AzToolsFramework::AssetSystemInfoBus::Handler
  87. void AssetCompilationSuccess(const AZStd::string& assetPath) override;
  88. void AssetCompilationFailed(const AZStd::string& assetPath) override;
  89. //////////////////////////////////////////////////////////////////////////
  90. //////////////////////////////////////////////////////////////////////////
  91. // IPC Handlers
  92. bool OnIPCOpenFiles(const AZStd::string& parameters);
  93. //////////////////////////////////////////////////////////////////////////
  94. //////////////////////////////////////////////////////////////////////////
  95. // ContextInterface Messages
  96. // it is an error to call GetDocumentData when the data is not yet ready.
  97. void ShowLUAEditorView() override;
  98. // this occurs from time to time, generally triggered when some external event occurs
  99. // that makes it suspect that its document statuses might be invalid:
  100. //////////////////////////////////////////////////////////////////////////
  101. //////////////////////////////////////////////////////////////////////////
  102. //Context_DocumentManagement Messages
  103. void OnNewDocument(const AZStd::string& assetId) override;
  104. void OnLoadDocument(const AZStd::string& assetId, bool errorOnNotFound) override;
  105. void OnCloseDocument(const AZStd::string& assetId) override;
  106. void OnSaveDocument(const AZStd::string& assetId, bool bCloseAfterSaved, bool bSaveAs) override;
  107. bool OnSaveDocumentAs(const AZStd::string& assetId, bool bCloseAfterSaved) override;
  108. void NotifyDocumentModified(const AZStd::string& assetId, bool modified) override;
  109. void DocumentCheckOutRequested(const AZStd::string& assetId) override;
  110. void RefreshAllDocumentPerforceStat() override;
  111. void OnReloadDocument(const AZStd::string assetId) override;
  112. void UpdateDocumentData(const AZStd::string& assetId, const char* dataPtr, const AZStd::size_t dataLength) override;
  113. void GetDocumentData(const AZStd::string& assetId, const char** dataPtr, AZStd::size_t& dataLength) override;
  114. //////////////////////////////////////////////////////////////////////////
  115. //////////////////////////////////////////////////////////////////////////
  116. // Remote Tools Events
  117. //////////////////////////////////////////////////////////////////////////
  118. void DesiredTargetConnected(bool connected);
  119. void DesiredTargetChanged(AZ::u32 newTargetID, AZ::u32 oldTargetID);
  120. //////////////////////////////////////////////////////////////////////////
  121. //Context_DebuggerManagement Messages
  122. //////////////////////////////////////////////////////////////////////////
  123. void ExecuteScriptBlob(const AZStd::string& fromAssetId, bool executeLocal) override;
  124. void SynchronizeBreakpoints() override;
  125. void CreateBreakpoint(const AZStd::string& fromAssetId, int lineNumber) override;
  126. void MoveBreakpoint(const AZ::Uuid& breakpointUID, int lineNumber) override;
  127. void DeleteBreakpoint(const AZ::Uuid& breakpointUID) override;
  128. void CleanUpBreakpoints() override;
  129. // These come from the VM
  130. void OnDebuggerAttached() override;
  131. void OnDebuggerRefused() override;
  132. void OnDebuggerDetached() override;
  133. void OnBreakpointHit(const AZStd::string& assetIdString, int lineNumber) override;
  134. void OnBreakpointAdded(const AZStd::string& assetIdString, int lineNumber) override;
  135. void OnBreakpointRemoved(const AZStd::string& assetIdString, int lineNumber) override;
  136. void OnReceivedAvailableContexts(const AZStd::vector<AZStd::string>& contexts) override;
  137. void OnReceivedRegisteredClasses(const AzFramework::ScriptUserClassList& classes) override;
  138. void OnReceivedRegisteredEBuses(const AzFramework::ScriptUserEBusList& ebuses) override;
  139. void OnReceivedRegisteredGlobals(const AzFramework::ScriptUserMethodList& methods, const AzFramework::ScriptUserPropertyList& properties) override;
  140. void OnReceivedLocalVariables(const AZStd::vector<AZStd::string>& vars) override;
  141. void OnReceivedCallstack(const AZStd::vector<AZStd::string>& callstack) override;
  142. void OnReceivedValueState(const AZ::ScriptContextDebug::DebugValue& value) override;
  143. void OnSetValueResult(const AZStd::string& name, bool success) override;
  144. void OnExecutionResumed() override;
  145. void OnExecuteScriptResult(bool success) override;
  146. //////////////////////////////////////////////////////////////////////////
  147. //BreakpointTracker Messages
  148. //////////////////////////////////////////////////////////////////////////
  149. const BreakpointMap* RequestBreakpoints() override;
  150. void RequestEditorFocus(const AZStd::string& assetIdString, int lineNumber) override;
  151. void RequestDeleteBreakpoint(const AZStd::string& assetIdString, int lineNumber) override;
  152. //////////////////////////////////////////////////////////////////////////
  153. //StackTracker Messages
  154. //////////////////////////////////////////////////////////////////////////
  155. void RequestStackClicked(const AZStd::string& stackString, int lineNumber) override;
  156. //////////////////////////////////////////////////////////////////////////
  157. //TargetContextTracker Messages
  158. //////////////////////////////////////////////////////////////////////////
  159. virtual const AZStd::vector<AZStd::string> RequestTargetContexts() override;
  160. const AZStd::string RequestCurrentTargetContext() override;
  161. void SetCurrentTargetContext(AZStd::string& contextName) override;
  162. //////////////////////////////////////////////////////////////////////////
  163. //Watch window messages
  164. //////////////////////////////////////////////////////////////////////////
  165. void RequestWatchedVariable(const AZStd::string& varName) override;
  166. //////////////////////////////////////////////////////////////////////////
  167. //Debug Request messages
  168. //////////////////////////////////////////////////////////////////////////
  169. void RequestDetachDebugger() override;
  170. void RequestAttachDebugger() override;
  171. //////////////////////////////////////////////////////////////////////////
  172. // AzToolsFramework CoreMessages
  173. void OnRestoreState() override; // sent when everything is registered up and ready to go, this is what bootstraps stuff to get going.
  174. bool OnGetPermissionToShutDown() override;
  175. bool CheckOkayToShutDown() override;
  176. void OnSaveState() override; // sent to everything when the app is about to shut down - do what you need to do.
  177. void OnDestroyState() override;
  178. void ApplicationDeactivated() override;
  179. void ApplicationActivated() override;
  180. void ApplicationShow(AZ::Uuid id) override;
  181. void ApplicationHide(AZ::Uuid id) override;
  182. void ApplicationCensus() override;
  183. //////////////////////////////////////////////////////////////////////////
  184. //////////////////////////////////////////////////////////////////////////
  185. // HighlightedWords
  186. const HighlightedWords::LUAKeywordsType* GetLUAKeywords() override { return &m_LUAKeywords; }
  187. const HighlightedWords::LUAKeywordsType* GetLUALibraryFunctions() override { return &m_LUALibraryFunctions; }
  188. // internal data structure for the LUA debugger class/member/property reference panel
  189. // this is what we serialize and work with
  190. struct ContextReference
  191. {
  192. struct
  193. {
  194. AzFramework::ScriptUserMethodList m_methods;
  195. AzFramework::ScriptUserPropertyList m_properties;
  196. } m_globals;
  197. AzFramework::ScriptUserClassList m_classes;
  198. AzFramework::ScriptUserEBusList m_buses;
  199. };
  200. // map of context -> reference info
  201. AZStd::unordered_map<AZStd::string, ContextReference> m_reference;
  202. void UpdateReferenceWindow();
  203. void ResetTargetContexts();
  204. // this bridges to the QT data model built from our internal data handling format
  205. QStandardItemModel* m_referenceModel;
  206. protected:
  207. static void Reflect(AZ::ReflectContext* reflection);
  208. private:
  209. using DocumentInfoMap = AZStd::unordered_map<AZStd::string, DocumentInfo> ;
  210. AZStd::optional<const DocumentInfoMap::iterator> FindDocumentInfo(const AZStd::string_view assetId);
  211. //////////////////////////////////////////////////////////////////////////
  212. // AssetManagementMessages
  213. //Our callback that tell us when the asset read request finishes
  214. void DataLoadDoneCallback(bool success, const AZStd::string& assetId);
  215. //Our callback that tell us when the asset write request finishes
  216. void DataSaveDoneCallback(bool success, const AZStd::string& assetId);
  217. // the asset manager will invoke this when the user indicates the intent to open an asset of a given type with a given name.
  218. // it will be up to the component that manages the state to actually perform what is needed to achieve this.
  219. virtual void AssetOpenRequested(const AZStd::string& assetId, bool errorOnNotFound);
  220. void OpenAssetByPhysicalPath(const char* physicalPath);
  221. void ProcessFailedAssetMessages();
  222. AZStd::mutex m_failedAssetMessagesMutex; // protects m_failedAssets from draining and adding entries into it from different threads at the same time
  223. AZStd::queue<AZStd::string> m_failedAssets;
  224. // the asset manager will invoke this when the user indicates they want to make a new asset of a given type.
  225. //virtual void AssetNewRequested(const AzToolsFramework::RegisteredAssetType& descriptor);
  226. //////////////////////////////////////////////////////////////////////////
  227. void AddDefaultLUAKeywords();
  228. void AddDefaultLUALibraryFunctions();
  229. bool m_queuedOpenRecent;
  230. AZStd::string mostRecentlyOpenedDocumentView;
  231. void OpenMostRecentDocumentView();
  232. void PerforceStatResponseCallback(bool success, const AzToolsFramework::SourceControlFileInfo& fileInfo, const AZStd::string& assetId);
  233. void PerforceRequestEditCallback(bool success, const AzToolsFramework::SourceControlFileInfo& fileInfo, const AZStd::string& assetId);
  234. bool IsLuaAsset(const AZStd::string& assetPath);
  235. DocumentInfoMap m_documentInfoMap;
  236. LUAEditorMainWindow* m_pLUAEditorMainWindow;
  237. bool m_connectedState;
  238. AZStd::vector<AZStd::string> m_targetContexts;
  239. AZStd::string m_currentTargetContext;
  240. AZStd::vector<AZStd::string> m_filesToOpen;
  241. public:
  242. // Script interface:
  243. void LoadLayout();
  244. void SaveLayout();
  245. private:
  246. AZStd::vector<CompilationErrorData*> m_errorData;
  247. // utility
  248. void ProvisionalShowAndFocus(bool forceShow = false, bool forcedHide = false);
  249. // breakpoint types are carried by the tracker bus, the context uses those types internally as do listeners
  250. AZStd::intrusive_ptr<BreakpointSavedState> m_pBreakpointSavedState;
  251. //AssetTypes::LUAIntermediateHandler *m_pAssetHandler;
  252. AZStd::atomic_int m_numOutstandingOperations;
  253. bool m_bShuttingDown;
  254. bool m_bProcessingActivate;
  255. // these documents have been modified whilst the user was alt tabbed, we should check them:
  256. void ProcessReloadCheck();
  257. bool m_bReloadCheckQueued;
  258. AZStd::unordered_set<AZStd::string> m_reloadCheckDocuments;
  259. HighlightedWords::LUAKeywordsType m_LUAKeywords;
  260. HighlightedWords::LUAKeywordsType m_LUALibraryFunctions;
  261. AZ::IO::FileIOBase* m_fileIO;
  262. LegacyFramework::IPCHandleType m_ipcOpenFilesHandle;
  263. AzFramework::RemoteToolsEndpointConnectedEvent::Handler m_connectedEventHandler;
  264. AzFramework::RemoteToolsEndpointChangedEvent::Handler m_changedEventHandler;
  265. };
  266. class ReferenceItem
  267. : public QStandardItem
  268. {
  269. public:
  270. AZ_CLASS_ALLOCATOR(ReferenceItem, AZ::SystemAllocator);
  271. ReferenceItem(const QIcon& icon, const QString& text, size_t id);
  272. ReferenceItem(const QString& text, size_t id);
  273. ~ReferenceItem() {}
  274. size_t GetTypeID() {return m_Id; }
  275. protected:
  276. size_t m_Id;
  277. };
  278. ////////////////////////////////////////////////////////////////////////////
  279. ////Context Factory
  280. //class ContextFactory : public AZ::ComponentFactory<Context>
  281. //{
  282. //public:
  283. // AZ_CLASS_ALLOCATOR(ContextFactory,AZ::SystemAllocator,0)
  284. // ContextFactory() : AZ::ComponentFactory<Context>(AZ_CRC_CE("LUAEditor::Context")){}
  285. // virtual const char* GetName() {return "LUAEditor::Context";}
  286. // virtual void Reflect(AZ::ReflectContext* reflection);
  287. //};
  288. class LUAEditorContextSavedState
  289. : public AZ::UserSettings
  290. {
  291. public:
  292. AZ_RTTI(LUAEditorContextSavedState, "{3FEBF499-760C-4275-AF47-C1D5A131D4BA}", AZ::UserSettings);
  293. AZ_CLASS_ALLOCATOR(LUAEditorContextSavedState, AZ::SystemAllocator);
  294. bool m_MainEditorWindowIsVisible;
  295. bool m_MainEditorWindowIsOpen;
  296. LUAEditorContextSavedState()
  297. : m_MainEditorWindowIsVisible(true)
  298. , m_MainEditorWindowIsOpen(true) {}
  299. static void Reflect(AZ::ReflectContext* reflection);
  300. };
  301. };