1 /**
2 Copyright: Copyright (c) 2016-2017 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 module voxelman.block.plugin;
7 
8 import voxelman.log;
9 import std.array : array;
10 import cbor;
11 import pluginlib;
12 import voxelman.core.config : BlockId;
13 import voxelman.world.storage;
14 import voxelman.world.block;
15 import voxelman.utils.mapping;
16 
17 import voxelman.world.serverworld;
18 import voxelman.world.clientworld;
19 
20 final class BlockManager : IResourceManager
21 {
22 private:
23 	Mapping!BlockInfo blockMapping;
24 
25 public:
26 	override string id() @property { return "voxelman.block.blockmanager"; }
27 	override void preInit()
28 	{
29 		regBaseBlocks(&regBlock);
30 		sideTable = sideIntersectionTable(NUM_SIDE_MASKS);
31 		setSideTable(sideTable);
32 	}
33 
34 	BlockInfoSetter regBlock(string name) {
35 		size_t id = blockMapping.put(BlockInfo(name));
36 		assert(id <= BlockId.max);
37 		return BlockInfoSetter(&blockMapping, id);
38 	}
39 
40 	BlockInfoTable getBlocks() {
41 		return BlockInfoTable(cast(immutable)blockMapping.infoArray, sideTable);
42 	}
43 
44 	// returns size_t.max if not found
45 	size_t getId(string name) {
46 		return blockMapping.id(name);
47 	}
48 
49 	SideIntersectionTable sideTable;
50 }
51 
52 mixin template BlockPluginCommonImpl()
53 {
54 	private BlockManager bm;
55 	auto dbKey = IoKey("voxelman.block.block_mapping");
56 
57 	override void registerResourceManagers(void delegate(IResourceManager) registerHandler)
58 	{
59 		registerHandler(bm = new BlockManager);
60 	}
61 
62 	BlockInfoTable getBlocks()
63 	{
64 		return bm.getBlocks;
65 	}
66 }
67 
68 final class BlockPluginClient : IPlugin
69 {
70 	mixin BlockPluginCommonImpl;
71 	// IPlugin stuff
72 	mixin IdAndSemverFrom!"voxelman.block.plugininfo";
73 
74 	override void init(IPluginManager pluginman)
75 	{
76 		auto clientWorld = pluginman.getPlugin!ClientWorld;
77 		clientWorld.idMapManager.regIdMapHandler(dbKey.str, &handleBlockMap);
78 	}
79 
80 	void handleBlockMap(string[] blocks)
81 	{
82 		bm.blockMapping.setMapping(blocks);
83 	}
84 }
85 
86 final class BlockPluginServer : IPlugin
87 {
88 	mixin BlockPluginCommonImpl;
89 	// IPlugin stuff
90 	mixin IdAndSemverFrom!"voxelman.block.plugininfo";
91 
92 	override void registerResources(IResourceManagerRegistry resmanRegistry)
93 	{
94 		auto ioman = resmanRegistry.getResourceManager!IoManager;
95 		ioman.registerWorldLoadSaveHandlers(&readBlockMap, &writeBlockMap);
96 	}
97 
98 	override void init(IPluginManager pluginman)
99 	{
100 		auto serverWorld = pluginman.getPlugin!ServerWorld;
101 		serverWorld.idMapManager.regIdMap(dbKey.str, bm.blockMapping.nameRange.array);
102 	}
103 
104 	void readBlockMap(ref PluginDataLoader loader)
105 	{
106 		loader.readMapping(dbKey, bm.blockMapping);
107 	}
108 
109 	void writeBlockMap(ref PluginDataSaver saver)
110 	{
111 		saver.writeMapping(dbKey, bm.blockMapping);
112 	}
113 }