CryEdit.h 18 KB

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