You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/CryEdit.h

527 lines
18 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#ifndef CRYINCLUDE_EDITOR_CRYEDIT_H
#define CRYINCLUDE_EDITOR_CRYEDIT_H
#pragma once
#if !defined(Q_MOC_RUN)
#include <AzCore/Outcome/Outcome.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include "WipFeatureManager.h"
#include "CryEditDoc.h"
#include "ViewPane.h"
#include <QSettings>
#endif
class CCryDocManager;
class CQuickAccessBar;
class CCryEditDoc;
class CEditCommandLineInfo;
class CMainFrame;
class CConsoleDialog;
struct mg_connection;
struct mg_request_info;
struct mg_context;
struct IEventLoopHook;
class QAction;
class MainWindow;
class QSharedMemory;
class SANDBOX_API RecentFileList
{
public:
RecentFileList();
void Remove(int index);
void Add(const QString& filename);
int GetSize();
void GetDisplayName(QString& name, int index, const QString& curDir);
QString& operator[](int index);
void ReadList();
void WriteList();
static const int Max = 12;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
QStringList m_arrNames;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
QSettings m_settings;
};
#define PROJECT_CONFIGURATOR_GEM_PAGE "Gems Settings"
/**
* Bus for controlling the application's idle processing (may include things like entity updates, ticks, viewport rendering, etc.).
* This is sometimes necessary in special event-processing loops to prevent long (or infinite) processing time because Idle Processing
* can perpetually generate more events.
*/
class EditorIdleProcessing : public AZ::EBusTraits
{
public:
using Bus = AZ::EBus<EditorIdleProcessing>;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
/// Disable the Editor's idle processing. EnableIdleProcessing() must be called exactly once when special processing is complete.
virtual void DisableIdleProcessing() {}
/// Re-enables Idle Processing. Must be called exactly one time for every call to DisableIdleProcessing().
virtual void EnableIdleProcessing() {}
};
using EditorIdleProcessingBus = AZ::EBus<EditorIdleProcessing>;
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
class SANDBOX_API CCryEditApp
: public QObject
, protected AzFramework::AssetSystemInfoBus::Handler
, protected EditorIdleProcessingBus::Handler
{
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
friend MainWindow;
Q_OBJECT
public:
enum ECreateLevelResult
{
ECLR_OK = 0,
ECLR_ALREADY_EXISTS,
ECLR_DIR_CREATION_FAILED,
ECLR_MAX_PATH_EXCEEDED
};
CCryEditApp();
~CCryEditApp();
static CCryEditApp* instance();
bool GetRootEnginePath(QDir& rootEnginePath) const;
bool CreateLevel(bool& wasCreateLevelOperationCancelled);
void LoadFile(QString fileName);
void ForceNextIdleProcessing() { m_bForceProcessIdle = true; }
void KeepEditorActive(bool bActive) { m_bKeepEditorActive = bActive; };
bool IsInTestMode() const { return m_bTestMode; };
bool IsInPreviewMode() const { return m_bPreviewMode; };
bool IsInExportMode() const { return m_bExportMode; };
bool IsExportingLegacyData() const { return m_bIsExportingLegacyData; }
bool IsInConsoleMode() const { return m_bConsoleMode; };
bool IsInAutotestMode() const { return m_bAutotestMode; };
bool IsInLevelLoadTestMode() const { return m_bLevelLoadTestMode; }
bool IsInRegularEditorMode();
bool IsExiting() const { return m_bExiting; }
void EnableAccelerator(bool bEnable);
void SaveAutoBackup();
void SaveAutoRemind();
void ExportToGame(bool bNoMsgBox = true);
//! \param sTitleStr overwrites the default title of the Editor
void SetEditorWindowTitle(QString sTitleStr = QString(), QString sPreTitleStr = QString(), QString sPostTitleStr = QString());
RecentFileList* GetRecentFileList();
virtual void AddToRecentFileList(const QString& lpszPathName);
ECreateLevelResult CreateLevel(const QString& levelName, QString& fullyQualifiedLevelName);
static void InitDirectory();
BOOL FirstInstance(bool bForceNewInstance = false);
void InitFromCommandLine(CEditCommandLineInfo& cmdInfo);
BOOL CheckIfAlreadyRunning();
//! @return successful outcome if initialization succeeded. or failed outcome with error message.
AZ::Outcome<void, AZStd::string> InitGameSystem(HWND hwndForInputSystem);
void CreateSplashScreen();
void InitPlugins();
bool InitGame();
BOOL InitConsole();
int IdleProcessing(bool bBackground);
bool IsWindowInForeground();
void RunInitPythonScript(CEditCommandLineInfo& cmdInfo);
void RegisterEventLoopHook(IEventLoopHook* pHook);
void UnregisterEventLoopHook(IEventLoopHook* pHook);
void DisableIdleProcessing() override;
void EnableIdleProcessing() override;
// Print to stdout even if there out has been redirected
void PrintAlways(const AZStd::string& output);
//! Launches a detached process
//! \param process The path to the process to start
//! \param args Space separated list of arguments to pass to the process on start.
void StartProcessDetached(const char* process, const char* args);
//! Launches the Lua Editor/Debugger
//! \param files A space separated list of aliased paths
void OpenLUAEditor(const char* files);
QString GetRootEnginePath() const;
void RedirectStdoutToNull();
// Overrides
// ClassWizard generated virtual function overrides
public:
virtual BOOL InitInstance();
virtual int ExitInstance(int exitCode = 0);
virtual BOOL OnIdle(LONG lCount);
virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszFileName);
CCryDocManager* GetDocManager() { return m_pDocManager; }
void RegisterActionHandlers();
// Implementation
void OnCreateLevel();
void OnOpenLevel();
void OnCreateSlice();
void OnOpenSlice();
void OnAppAbout();
void OnAppShowWelcomeScreen();
void OnUpdateShowWelcomeScreen(QAction* action);
void OnDocumentationTutorials();
void OnDocumentationGlossary();
void OnDocumentationO3DE();
void OnDocumentationGamelift();
void OnDocumentationReleaseNotes();
void OnDocumentationGameDevBlog();
void OnDocumentationForums();
void OnDocumentationAWSSupport();
void OnCommercePublish();
void OnCommerceMerch();
void SaveTagLocations();
void OnExportSelectedObjects();
void OnEditHold();
void OnEditFetch();
void OnFileExportToGameNoSurfaceTexture();
void OnViewSwitchToGame();
void OnViewDeploy();
void DeleteSelectedEntities(bool includeDescendants);
void OnMoveObject();
void OnRenameObj();
void OnEditmodeMove();
void OnEditmodeRotate();
void OnEditmodeScale();
void OnUpdateEditmodeMove(QAction* action);
void OnUpdateEditmodeRotate(QAction* action);
void OnUpdateEditmodeScale(QAction* action);
void OnUndo();
void OnOpenAssetImporter();
void OnUpdateSelected(QAction* action);
void OnEditLevelData();
void OnFileEditLogFile();
void OnFileResaveSlices();
void OnFileEditEditorini();
void OnPreferences();
void OnOpenProjectManagerSettings();
void OnOpenProjectManagerNew();
void OnOpenProjectManager();
void OnRedo();
void OnUpdateRedo(QAction* action);
void OnUpdateUndo(QAction* action);
void OnSwitchPhysics();
void OnSwitchPhysicsUpdate(QAction* action);
void OnSyncPlayer();
void OnSyncPlayerUpdate(QAction* action);
void OnResourcesReduceworkingset();
void OnDummyCommand() {};
void OnShowHelpers();
void OnFileSave();
void OnUpdateDocumentReady(QAction* action);
void OnUpdateFileOpen(QAction* action);
void OnUpdateNonGameMode(QAction* action);
void OnUpdateNewLevel(QAction* action);
void OnUpdatePlayGame(QAction* action);
protected:
// ------- AzFramework::AssetSystemInfoBus::Handler ------
void OnError(AzFramework::AssetSystem::AssetSystemErrors error) override;
// -------------------------------------------
private:
void InitLevel(const CEditCommandLineInfo& cmdInfo);
bool ConnectToAssetProcessor() const;
void CompileCriticalAssets() const;
CMainFrame* GetMainFrame() const;
void WriteConfig();
void TagLocation(int index);
void GotoTagLocation(int index);
void LoadTagLocations();
bool UserExportToGame(bool bNoMsgBox = true);
static void ShowSplashScreen(CCryEditApp* app);
static void CloseSplashScreen();
static void OutputStartupMessage(QString str);
bool ShowEnableDisableGemDialog(const QString& title, const QString& message);
QString ShowWelcomeDialog();
bool FixDanglingSharedMemory(const QString& sharedMemName) const;
//! Displays level load errors after a certain number of idle frames have been processed.
//! Due to the asyncrhonous nature of loading assets any errors that are reported by components
//! can happen after the level is loaded. This method will wait for a few idle updates and then
//! display the load errors to ensure all errors are displayed properly.
void DisplayLevelLoadErrors();
class CEditorImpl* m_pEditor = nullptr;
static CCryEditApp* s_currentInstance;
//! True if editor is in test mode.
//! Test mode is a special mode enabled when Editor ran with /test command line.
//! In this mode editor starts up, but exit immediately after all initialization.
bool m_bTestMode = false;
//! In this mode editor will load specified cry file, export t, and then close.
bool m_bExportMode = false;
QString m_exportFile;
//! This flag is set to true every time any of the "Export" commands is being executed.
//! Once exporting is finished the flag is set back to false.
//! UI events like "New Level" or "Open Level", should not be allowed while m_bIsExportingLegacyData==true.
//! Otherwise it could trigger crashes trying to export while exporting.
bool m_bIsExportingLegacyData = false;
//! If application exiting.
bool m_bExiting = false;
//! True if editor is in preview mode.
//! In this mode only very limited functionality is available and only for fast preview of models.
bool m_bPreviewMode = false;
// Only console window is created.
bool m_bConsoleMode = false;
// Skip showing the WelcomeScreenDialog
bool m_bSkipWelcomeScreenDialog = false;
// Level load test mode
bool m_bLevelLoadTestMode = false;
//! Current file in preview mode.
char m_sPreviewFile[_MAX_PATH];
//! True if "/runpythontest" was passed as a flag.
bool m_bRunPythonTestScript = false;
//! True if "/runpython" was passed as a flag.
bool m_bRunPythonScript = false;
//! File to run on startup
QString m_execFile;
//! Command to run on startup
QString m_execLineCmd;
//! Autotest mode: Special mode meant for automated testing, things like blocking dialogs or error report windows won't appear
bool m_bAutotestMode = false;
CConsoleDialog* m_pConsoleDialog = nullptr;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
Vec3 m_tagLocations[12];
Ang3 m_tagAngles[12];
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
float m_fastRotateAngle = 45.0f;
float m_moveSpeedStep = 0.1f;
ULONG_PTR m_gdiplusToken;
QSharedMemory* m_mutexApplication = nullptr;
//! was the editor active in the previous frame ... needed to detect if the game lost focus and
//! dispatch proper SystemEvent (needed to release input keys)
bool m_bPrevActive = false;
// If this flag is set, the next OnIdle() will update, even if the app is in the background, and then
// this flag will be reset.
bool m_bForceProcessIdle = false;
// This is set while IdleProcessing is running to prevent re-entrancy
bool m_idleProcessingRunning = false;
// Keep the editor alive, even if no focus is set
bool m_bKeepEditorActive = false;
// Currently creating a new level
bool m_creatingNewLevel = false;
bool m_openingLevel = false;
bool m_savingLevel = false;
// Flag indicating if the errors for the currently loaded level have been displayed
bool m_levelErrorsHaveBeenDisplayed = false;
// Number of idle frames that have passed before displaying level errors
int m_numBeforeDisplayErrorFrames = 0;
QString m_lastOpenLevelPath;
CQuickAccessBar* m_pQuickAccessBar = nullptr;
IEventLoopHook* m_pEventLoopHook = nullptr;
QString m_rootEnginePath;
int m_disableIdleProcessingCounter = 0; //!< Counts requests to disable idle processing. When non-zero, idle processing will be disabled.
CCryDocManager* m_pDocManager = nullptr;
// Disable warning for dll export since this member won't be used outside this class
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZ::IO::FileDescriptorRedirector m_stdoutRedirection = AZ::IO::FileDescriptorRedirector(1); // < 1 for STDOUT
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
private:
static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
struct PythonOutputHandler;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZStd::shared_ptr<PythonOutputHandler> m_pythonOutputHandler;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
friend struct PythonTestOutputHandler;
void OpenProjectManager(const AZStd::string& screen);
void OnWireframe();
void OnUpdateWireframe(QAction* action);
void OnViewConfigureLayout();
// Tag Locations.
void OnTagLocation1();
void OnTagLocation2();
void OnTagLocation3();
void OnTagLocation4();
void OnTagLocation5();
void OnTagLocation6();
void OnTagLocation7();
void OnTagLocation8();
void OnTagLocation9();
void OnTagLocation10();
void OnTagLocation11();
void OnTagLocation12();
void OnGotoLocation1();
void OnGotoLocation2();
void OnGotoLocation3();
void OnGotoLocation4();
void OnGotoLocation5();
void OnGotoLocation6();
void OnGotoLocation7();
void OnGotoLocation8();
void OnGotoLocation9();
void OnGotoLocation10();
void OnGotoLocation11();
void OnGotoLocation12();
void OnToolsLogMemoryUsage();
void OnCustomizeKeyboard();
void OnToolsConfiguretools();
void OnToolsScriptHelp();
void OnViewCycle2dviewport();
void OnDisplayGotoPosition();
void OnChangemovespeedIncrease();
void OnChangemovespeedDecrease();
void OnChangemovespeedChangestep();
void OnFileSavelevelresources();
void OnClearRegistryData();
void OnValidatelevel();
void OnToolsPreferences();
void OnGraphicsSettings();
void OnSwitchToDefaultCamera();
void OnUpdateSwitchToDefaultCamera(QAction* action);
void OnSwitchToSequenceCamera();
void OnUpdateSwitchToSequenceCamera(QAction* action);
void OnSwitchToSelectedcamera();
void OnUpdateSwitchToSelectedCamera(QAction* action);
void OnSwitchcameraNext();
void OnOpenProceduralMaterialEditor();
void OnOpenAssetBrowserView();
void OnOpenTrackView();
void OnOpenAudioControlsEditor();
void OnOpenUICanvasEditor();
void OnChangeGameSpec(UINT nID);
void SetGameSpecCheck(ESystemConfigSpec spec, ESystemConfigPlatform platform, int &nCheck, bool &enable);
void OnUpdateGameSpec(QAction* action);
void OnOpenQuickAccessBar();
public:
void ExportLevel(bool bExportToGame, bool bExportTexture, bool bAutoExport);
static bool Command_ExportToEngine();
void OnFileExportOcclusionMesh();
};
//////////////////////////////////////////////////////////////////////////
class CCrySingleDocTemplate
: public QObject
{
private:
explicit CCrySingleDocTemplate(const QMetaObject* pDocClass)
: QObject()
, m_documentClass(pDocClass)
{
}
public:
enum Confidence
{
noAttempt,
maybeAttemptForeign,
maybeAttemptNative,
yesAttemptForeign,
yesAttemptNative,
yesAlreadyOpen
};
template<typename DOCUMENT>
static CCrySingleDocTemplate* create()
{
return new CCrySingleDocTemplate(&DOCUMENT::staticMetaObject);
}
~CCrySingleDocTemplate() {};
// avoid creating another CMainFrame
// close other type docs before opening any things
virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszPathName, BOOL bAddToMRU, BOOL bMakeVisible);
virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszPathName, BOOL bMakeVisible = TRUE);
virtual Confidence MatchDocType(LPCTSTR lpszPathName, CCryEditDoc*& rpDocMatch);
private:
const QMetaObject* m_documentClass = nullptr;
};
class CDocTemplate;
class CCryDocManager
{
CCrySingleDocTemplate* m_pDefTemplate = nullptr;
public:
CCryDocManager();
CCrySingleDocTemplate* SetDefaultTemplate(CCrySingleDocTemplate* pNew);
// Copied from MFC to get rid of the silly ugly unoverridable doc-type pick dialog
virtual void OnFileNew();
virtual BOOL DoPromptFileName(QString& fileName, UINT nIDSTitle,
DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
virtual CCryEditDoc* OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToMRU);
QVector<CCrySingleDocTemplate*> m_templateList;
};
#include <AzCore/Component/Component.h>
namespace AzToolsFramework
{
//! A component to reflect scriptable commands for the Editor
class CryEditPythonHandler final
: public AZ::Component
{
public:
AZ_COMPONENT(CryEditPythonHandler, "{D4B19973-54D9-44BD-9E70-6069462A0CDC}")
virtual ~CryEditPythonHandler() = default;
SANDBOX_API static void Reflect(AZ::ReflectContext* context);
// AZ::Component ...
void Activate() override {}
void Deactivate() override {}
class CryEditHandler
{
public:
AZ_RTTI(CryEditHandler, "{6C1FD05A-2F39-4094-80D4-CA526676F13E}")
virtual ~CryEditHandler() = default;
};
class CryEditCheckoutHandler
{
public:
AZ_RTTI(CryEditCheckoutHandler, "{C65EF439-6754-4ACD-AEA2-196F2DBA0AF3}")
virtual ~CryEditCheckoutHandler() = default;
};
};
} // namespace AzToolsFramework
extern "C" AZ_DLL_EXPORT void InitializeDynamicModule(void* env);
extern "C" AZ_DLL_EXPORT void UninitializeDynamicModule();
#endif // CRYINCLUDE_EDITOR_CRYEDIT_H