1 /**
2 Copyright: Copyright (c) 2015-2018 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 module voxelman.input.keybindingmanager;
7 
8 import voxelman.log;
9 
10 import pluginlib;
11 import voxelman.config.configmanager;
12 import voxelman.platform.keynamemap;
13 public import voxelman.platform.input : KeyCode, PointerButton;
14 
15 enum FireBeforeInput : bool { no = false, yes = true }
16 struct KeyBinding
17 {
18 	uint keyCode;
19 	string keyName;
20 	KeyHandler pressHandler;
21 	KeyHandler releaseHandler;
22 	FireBeforeInput fireBeforeInput = FireBeforeInput.no;
23 }
24 
25 alias KeyHandler = void delegate(string key);
26 
27 final class KeyBindingManager : IResourceManager
28 {
29 	KeyBinding*[uint] keyBindingsByCode;
30 	KeyBinding*[string] keyBindingsByName;
31 	private ConfigOption[string] options;
32 	private ConfigManager config;
33 
34 	override string id() @property { return "voxelman.managers.keybindingmanager"; }
35 
36 	override void init(IResourceManagerRegistry resmanRegistry)
37 	{
38 		config = resmanRegistry.getResourceManager!ConfigManager;
39 	}
40 
41 	// Load all keybindings from config
42 	override void postInit()
43 	{
44 		foreach(pair; options.byKeyValue)
45 		{
46 			string optionName = pair.key;
47 			ConfigOption option = pair.value;
48 			if (optionName !in keyBindingsByName) continue;
49 
50 			KeyBinding* binding = keyBindingsByName[optionName];
51 			string key = option.get!string;
52 			if (key !in stringToKeyMap) continue;
53 
54 			uint configKeyCode = stringToKeyMap[key];
55 			if (binding.keyCode != configKeyCode)
56 			{
57 				keyBindingsByCode.remove(binding.keyCode);
58 				keyBindingsByCode[configKeyCode] = binding;
59 				binding.keyCode = configKeyCode;
60 			}
61 		}
62 	}
63 
64 	// Called during IPlugin.registerResources calls.
65 	void registerKeyBinding(KeyBinding* binding)
66 	{
67 		assert(binding);
68 		auto option = config.registerOption!string(binding.keyName, keyToStringMap[binding.keyCode]);
69 		options[binding.keyName] = option;
70 		keyBindingsByCode[binding.keyCode] = binding;
71 		keyBindingsByName[binding.keyName] = binding;
72 	}
73 }