Skip to content

Commit da4e2b6

Browse files
committed
Renamed Block to BlockHandler to resolve ambiguity with spaar.ModLoader.Block
1 parent dc2e65c commit da4e2b6

30 files changed

+397
-419
lines changed

AdvancedControlsMod/AdvancedControlsMod.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@
115115
<Compile Include="Axes\CustomAxis.cs" />
116116
<Compile Include="Axes\MouseAxis.cs" />
117117
<Compile Include="Axes\KeyAxis.cs" />
118-
<Compile Include="BlockHandlers.cs" />
118+
<Compile Include="BlockHandlerController.cs" />
119119
<Compile Include="Blocks\Automatron.cs" />
120-
<Compile Include="Blocks\Block.cs" />
120+
<Compile Include="Blocks\BlockHandler.cs" />
121121
<Compile Include="Blocks\Cannon.cs" />
122122
<Compile Include="Blocks\Cog.cs" />
123123
<Compile Include="Blocks\Decoupler.cs" />
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Lench.AdvancedControls.Blocks;
4+
5+
namespace Lench.AdvancedControls
6+
{
7+
/// <summary>
8+
/// Block Handlers API of the scripting mod.
9+
/// </summary>
10+
public class BlockHandlerController : SingleInstance<BlockHandlerController>
11+
{
12+
/// <summary>
13+
///
14+
/// </summary>
15+
public override string Name { get { return "Block Handlers Controller"; } }
16+
17+
/// <summary>
18+
/// Event invoked when simulation block handlers are initialised.
19+
/// Use this instead of OnSimulation if you're relying on block handlers.
20+
/// </summary>
21+
public static InitialisationDelegate OnInitialisation;
22+
23+
/// <summary>
24+
/// Returns True if block handlers are initialised.
25+
/// </summary>
26+
public static bool Initialised { get; private set; }
27+
28+
// Map: Building GUID -> Sequential ID
29+
internal static Dictionary<Guid, string> buildingBlocks;
30+
31+
// Map: BlockBehaviour -> Block handler
32+
internal static Dictionary<BlockBehaviour, BlockHandler> bbToBlockHandler;
33+
34+
// Map: GUID -> Block handler
35+
internal static Dictionary<Guid, BlockHandler> guidToBlockHandler;
36+
37+
// Map: ID -> Block handler
38+
internal static Dictionary<string, BlockHandler> idToBlockHandler;
39+
40+
// Map: BlockType -> BlockHandler type
41+
internal static Dictionary<int, Type> Types = new Dictionary<int, Type>
42+
{
43+
{(int)BlockType.Cannon, typeof(Cannon)},
44+
{(int)BlockType.ShrapnelCannon, typeof(Cannon)},
45+
{(int)BlockType.CogMediumPowered, typeof(Cog)},
46+
{(int)BlockType.Wheel, typeof(Cog)},
47+
{(int)BlockType.LargeWheel, typeof(Cog)},
48+
{(int)BlockType.Drill, typeof(Cog)},
49+
{(int)BlockType.Decoupler, typeof(Decoupler)},
50+
{(int)BlockType.Flamethrower, typeof(Flamethrower)},
51+
{(int)BlockType.FlyingBlock, typeof(FlyingSpiral)},
52+
{(int)BlockType.Grabber, typeof(Grabber)},
53+
{(int)BlockType.Grenade, typeof(Grenade)},
54+
{(int)BlockType.Piston, typeof(Piston)},
55+
{59, typeof(Rocket) },
56+
{(int)BlockType.Spring, typeof(Spring)},
57+
{(int)BlockType.RopeWinch, typeof(Spring)},
58+
{(int)BlockType.SteeringHinge, typeof(Steering)},
59+
{(int)BlockType.SteeringBlock, typeof(Steering)},
60+
{(int)BlockType.WaterCannon, typeof(WaterCannon)},
61+
{410, typeof(Automatron)},
62+
{790, typeof(VectorThruster) }
63+
};
64+
65+
/// <summary>
66+
/// Events invoked on updates.
67+
/// </summary>
68+
internal delegate void UpdateEventHandler();
69+
internal static event UpdateEventHandler OnUpdate;
70+
71+
internal delegate void LateUpdateEventHandler();
72+
internal static event LateUpdateEventHandler OnLateUpdate;
73+
74+
internal delegate void FixedUpdateEventHandler();
75+
internal static event FixedUpdateEventHandler OnFixedUpdate;
76+
77+
/// <summary>
78+
/// Event invoked when simulation block handlers are initialised.
79+
/// </summary>
80+
public delegate void InitialisationDelegate();
81+
82+
/// <summary>
83+
/// Calls Update method of all initialised Block handlers.
84+
/// </summary>
85+
private void Update()
86+
{
87+
OnUpdate?.Invoke();
88+
}
89+
90+
/// <summary>
91+
/// Calls LateUpdate method of all initialised Block handlers.
92+
/// </summary>
93+
private void LateUpdate()
94+
{
95+
OnLateUpdate?.Invoke();
96+
}
97+
98+
/// <summary>
99+
/// Calls FixedUpdate method of all initialised Block handlers.
100+
/// </summary>
101+
private void FixedUpdate()
102+
{
103+
OnFixedUpdate?.Invoke();
104+
}
105+
106+
/// <summary>
107+
/// Initializes and returns new Block handler object.
108+
/// Each block should only have one Block handler.
109+
/// </summary>
110+
/// <param name="bb">BlockBehaviour object.</param>
111+
/// <returns>LenchScripterMod.Block object.</returns>
112+
private static BlockHandler CreateBlock(BlockBehaviour bb)
113+
{
114+
BlockHandler block;
115+
if (Types.ContainsKey(bb.GetBlockID()))
116+
block = (BlockHandler)Activator.CreateInstance(Types[bb.GetBlockID()], new object[] { bb });
117+
else
118+
block = new BlockHandler(bb);
119+
bbToBlockHandler[bb] = block;
120+
return block;
121+
}
122+
123+
/// <summary>
124+
/// Return Block handler with given Guid.
125+
/// </summary>
126+
/// <param name="blockGuid">Block's GUID.</param>
127+
/// <returns>Returns reference to blocks Block handler object.</returns>
128+
public static BlockHandler GetBlock(Guid blockGuid)
129+
{
130+
if (!Initialised) throw new InvalidOperationException("Block handlers are not initialised.");
131+
if (guidToBlockHandler.ContainsKey(blockGuid))
132+
return guidToBlockHandler[blockGuid];
133+
throw new BlockNotFoundException("Block " + blockGuid + " not found.");
134+
}
135+
136+
/// <summary>
137+
/// Returns Block handler for a given BlockBehaviour.
138+
/// </summary>
139+
/// <param name="bb"></param>
140+
/// <returns></returns>
141+
public static BlockHandler GetBlock(BlockBehaviour bb)
142+
{
143+
if (!Initialised) throw new InvalidOperationException("Block handlers are not initialised.");
144+
if (bbToBlockHandler.ContainsKey(bb))
145+
return bbToBlockHandler[bb];
146+
throw new BlockNotFoundException("Given BlockBehaviour has no corresponding Block handler.");
147+
}
148+
149+
/// <summary>
150+
/// Finds blockId identifier in dictionary of simulation blocks.
151+
/// </summary>
152+
/// <param name="blockId">Block's sequential identifier.</param>
153+
/// <returns>Returns reference to blocks Block handler object.</returns>
154+
public static BlockHandler GetBlock(string blockId)
155+
{
156+
if (!Initialised) throw new InvalidOperationException("Block handlers are not initialised.");
157+
if (idToBlockHandler.ContainsKey(blockId.ToUpper()))
158+
return idToBlockHandler[blockId.ToUpper()];
159+
throw new BlockNotFoundException("Block " + blockId + " not found.");
160+
}
161+
162+
/// <summary>
163+
/// Returns sequential identifier of a block during building.
164+
/// </summary>
165+
/// <param name="block">Block object.</param>
166+
/// <returns></returns>
167+
public static string GetID(GenericBlock block)
168+
{
169+
if (buildingBlocks == null || !buildingBlocks.ContainsKey(block.Guid))
170+
InitializeBuildingBlockIDs();
171+
return buildingBlocks[block.Guid];
172+
}
173+
174+
/// <summary>
175+
/// Returns sequential identifier of a block with given guid during building.
176+
/// </summary>
177+
/// <param name="guid">Guid of the block.</param>
178+
/// <returns></returns>
179+
public static string GetID(Guid guid)
180+
{
181+
if (buildingBlocks == null || !buildingBlocks.ContainsKey(guid))
182+
InitializeBuildingBlockIDs();
183+
return buildingBlocks[guid];
184+
}
185+
186+
/// <summary>
187+
/// Populates dictionary with references to building blocks.
188+
/// Used for dumping block IDs while building.
189+
/// Called at first DumpBlockID after machine change.
190+
/// </summary>
191+
public static void InitializeBuildingBlockIDs()
192+
{
193+
var typeCount = new Dictionary<string, int>();
194+
buildingBlocks = new Dictionary<Guid, string>();
195+
for (int i = 0; i < ReferenceMaster.BuildingBlocks.Count; i++)
196+
{
197+
GenericBlock block = ReferenceMaster.BuildingBlocks[i].GetComponent<GenericBlock>();
198+
string name = ReferenceMaster.BuildingBlocks[i].GetComponent<MyBlockInfo>().blockName.ToUpper();
199+
typeCount[name] = typeCount.ContainsKey(name) ? typeCount[name] + 1 : 1;
200+
buildingBlocks[block.Guid] = name + " " + typeCount[name];
201+
}
202+
}
203+
204+
/// <summary>
205+
/// Populates dictionary with references to block handlers.
206+
/// Used for accessing blocks with GetBlock() while simulating.
207+
/// If mod is loaded, it gets called automatically at the start of simulation.
208+
/// Invokes OnInitialisation event when done.
209+
/// </summary>
210+
public static void InitializeBlockHandlers()
211+
{
212+
idToBlockHandler = new Dictionary<string, BlockHandler>();
213+
guidToBlockHandler = new Dictionary<Guid, BlockHandler>();
214+
bbToBlockHandler = new Dictionary<BlockBehaviour, BlockHandler>();
215+
var typeCount = new Dictionary<string, int>();
216+
for (int i = 0; i < ReferenceMaster.BuildingBlocks.Count; i++)
217+
{
218+
var name = ReferenceMaster.BuildingBlocks[i].GetComponent<MyBlockInfo>().blockName.ToUpper();
219+
typeCount[name] = typeCount.ContainsKey(name) ? typeCount[name] + 1 : 1;
220+
var id = name + " " + typeCount[name];
221+
Guid guid = ReferenceMaster.BuildingBlocks[i].Guid;
222+
var b = CreateBlock(ReferenceMaster.SimulationBlocks[i]);
223+
idToBlockHandler[id] = b;
224+
guidToBlockHandler[guid] = b;
225+
}
226+
227+
Initialised = true;
228+
OnInitialisation?.Invoke();
229+
}
230+
231+
/// <summary>
232+
/// Destroys dictionary of block handler references.
233+
/// Called at the end of the simulation.
234+
/// </summary>
235+
public static void DestroyBlockHandlers()
236+
{
237+
if (bbToBlockHandler != null)
238+
foreach (var entry in bbToBlockHandler)
239+
entry.Value.Dispose();
240+
idToBlockHandler = null;
241+
guidToBlockHandler = null;
242+
bbToBlockHandler = null;
243+
Initialised = false;
244+
}
245+
246+
/// <summary>
247+
/// Retrieve all initialized Block handlers.
248+
/// </summary>
249+
public static List<BlockHandler> GetBlocks()
250+
{
251+
if (!Initialised) throw new InvalidOperationException("Block handlers are not initialised.");
252+
var blocks = new List<BlockHandler>();
253+
foreach (KeyValuePair<string, BlockHandler> entry in idToBlockHandler)
254+
{
255+
blocks.Add(entry.Value);
256+
}
257+
return blocks;
258+
}
259+
260+
/// <summary>
261+
/// Add custom BlockHandler to be initialized for blocks of the specified BlockType.
262+
/// Must derive from LenchScripter.Blocks.Block base class.
263+
/// </summary>
264+
/// <param name="BlockType">Block type ID.</param>
265+
/// <param name="BlockHandler">Type of your Block handler.</param>
266+
public static void AddBlockHandler(int BlockType, Type BlockHandler)
267+
{
268+
if (!BlockHandler.IsSubclassOf(typeof(Block)))
269+
{
270+
throw new ArgumentException(BlockHandler.ToString() + " is not a subclass of Block.");
271+
}
272+
if (Types.ContainsKey(BlockType))
273+
{
274+
Types[BlockType] = BlockHandler;
275+
}
276+
else
277+
{
278+
Types.Add(BlockType, BlockHandler);
279+
}
280+
}
281+
}
282+
283+
284+
/// <summary>
285+
/// Exception to be thrown when a block is not found.
286+
/// </summary>
287+
public class BlockNotFoundException : Exception
288+
{
289+
/// <summary>
290+
/// Creates new BlockNotFoundException with given message.
291+
/// </summary>
292+
/// <param name="message"></param>
293+
public BlockNotFoundException(string message) : base(message) { }
294+
}
295+
296+
/// <summary>
297+
/// Exception to be thrown when trying to call an action that does not exist for the current block.
298+
/// </summary>
299+
public class ActionNotFoundException : Exception
300+
{
301+
/// <summary>
302+
/// Creates new ActionNotFoundException with given message.
303+
/// </summary>
304+
/// <param name="message"></param>
305+
public ActionNotFoundException(string message) : base(message) { }
306+
}
307+
308+
/// <summary>
309+
/// Exception to be thrown when referencing the block's property that does not exist for the current block.
310+
/// </summary>
311+
public class PropertyNotFoundException : Exception
312+
{
313+
/// <summary>
314+
/// Creates new PropertyNotFoundException with given message.
315+
/// </summary>
316+
/// <param name="message"></param>
317+
public PropertyNotFoundException(string message) : base(message) { }
318+
}
319+
320+
/// <summary>
321+
/// Exception to be thrown when trying to access the block's rigid body if it does not have one.
322+
/// </summary>
323+
public class NoRigidBodyException : Exception
324+
{
325+
/// <summary>
326+
/// Creates new NoRigidBody with given message.
327+
/// </summary>
328+
/// <param name="message"></param>
329+
public NoRigidBodyException(string message) : base(message) { }
330+
}
331+
}

0 commit comments

Comments
 (0)