Skip to content

Commit 7ab30c5

Browse files
author
Nestor Soriano Vilchez
committedMar 21, 2016
More documentation written.
1 parent 2efba72 commit 7ab30c5

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed
 

‎NestorMSX.BuiltInPlugins/SlotPlugins/DiskImageBasedStoragePlugin.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public DiskImageBasedStoragePlugin(PluginContext context, IDictionary<string, ob
7575
.Select(f => StringExtensions.AsAbsolutePath(f, basePathForDiskImages))
7676
.ToArray();
7777

78-
this.slotNumber = new SlotNumber(pluginConfig.GetValue<byte>("slotNumber"));
78+
this.slotNumber = new SlotNumber(pluginConfig.GetValue<byte>("NestorMSX.slotNumber"));
7979

8080
var machineName = pluginConfig.GetValue<string>("NestorMSX.machineName");
8181
stateFileFullPath = $"{machineName}/{PluginDisplayName} in slot {slotNumber}.dat".AsAbsolutePath();

‎NestorMSX.Infrastructure/Misc/DictionaryUtils.cs ‎NestorMSX.Infrastructure/Misc/DictionaryExtensions.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Konamiman.NestorMSX.Misc
88
{
9-
public static class DictionaryUtils
9+
public static class DictionaryExtensions
1010
{
1111
/// <summary>
1212
/// Gets the value of the configuration for the specified key, converted
@@ -140,21 +140,21 @@ private static T AdaptValue<T>(string key, object value)
140140
return (T)AdaptValue(typeof(T), key, value);
141141
}
142142

143-
private static object AdaptValue(Type type, string key, object value)
143+
private static object AdaptValue(Type destinationType, string key, object value)
144144
{
145145
if(value == null)
146146
return null;
147147

148-
if(type.IsInstanceOfType(value))
148+
if(destinationType.IsInstanceOfType(value))
149149
return value;
150150

151-
if(type.IsArray)
151+
if(destinationType.IsArray)
152152
{
153153
if(!value.GetType().IsArray)
154154
throw new ConfigurationException($"Configuration key '{key}' has value '{value.ToString()}', that can't be converted to an array");
155155

156156
var originalArray = (Array)value;
157-
var arrayItemsType = type.GetElementType();
157+
var arrayItemsType = destinationType.GetElementType();
158158

159159
var arrayLength = originalArray.GetLength(0);
160160
var adaptedArray = Array.CreateInstance(arrayItemsType, arrayLength);
@@ -168,10 +168,10 @@ private static object AdaptValue(Type type, string key, object value)
168168
object[] convertMethodArguments;
169169
if(value is string)
170170
{
171-
convertMethod = GetConvertMethod(type, new[] {typeof(string), typeof(int)});
171+
convertMethod = GetConvertMethod(destinationType, new[] {typeof(string), typeof(int)});
172172
if(convertMethod == null)
173173
{
174-
convertMethod = GetConvertMethod(type, new[] {typeof(object)});
174+
convertMethod = GetConvertMethod(destinationType, new[] {typeof(object)});
175175
convertMethodArguments = new object[] { value };
176176
}
177177
else
@@ -187,12 +187,12 @@ private static object AdaptValue(Type type, string key, object value)
187187
}
188188
else
189189
{
190-
convertMethod = GetConvertMethod(type, new[] { typeof(object) });
190+
convertMethod = GetConvertMethod(destinationType, new[] { typeof(object) });
191191
convertMethodArguments = new object[] { value };
192192
}
193193

194194
if(convertMethod == null)
195-
throw new ConfigurationException($"Configuration key '{key}' has value '{value.ToString()}', that can't be converted to '{type.Name}'");
195+
throw new ConfigurationException($"Configuration key '{key}' has value '{value.ToString()}', that can't be converted to '{destinationType.Name}'");
196196

197197
try
198198
{
@@ -201,7 +201,7 @@ private static object AdaptValue(Type type, string key, object value)
201201
catch(TargetInvocationException ex)
202202
{
203203
throw new ConfigurationException(
204-
$"Error when converting value {value.ToString()} for key '{key}' to {type.Name}: {ex.InnerException.Message}",
204+
$"Error when converting value {value.ToString()} for key '{key}' to {destinationType.Name}: {ex.InnerException.Message}",
205205
ex.InnerException);
206206
}
207207
}

‎NestorMSX.Infrastructure/NestorMSX.Infrastructure.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<Compile Include="Memories\PlainRam.cs" />
7070
<Compile Include="Memories\PlainRom.cs" />
7171
<Compile Include="Menus\MenuEntry.cs" />
72-
<Compile Include="Misc\DictionaryUtils.cs" />
72+
<Compile Include="Misc\DictionaryExtensions.cs" />
7373
<Compile Include="Misc\SlotNumber.cs" />
7474
<Compile Include="Misc\StringExtensions.cs" />
7575
<Compile Include="Misc\TwinBit.cs" />

‎NestorMSX/Emulator/MsxEmulationEnvironment.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ private void CreateSlotsSystem()
222222
continue;
223223

224224
var pluginConfig = (IDictionary<string, object>)slotConfig.Value;
225-
pluginConfig["slotNumber"] = slotNumber.EncodedByte;
225+
pluginConfig["NestorMSX.slotNumber"] = slotNumber.EncodedByte;
226226

227227
var typeName = (string)pluginConfig["type"];
228228

‎PluginDevelopmentGuide.md

+32
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,35 @@ The supplied `PluginContext` instance is what allows the plugin to really do som
153153
Note that the `PluginContext` class has a `EnvironmentInitializationComplete` event. If your plugin needs to access the loaded plugins list or the slots system, it shouldn't do so until this event is fired. Note also that plugins aren't loaded/initialized in any particular order.
154154

155155
Please take a look at the `PluginContext` class itself for more details.
156+
157+
158+
## The plugin configuration ##
159+
160+
The `pluginConfig` argument passed to the plugin class constructor or to the `GetInstance` method contains all the configuration that the user has supplied for the plugin in either the global _NestorMSX.config_ file or the specific _machine.config_ file. It is a dictionary that represents a direct translation of the JSON object that represents the plugin configuration. Values that are in turn JSON objects are supplied as nested dictionaries in turn.
161+
162+
Rather than accessing the supplied dictionary directly, it is recommended to use the extension methods that are available in [the DictionaryExtensions class](NestorMSX.Infrastructure/Misc/DictionaryExtensions.cs), being the most important ones:
163+
164+
* **GetValue<T>(key):** Gets the value of the specified key, appropriately converted to the specified type T. [The standard Convert class](https://msdn.microsoft.com/en-us/library/system.convert) is used to perform the conversion from string to T, and a special handling is in place for arrays. An exception is thrown if the key does not exist.
165+
166+
* **GetValueOrDefault<T>(key):** Same as above, but the supplied default value is returned if the key does not exist.
167+
168+
* **GetDictionaryOrDefault(key):** Returns the value of the specified key as a dictionary. If the key does not exist it returns an empty dictionary. If the key exists but the value is not a dictionary, an exception is thrown.
169+
170+
* **MergeInto(destination):** Copies all the key/value pairs into the destination dictionary, but only for the keys that don't already exist. Useful to inject default values in the supplied configuration dictionary.
171+
172+
* **GetMachineFilePath, GetMachineOrDataFilePath:** These methods are useful to find plugin-specific files when relative paths are supplied.
173+
174+
See also [the StringExtensions class](NestorMSX.Infrastructure/Misc/StringExtensions.cs).
175+
176+
177+
### Injected configuration ###
178+
179+
Besides containing the configuration object supplied by the user as a JSON object in the global or machine configuration file, `pluginConfig` contains also some extra values that are injected by NestorMSX and can be useful for the plugin. These are:
180+
181+
* **"NestorMSX.machineName"**: Contains the name of the machine currently running.
182+
* **"NestorMSX.machineDirectory"**: Contains the full path of the directory where the `machine.config` file for the currently running machine is.
183+
* **"NestorMSX.sharedDirectory"**: Contains the full path of the _Shared_ subdirectory in the machines directory. Note that this directory is examined automatically as needed if you use the `GetMachineFilePath` and `GetMachineOrDataFilePath` methods.
184+
* **"NestorMSX.applicationDirectory"**: Contains the full path of the _NestorMSX.exe_ file.
185+
* **"NestorMSX.slotNumber"**: This value is injected only for plugins that are plugged in a slot. It contains the slot number where the plugin is, as one byte in the standard format (slot + 4*subslot + 128 if slot is expanded).
186+
187+
Future versions of NestorMSX could inject more values, but the names of these will always start with "NestorMSX."

0 commit comments

Comments
 (0)
Please sign in to comment.