1 /**
2 Copyright: Copyright (c) 2015-2017 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module voxelman.gui.plugin;
8 
9 import voxelman.log;
10 import std..string : format;
11 import voxelman.math;
12 import derelict.imgui.imgui;
13 
14 import anchovy.glfwwindow;
15 import anchovy.input;
16 import anchovy.irenderer;
17 import anchovy.iwindow;
18 import anchovy.oglrenderer;
19 
20 import pluginlib;
21 import voxelman.imgui_glfw;
22 
23 import voxelman.core.config;
24 import voxelman.core.events;
25 import voxelman.world.storage;
26 
27 import voxelman.eventdispatcher.plugin;
28 import voxelman.config.configmanager;
29 
30 
31 struct ClosePressedEvent {}
32 
33 
34 final class GuiPlugin : IPlugin
35 {
36 private:
37 	EventDispatcherPlugin evDispatcher;
38 	ConfigOption resolution;
39 
40 public:
41 	IWindow window;
42 	IRenderer renderer;
43 	ImguiState igState;
44 	bool mouseLocked;
45 
46 	mixin IdAndSemverFrom!"voxelman.gui.plugininfo";
47 
48 	override void registerResources(IResourceManagerRegistry resmanRegistry)
49 	{
50 		auto config = resmanRegistry.getResourceManager!ConfigManager;
51 		resolution = config.registerOption!(int[])("resolution", [1280, 720]);
52 	}
53 
54 	override void preInit()
55 	{
56 		initLibs();
57 
58 		window = new GlfwWindow();
59 		window.init(ivec2(resolution.get!(int[])), "Voxelman client");
60 		renderer = new OglRenderer(window);
61 		igState.init((cast(GlfwWindow)window).handle);
62 
63 		// Bind events
64 		window.windowResized.connect(&windowResized);
65 		window.closePressed.connect(&closePressed);
66 
67 		window.keyPressed.connect(&igState.onKeyPressed);
68 		window.keyReleased.connect(&igState.onKeyReleased);
69 		window.charEntered.connect(&igState.charCallback);
70 		window.mousePressed.connect(&igState.onMousePressed);
71 		window.mouseReleased.connect(&igState.onMouseReleased);
72 		window.wheelScrolled.connect((dvec2 s) => igState.scrollCallback(s.y));
73 	}
74 
75 	void initLibs()
76 	{
77 		import derelict.glfw3.glfw3;
78 		import derelict.opengl3.gl3;
79 		import derelict.imgui.imgui;
80 		import voxelman.utils.libloader;
81 
82 		DerelictGL3.load();
83 		loadLib(DerelictGLFW3, BUILD_TO_ROOT_PATH, "glfw3");
84 		loadLib(DerelictImgui, BUILD_TO_ROOT_PATH, "cimgui");
85 	}
86 
87 	override void init(IPluginManager pluginman)
88 	{
89 		evDispatcher = pluginman.getPlugin!EventDispatcherPlugin;
90 		evDispatcher.subscribeToEvent(&onPreUpdateEvent);
91 		evDispatcher.subscribeToEvent(&onRender3Event);
92 		evDispatcher.subscribeToEvent(&onGameStopEvent);
93 	}
94 
95 	void onPreUpdateEvent(ref PreUpdateEvent event)
96 	{
97 		window.processEvents();
98 		igState.newFrame();
99 	}
100 
101 	void onRender3Event(ref Render3Event event)
102 	{
103 		igState.render();
104 	}
105 
106 	void onGameStopEvent(ref GameStopEvent stopEvent)
107 	{
108 		window.releaseWindow;
109 		igState.shutdown();
110 	}
111 
112 	private void windowResized(ivec2 newSize)
113 	{
114 		evDispatcher.postEvent(WindowResizedEvent(newSize));
115 	}
116 
117 	private void closePressed()
118 	{
119 		evDispatcher.postEvent(ClosePressedEvent());
120 	}
121 
122 	void toggleMouseLock()
123 	{
124 		mouseLocked = !mouseLocked;
125 		if (mouseLocked)
126 		{
127 			window.mousePosition = cast(ivec2)(window.size) / 2;
128 		}
129 		window.setMouseLock(mouseLocked);
130 	}
131 }