CryEdit.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  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. #ifndef CRYINCLUDE_EDITOR_CRYEDIT_H
  9. #define CRYINCLUDE_EDITOR_CRYEDIT_H
  10. #pragma once
  11. #if !defined(Q_MOC_RUN)
  12. #include <AzCore/Outcome/Outcome.h>
  13. #include <AzFramework/Asset/AssetSystemBus.h>
  14. #include "CryEditDoc.h"
  15. #include "ViewPane.h"
  16. #include <QSettings>
  17. #endif
  18. class CCryDocManager;
  19. class CCryEditDoc;
  20. class CEditCommandLineInfo;
  21. class CMainFrame;
  22. class CConsoleDialog;
  23. class QAction;
  24. class MainWindow;
  25. class QSharedMemory;
  26. class SANDBOX_API RecentFileList
  27. {
  28. public:
  29. RecentFileList();
  30. void Remove(int index);
  31. void Add(const QString& filename);
  32. int GetSize();
  33. void GetDisplayName(QString& name, int index, const QString& curDir);
  34. QString& operator[](int index);
  35. void ReadList();
  36. void WriteList();
  37. static const int Max = 12;
  38. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  39. QStringList m_arrNames;
  40. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  41. QSettings m_settings;
  42. };
  43. /**
  44. * Bus for controlling the application's idle processing (may include things like entity updates, ticks, viewport rendering, etc.).
  45. * This is sometimes necessary in special event-processing loops to prevent long (or infinite) processing time because Idle Processing
  46. * can perpetually generate more events.
  47. */
  48. class EditorIdleProcessing : public AZ::EBusTraits
  49. {
  50. public:
  51. using Bus = AZ::EBus<EditorIdleProcessing>;
  52. static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
  53. static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
  54. /// Disable the Editor's idle processing. EnableIdleProcessing() must be called exactly once when special processing is complete.
  55. virtual void DisableIdleProcessing() {}
  56. /// Re-enables Idle Processing. Must be called exactly one time for every call to DisableIdleProcessing().
  57. virtual void EnableIdleProcessing() {}
  58. };
  59. using EditorIdleProcessingBus = AZ::EBus<EditorIdleProcessing>;
  60. enum class COpenSameLevelOptions
  61. {
  62. ReopenLevelIfSame,
  63. NotReopenIfSame
  64. };
  65. AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
  66. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  67. class SANDBOX_API CCryEditApp
  68. : public QObject
  69. , protected AzFramework::AssetSystemInfoBus::Handler
  70. , protected EditorIdleProcessingBus::Handler
  71. , protected AzFramework::AssetSystemStatusBus::Handler
  72. {
  73. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  74. AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
  75. friend MainWindow;
  76. Q_OBJECT
  77. public:
  78. enum ECreateLevelResult
  79. {
  80. ECLR_OK = 0,
  81. ECLR_ALREADY_EXISTS,
  82. ECLR_DIR_CREATION_FAILED,
  83. ECLR_MAX_PATH_EXCEEDED
  84. };
  85. CCryEditApp();
  86. ~CCryEditApp();
  87. static CCryEditApp* instance();
  88. bool CreateLevel(bool& wasCreateLevelOperationCancelled);
  89. void LoadFile(QString fileName);
  90. void ForceNextIdleProcessing() { m_bForceProcessIdle = true; }
  91. void KeepEditorActive(bool bActive) { m_bKeepEditorActive = bActive; };
  92. bool IsInTestMode() const { return m_bTestMode; };
  93. bool IsInPreviewMode() const { return m_bPreviewMode; };
  94. bool IsInExportMode() const { return m_bExportMode; };
  95. bool IsExportingLegacyData() const { return m_bIsExportingLegacyData; }
  96. bool IsInConsoleMode() const { return m_bConsoleMode; };
  97. bool IsInAutotestMode() const { return m_bAutotestMode; };
  98. bool IsInLevelLoadTestMode() const { return m_bLevelLoadTestMode; }
  99. bool IsInRegularEditorMode();
  100. bool IsExiting() const { return m_bExiting; }
  101. void EnableAccelerator(bool bEnable);
  102. void SaveAutoBackup();
  103. void SaveAutoRemind();
  104. void ExportToGame(bool bNoMsgBox = true);
  105. //! \param sTitleStr overwrites the default title of the Editor
  106. void SetEditorWindowTitle(QString sTitleStr = QString(), QString sPreTitleStr = QString(), QString sPostTitleStr = QString());
  107. RecentFileList* GetRecentFileList();
  108. virtual void AddToRecentFileList(const QString& lpszPathName);
  109. ECreateLevelResult CreateLevel(const QString& templateName, const QString& levelName, QString& fullyQualifiedLevelName);
  110. bool FirstInstance(bool bForceNewInstance = false);
  111. void InitFromCommandLine(CEditCommandLineInfo& cmdInfo);
  112. bool CheckIfAlreadyRunning();
  113. //! @return successful outcome if initialization succeeded. or failed outcome with error message.
  114. AZ::Outcome<void, AZStd::string> InitGameSystem(HWND hwndForInputSystem);
  115. void CreateSplashScreen();
  116. void InitPlugins();
  117. bool InitGame();
  118. bool InitConsole();
  119. int IdleProcessing(bool bBackground);
  120. bool IsWindowInForeground();
  121. void RunInitPythonScript(CEditCommandLineInfo& cmdInfo);
  122. void DisableIdleProcessing() override;
  123. void EnableIdleProcessing() override;
  124. // Print to stdout even if there out has been redirected
  125. void PrintAlways(const AZStd::string& output);
  126. //! Launches the Lua Editor/Debugger
  127. //! \param files A space separated list of aliased paths
  128. void OpenLUAEditor(const char* files);
  129. QString GetRootEnginePath() const;
  130. void RedirectStdoutToNull();
  131. // Overrides
  132. public:
  133. virtual bool InitInstance();
  134. virtual int ExitInstance(int exitCode = 0);
  135. virtual bool OnIdle(LONG lCount);
  136. virtual CCryEditDoc* OpenDocumentFile(const char* filename,
  137. bool addToMostRecentFileList=true,
  138. COpenSameLevelOptions openSameLevelOptions = COpenSameLevelOptions::NotReopenIfSame);
  139. CCryDocManager* GetDocManager() { return m_pDocManager; }
  140. // Implementation
  141. void OnCreateLevel();
  142. void OnOpenLevel();
  143. void OnAppAbout();
  144. void OnAppShowWelcomeScreen();
  145. void OnUpdateShowWelcomeScreen(QAction* action);
  146. void OnDocumentationTutorials();
  147. void OnDocumentationGlossary();
  148. void OnDocumentationO3DE();
  149. void OnDocumentationReleaseNotes();
  150. void OnDocumentationGameDevBlog();
  151. void OnDocumentationForums();
  152. void OnEditHold();
  153. void OnEditFetch();
  154. void OnFileExportToGameNoSurfaceTexture();
  155. void OnViewSwitchToGame();
  156. void OnViewSwitchToGameFullScreen();
  157. void OnMoveObject();
  158. void OnRenameObj();
  159. void OnUndo();
  160. void OnEditLevelData();
  161. void OnFileEditLogFile();
  162. void OnFileEditEditorini();
  163. void OnPreferences();
  164. void OnOpenProjectManagerSettings();
  165. void OnOpenProjectManagerNew();
  166. void OnOpenProjectManager();
  167. void OnRedo();
  168. void OnUpdateRedo(QAction* action);
  169. void OnUpdateUndo(QAction* action);
  170. void OnSwitchPhysics();
  171. void OnSwitchPhysicsUpdate(QAction* action);
  172. void OnSyncPlayer();
  173. void OnSyncPlayerUpdate(QAction* action);
  174. void OnResourcesReduceworkingset();
  175. void OnDummyCommand() {};
  176. void OnFileSave();
  177. void OnUpdateDocumentReady(QAction* action);
  178. void OnUpdateFileOpen(QAction* action);
  179. void OnUpdateNonGameMode(QAction* action);
  180. void OnUpdateNewLevel(QAction* action);
  181. void OnUpdatePlayGame(QAction* action);
  182. void OnToolsLogMemoryUsage();
  183. void OnToolsPreferences();
  184. protected:
  185. // ------- AzFramework::AssetSystemInfoBus::Handler ------
  186. void OnError(AzFramework::AssetSystem::AssetSystemErrors error) override;
  187. // -------------------------------------------
  188. // ------- AzFramework::AssetSystemStatusBus::Handler ------
  189. void AssetSystemWaiting() override;
  190. // -------------------------------------------
  191. private:
  192. friend class EditorActionsHandler;
  193. void InitLevel(const CEditCommandLineInfo& cmdInfo);
  194. bool ConnectToAssetProcessor() const;
  195. void CompileCriticalAssets() const;
  196. CMainFrame* GetMainFrame() const;
  197. void WriteConfig();
  198. bool UserExportToGame(bool bNoMsgBox = true);
  199. static void ShowSplashScreen(CCryEditApp* app);
  200. static void CloseSplashScreen();
  201. static void OutputStartupMessage(QString str);
  202. bool ShowEnableDisableGemDialog(const QString& title, const QString& message);
  203. QString ShowWelcomeDialog();
  204. bool FixDanglingSharedMemory(const QString& sharedMemName) const;
  205. //! Displays level load errors after a certain number of idle frames have been processed.
  206. //! Due to the asyncrhonous nature of loading assets any errors that are reported by components
  207. //! can happen after the level is loaded. This method will wait for a few idle updates and then
  208. //! display the load errors to ensure all errors are displayed properly.
  209. void DisplayLevelLoadErrors();
  210. class CEditorImpl* m_pEditor = nullptr;
  211. static CCryEditApp* s_currentInstance;
  212. //! True if editor is in test mode.
  213. //! Test mode is a special mode enabled when Editor ran with /test command line.
  214. //! In this mode editor starts up, but exit immediately after all initialization.
  215. bool m_bTestMode = false;
  216. //! In this mode editor will load specified cry file, export t, and then close.
  217. bool m_bExportMode = false;
  218. QString m_exportFile;
  219. //! This flag is set to true every time any of the "Export" commands is being executed.
  220. //! Once exporting is finished the flag is set back to false.
  221. //! UI events like "New Level" or "Open Level", should not be allowed while m_bIsExportingLegacyData==true.
  222. //! Otherwise it could trigger crashes trying to export while exporting.
  223. bool m_bIsExportingLegacyData = false;
  224. //! If application exiting.
  225. bool m_bExiting = false;
  226. //! True if editor is in preview mode.
  227. //! In this mode only very limited functionality is available and only for fast preview of models.
  228. bool m_bPreviewMode = false;
  229. // Only console window is created.
  230. bool m_bConsoleMode = false;
  231. // Skip showing the WelcomeScreenDialog
  232. bool m_bSkipWelcomeScreenDialog = false;
  233. // Level load test mode
  234. bool m_bLevelLoadTestMode = false;
  235. //! Current file in preview mode.
  236. char m_sPreviewFile[_MAX_PATH];
  237. //! True if "/runpythontest" was passed as a flag.
  238. bool m_bRunPythonTestScript = false;
  239. //! True if "/runpython" was passed as a flag.
  240. bool m_bRunPythonScript = false;
  241. //! File to run on startup
  242. QString m_execFile;
  243. //! Command to run on startup
  244. QString m_execLineCmd;
  245. //! Autotest mode: Special mode meant for automated testing, things like blocking dialogs or error report windows won't appear
  246. bool m_bAutotestMode = false;
  247. CConsoleDialog* m_pConsoleDialog = nullptr;
  248. float m_fastRotateAngle = 45.0f;
  249. float m_moveSpeedStep = 0.1f;
  250. ULONG_PTR m_gdiplusToken;
  251. QSharedMemory* m_mutexApplication = nullptr;
  252. //! was the editor active in the previous frame ... needed to detect if the game lost focus and
  253. //! dispatch proper SystemEvent (needed to release input keys)
  254. bool m_bPrevActive = false;
  255. // If this flag is set, the next OnIdle() will update, even if the app is in the background, and then
  256. // this flag will be reset.
  257. bool m_bForceProcessIdle = false;
  258. // This is set while IdleProcessing is running to prevent re-entrancy
  259. bool m_idleProcessingRunning = false;
  260. // Keep the editor alive, even if no focus is set
  261. bool m_bKeepEditorActive = false;
  262. // Currently creating a new level
  263. bool m_creatingNewLevel = false;
  264. bool m_openingLevel = false;
  265. bool m_savingLevel = false;
  266. // Flag indicating if the errors for the currently loaded level have been displayed
  267. bool m_levelErrorsHaveBeenDisplayed = false;
  268. // Number of idle frames that have passed before displaying level errors
  269. int m_numBeforeDisplayErrorFrames = 0;
  270. QString m_lastOpenLevelPath;
  271. QString m_rootEnginePath;
  272. int m_disableIdleProcessingCounter = 0; //!< Counts requests to disable idle processing. When non-zero, idle processing will be disabled.
  273. CCryDocManager* m_pDocManager = nullptr;
  274. // Disable warning for dll export since this member won't be used outside this class
  275. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  276. AZ::IO::FileDescriptorRedirector m_stdoutRedirection = AZ::IO::FileDescriptorRedirector(1); // < 1 for STDOUT
  277. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  278. private:
  279. // Optional Uri to start an external lua debugger. If not specified,
  280. // then the Editor will open LuaIDE.exe.
  281. // For example, if using The Visual Studio Debugger Extension provided by lumbermixalot
  282. // The value will be: "vscode://lumbermixalot.o3de-lua-debug/debug?"
  283. // The following parameters will be added to the URI at runtime:
  284. // "projectPath". Absolute path of the game projec root.
  285. // "enginePath". Absolute path of the engine root. if not specified, it will be assume to be one directory above the game project root.
  286. // "files[]". A list of files,
  287. // Full example using the Uri shown below:
  288. // "vscode://lumbermixalot.o3de-lua-debug/debug?projectPath=D:\mydir\myproject&enginePath=C:\GIT\o3de&files[]=D:\mydir\myproject\scripts\something.lua&files[]=D:\mydir\myproject\scripts\utils\something2.lua"
  289. // or
  290. // "vscode://lumbermixalot.o3de-lua-debug/debug?projectPath=D:\GIT\o3de\AutomatedTesting&files[]=D:\GIT\o3de\AutomatedTesting\Assets\Scripts\something.lua"
  291. static constexpr AZStd::string_view LuaDebuggerUriRegistryKey = "/O3DE/Lua/Debugger/Uri";
  292. struct PythonOutputHandler;
  293. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  294. AZStd::shared_ptr<PythonOutputHandler> m_pythonOutputHandler;
  295. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  296. friend struct PythonTestOutputHandler;
  297. void OpenProjectManager(const AZStd::string& screen);
  298. void OnUpdateWireframe(QAction* action);
  299. void OnViewConfigureLayout();
  300. void OnCustomizeKeyboard();
  301. void OnToolsScriptHelp();
  302. void OnViewCycle2dviewport();
  303. void OnDisplayGotoPosition();
  304. void OnFileSavelevelresources();
  305. void OnClearRegistryData();
  306. void OnSwitchToSequenceCamera();
  307. void OnUpdateSwitchToSequenceCamera(QAction* action);
  308. void OnSwitchToSelectedcamera();
  309. void OnUpdateSwitchToSelectedCamera(QAction* action);
  310. void OnSwitchcameraNext();
  311. void OnOpenProceduralMaterialEditor();
  312. void OnOpenAssetBrowserView();
  313. void OnOpenTrackView();
  314. void OnOpenAudioControlsEditor();
  315. void OnOpenUICanvasEditor();
  316. // @param files: A list of file paths, separated by '|';
  317. void OpenExternalLuaDebugger(AZStd::string_view luaDebuggerUri, AZStd::string_view enginePath, AZStd::string_view projectPath, const char * files);
  318. public:
  319. void ExportLevel(bool bExportToGame, bool bExportTexture, bool bAutoExport);
  320. static bool Command_ExportToEngine();
  321. };
  322. //////////////////////////////////////////////////////////////////////////
  323. class CCrySingleDocTemplate
  324. : public QObject
  325. {
  326. Q_OBJECT
  327. private:
  328. explicit CCrySingleDocTemplate(const QMetaObject* pDocClass)
  329. : QObject()
  330. , m_documentClass(pDocClass)
  331. {
  332. }
  333. public:
  334. enum Confidence
  335. {
  336. noAttempt,
  337. maybeAttemptForeign,
  338. maybeAttemptNative,
  339. yesAttemptForeign,
  340. yesAttemptNative,
  341. yesAlreadyOpen
  342. };
  343. template<typename DOCUMENT>
  344. static CCrySingleDocTemplate* create()
  345. {
  346. return new CCrySingleDocTemplate(&DOCUMENT::staticMetaObject);
  347. }
  348. ~CCrySingleDocTemplate() {};
  349. // avoid creating another CMainFrame
  350. // close other type docs before opening any things
  351. virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool addToMostRecentFileList, bool bMakeVisible);
  352. virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool bMakeVisible = TRUE);
  353. virtual Confidence MatchDocType(const char* lpszPathName, CCryEditDoc*& rpDocMatch);
  354. private:
  355. const QMetaObject* m_documentClass = nullptr;
  356. };
  357. class CDocTemplate;
  358. class CCryDocManager
  359. {
  360. CCrySingleDocTemplate* m_pDefTemplate = nullptr;
  361. public:
  362. CCryDocManager();
  363. virtual ~CCryDocManager() = default;
  364. CCrySingleDocTemplate* SetDefaultTemplate(CCrySingleDocTemplate* pNew);
  365. // Copied from MFC to get rid of the silly ugly unoverridable doc-type pick dialog
  366. virtual void OnFileNew();
  367. virtual bool DoPromptFileName(QString& fileName, UINT nIDSTitle,
  368. DWORD lFlags, bool bOpenFileDialog, CDocTemplate* pTemplate);
  369. virtual CCryEditDoc* OpenDocumentFile(const char* filename, bool addToMostRecentFileList, COpenSameLevelOptions openSameLevelOptions = COpenSameLevelOptions::NotReopenIfSame);
  370. QVector<CCrySingleDocTemplate*> m_templateList;
  371. };
  372. #include <AzCore/Component/Component.h>
  373. namespace AzToolsFramework
  374. {
  375. //! A component to reflect scriptable commands for the Editor
  376. class CryEditPythonHandler final
  377. : public AZ::Component
  378. {
  379. public:
  380. AZ_COMPONENT(CryEditPythonHandler, "{D4B19973-54D9-44BD-9E70-6069462A0CDC}")
  381. virtual ~CryEditPythonHandler() = default;
  382. SANDBOX_API static void Reflect(AZ::ReflectContext* context);
  383. // AZ::Component ...
  384. void Activate() override {}
  385. void Deactivate() override {}
  386. class CryEditHandler
  387. {
  388. public:
  389. AZ_RTTI(CryEditHandler, "{6C1FD05A-2F39-4094-80D4-CA526676F13E}")
  390. virtual ~CryEditHandler() = default;
  391. };
  392. class CryEditCheckoutHandler
  393. {
  394. public:
  395. AZ_RTTI(CryEditCheckoutHandler, "{C65EF439-6754-4ACD-AEA2-196F2DBA0AF3}")
  396. virtual ~CryEditCheckoutHandler() = default;
  397. };
  398. };
  399. } // namespace AzToolsFramework
  400. extern "C" AZ_DLL_EXPORT void InitializeDynamicModule();
  401. extern "C" AZ_DLL_EXPORT void UninitializeDynamicModule();
  402. #endif // CRYINCLUDE_EDITOR_CRYEDIT_H