While implementing the UI functionality of Azura, I faced a little problem in segregating code for Different HUDs like Settings related UI Elements should be in a Settings related class and same goes for Main Menu Elements, Levels UI Elements etc.

But it was not possible with the Current strucutre. So I moved things around.

I coded an abstract class called Scene.

ref class Scene abstract
{
internal:
	Scene(
	  ID2D1Factory3* d2dFactory,
	  IDWriteFactory3* dwriteFactory,
	  ID2D1DeviceContext2* d2dContext,
	  CoreWindow^ window
	);

	// Override Functions (Hooks)
	virtual void Init() = 0;
	virtual void Update() = 0;
	virtual void OnSceneEnter() = 0;
	virtual void OnSceneExit() = 0;
	
	// Internal Common Functions
	UIHUD^ CreateHUD(std::wstring id);
	
	// Direct 3D Render and Update Phase
	void UpdatePhase();
	void RenderPhase(D2D1::Matrix3x2F orientationMatrix);
	std::map<std::wstring, UIHUD^> GetHUDMap() {
	  return m_hudMap; 
	}
	
	// Other Utilities
	CoreWindow^ GetWindow() { return m_window; }
	UIHUD^ GetHUD(std::wstring id);

private:
	CoreWindow^ m_window;

	std::map<std::wstring, UIHUD^> m_hudMap;
	Microsoft::WRL::ComPtr<ID2D1Factory3> m_d2dFactory;
	Microsoft::WRL::ComPtr<IDWriteFactory3> m_dwriteFactory;
	Microsoft::WRL::ComPtr<ID2D1DeviceContext2> m_d2dContext;

};

What’s so awesome is that I am now able to create Scenes seamlessly. Also, Each scene has now a collection of HUDs (earlier there was a UIManager, which has now been deprecated).

So who does the gluing of all the Scenes ? Answer: The SceneDirector.

ref class SceneDirector sealed
{
internal:
	SceneDirector();
	void AddScene(std::wstring id, Scene^ scene);
	void ChangeScene(std::wstring id);
	Scene^ GetScene(std::wstring id);
	void DeleteScene(std::wstring id);
	void Update();
	void Render(D2D1::Matrix3x2F oritentationMatrix);
	void Clear();

private:
	Scene^ m_currentScene;
	std::map<std::wstring, Scene^> m_sceneMap;
};

The director stores the Scenes beautifully in std::map<std::wstring, Scene^> m_sceneMap. This enables me to define Scenes as:

ref class MainMenuScene sealed : public Scene
{
internal:
	MainMenuScene(
	  ID2D1Factory3* d2dFactory,
	  IDWriteFactory3* dwriteFactory,
	  ID2D1DeviceContext2* d2dContext,
	  CoreWindow^ window
	  );

	void Init() override;
	void Update() override;
	void OnSceneEnter() override;
	void OnSceneExit() override;
};

Here I created a custom MainMenuScene which stores all the UI Elements only specific to the Main Menu. This way I can create multiple Scenes and store them in individual files and reusing a lot of code. Also I didn’t use the interface attribute for the Scene class because I wanted to create some common functions like createHUD() which is not possible when making an Interface like IScene as all the methods have to be pure virutal there.