CryEdit.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  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. {
  72. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  73. AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
  74. friend MainWindow;
  75. Q_OBJECT
  76. public:
  77. enum ECreateLevelResult
  78. {
  79. ECLR_OK = 0,
  80. ECLR_ALREADY_EXISTS,
  81. ECLR_DIR_CREATION_FAILED,
  82. ECLR_MAX_PATH_EXCEEDED
  83. };
  84. CCryEditApp();
  85. ~CCryEditApp();
  86. static CCryEditApp* instance();
  87. bool GetRootEnginePath(QDir& rootEnginePath) const;
  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& 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. void RegisterActionHandlers();
  141. // Implementation
  142. void OnCreateLevel();
  143. void OnOpenLevel();
  144. void OnCreateSlice();
  145. void OnOpenSlice();
  146. void OnAppAbout();
  147. void OnAppShowWelcomeScreen();
  148. void OnUpdateShowWelcomeScreen(QAction* action);
  149. void OnDocumentationTutorials();
  150. void OnDocumentationGlossary();
  151. void OnDocumentationO3DE();
  152. void OnDocumentationGamelift();
  153. void OnDocumentationReleaseNotes();
  154. void OnDocumentationGameDevBlog();
  155. void OnDocumentationForums();
  156. void OnDocumentationAWSSupport();
  157. void OnCommercePublish();
  158. void OnCommerceMerch();
  159. void OnEditHold();
  160. void OnEditFetch();
  161. void OnFileExportToGameNoSurfaceTexture();
  162. void OnViewSwitchToGame();
  163. void OnViewSwitchToGameFullScreen();
  164. void OnViewDeploy();
  165. void OnMoveObject();
  166. void OnRenameObj();
  167. void OnUndo();
  168. void OnOpenAssetImporter();
  169. void OnUpdateSelected(QAction* action);
  170. void OnEditLevelData();
  171. void OnFileEditLogFile();
  172. void OnFileResaveSlices();
  173. void OnFileEditEditorini();
  174. void OnPreferences();
  175. void OnOpenProjectManagerSettings();
  176. void OnOpenProjectManagerNew();
  177. void OnOpenProjectManager();
  178. void OnRedo();
  179. void OnUpdateRedo(QAction* action);
  180. void OnUpdateUndo(QAction* action);
  181. void OnSwitchPhysics();
  182. void OnSwitchPhysicsUpdate(QAction* action);
  183. void OnSyncPlayer();
  184. void OnSyncPlayerUpdate(QAction* action);
  185. void OnResourcesReduceworkingset();
  186. void OnDummyCommand() {};
  187. void OnFileSave();
  188. void OnUpdateDocumentReady(QAction* action);
  189. void OnUpdateFileOpen(QAction* action);
  190. void OnUpdateNonGameMode(QAction* action);
  191. void OnUpdateNewLevel(QAction* action);
  192. void OnUpdatePlayGame(QAction* action);
  193. void OnToolsLogMemoryUsage();
  194. void OnToolsPreferences();
  195. protected:
  196. // ------- AzFramework::AssetSystemInfoBus::Handler ------
  197. void OnError(AzFramework::AssetSystem::AssetSystemErrors error) 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. static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
  288. // Optional Uri to start an external lua debugger. If not specified,
  289. // then the Editor will open LuaIDE.exe.
  290. // For example, if using The Visual Studio Debugger Extension provided by lumbermixalot
  291. // The value will be: "vscode://lumbermixalot.o3de-lua-debug/debug?"
  292. // The following parameters will be added to the URI at runtime:
  293. // "projectPath". Absolute path of the game projec root.
  294. // "enginePath". Absolute path of the engine root. if not specified, it will be assume to be one directory above the game project root.
  295. // "files[]". A list of files,
  296. // Full example using the Uri shown below:
  297. // "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"
  298. // or
  299. // "vscode://lumbermixalot.o3de-lua-debug/debug?projectPath=D:\GIT\o3de\AutomatedTesting&files[]=D:\GIT\o3de\AutomatedTesting\Assets\Scripts\something.lua"
  300. static constexpr AZStd::string_view LuaDebuggerUriRegistryKey = "/O3DE/Lua/Debugger/Uri";
  301. struct PythonOutputHandler;
  302. AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
  303. AZStd::shared_ptr<PythonOutputHandler> m_pythonOutputHandler;
  304. AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
  305. friend struct PythonTestOutputHandler;
  306. void OpenProjectManager(const AZStd::string& screen);
  307. void OnUpdateWireframe(QAction* action);
  308. void OnViewConfigureLayout();
  309. void OnCustomizeKeyboard();
  310. void OnToolsConfiguretools();
  311. void OnToolsScriptHelp();
  312. void OnViewCycle2dviewport();
  313. void OnDisplayGotoPosition();
  314. void OnFileSavelevelresources();
  315. void OnClearRegistryData();
  316. void OnSwitchToDefaultCamera();
  317. void OnUpdateSwitchToDefaultCamera(QAction* action);
  318. void OnSwitchToSequenceCamera();
  319. void OnUpdateSwitchToSequenceCamera(QAction* action);
  320. void OnSwitchToSelectedcamera();
  321. void OnUpdateSwitchToSelectedCamera(QAction* action);
  322. void OnSwitchcameraNext();
  323. void OnOpenProceduralMaterialEditor();
  324. void OnOpenAssetBrowserView();
  325. void OnOpenTrackView();
  326. void OnOpenAudioControlsEditor();
  327. void OnOpenUICanvasEditor();
  328. // @param files: A list of file paths, separated by '|';
  329. void OpenExternalLuaDebugger(AZStd::string_view luaDebuggerUri, AZStd::string_view enginePath, AZStd::string_view projectPath, const char * files);
  330. public:
  331. void ExportLevel(bool bExportToGame, bool bExportTexture, bool bAutoExport);
  332. static bool Command_ExportToEngine();
  333. };
  334. //////////////////////////////////////////////////////////////////////////
  335. class CCrySingleDocTemplate
  336. : public QObject
  337. {
  338. Q_OBJECT
  339. private:
  340. explicit CCrySingleDocTemplate(const QMetaObject* pDocClass)
  341. : QObject()
  342. , m_documentClass(pDocClass)
  343. {
  344. }
  345. public:
  346. enum Confidence
  347. {
  348. noAttempt,
  349. maybeAttemptForeign,
  350. maybeAttemptNative,
  351. yesAttemptForeign,
  352. yesAttemptNative,
  353. yesAlreadyOpen
  354. };
  355. template<typename DOCUMENT>
  356. static CCrySingleDocTemplate* create()
  357. {
  358. return new CCrySingleDocTemplate(&DOCUMENT::staticMetaObject);
  359. }
  360. ~CCrySingleDocTemplate() {};
  361. // avoid creating another CMainFrame
  362. // close other type docs before opening any things
  363. virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool addToMostRecentFileList, bool bMakeVisible);
  364. virtual CCryEditDoc* OpenDocumentFile(const char* lpszPathName, bool bMakeVisible = TRUE);
  365. virtual Confidence MatchDocType(const char* lpszPathName, CCryEditDoc*& rpDocMatch);
  366. private:
  367. const QMetaObject* m_documentClass = nullptr;
  368. };
  369. class CDocTemplate;
  370. class CCryDocManager
  371. {
  372. CCrySingleDocTemplate* m_pDefTemplate = nullptr;
  373. public:
  374. CCryDocManager();
  375. virtual ~CCryDocManager() = default;
  376. CCrySingleDocTemplate* SetDefaultTemplate(CCrySingleDocTemplate* pNew);
  377. // Copied from MFC to get rid of the silly ugly unoverridable doc-type pick dialog
  378. virtual void OnFileNew();
  379. virtual bool DoPromptFileName(QString& fileName, UINT nIDSTitle,
  380. DWORD lFlags, bool bOpenFileDialog, CDocTemplate* pTemplate);
  381. virtual CCryEditDoc* OpenDocumentFile(const char* filename, bool addToMostRecentFileList, COpenSameLevelOptions openSameLevelOptions = COpenSameLevelOptions::NotReopenIfSame);
  382. QVector<CCrySingleDocTemplate*> m_templateList;
  383. };
  384. #include <AzCore/Component/Component.h>
  385. namespace AzToolsFramework
  386. {
  387. //! A component to reflect scriptable commands for the Editor
  388. class CryEditPythonHandler final
  389. : public AZ::Component
  390. {
  391. public:
  392. AZ_COMPONENT(CryEditPythonHandler, "{D4B19973-54D9-44BD-9E70-6069462A0CDC}")
  393. virtual ~CryEditPythonHandler() = default;
  394. SANDBOX_API static void Reflect(AZ::ReflectContext* context);
  395. // AZ::Component ...
  396. void Activate() override {}
  397. void Deactivate() override {}
  398. class CryEditHandler
  399. {
  400. public:
  401. AZ_RTTI(CryEditHandler, "{6C1FD05A-2F39-4094-80D4-CA526676F13E}")
  402. virtual ~CryEditHandler() = default;
  403. };
  404. class CryEditCheckoutHandler
  405. {
  406. public:
  407. AZ_RTTI(CryEditCheckoutHandler, "{C65EF439-6754-4ACD-AEA2-196F2DBA0AF3}")
  408. virtual ~CryEditCheckoutHandler() = default;
  409. };
  410. };
  411. } // namespace AzToolsFramework
  412. extern "C" AZ_DLL_EXPORT void InitializeDynamicModule();
  413. extern "C" AZ_DLL_EXPORT void UninitializeDynamicModule();
  414. #endif // CRYINCLUDE_EDITOR_CRYEDIT_H