-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added factory architecture to assist with creating factories of item …
…types. Courtesy of Thraka and the GoRogue-SadConsole integration library for the original code :D
- Loading branch information
Showing
5 changed files
with
193 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace SadConsole.Factory | ||
{ | ||
/// <summary> | ||
/// Base class for a settings object that contains parameters to pass to the Create function of a factory. | ||
/// </summary> | ||
public class BlueprintConfig | ||
{ | ||
/// <summary> | ||
/// Represents no arguments -- pass as the config parameter to Create if there are no parameters you wish to pass. | ||
/// </summary> | ||
public static readonly BlueprintConfig Empty = new BlueprintConfig(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
using System; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
|
||
namespace SadConsole.Factory | ||
{ | ||
/// <summary> | ||
/// A factory that produces a type of object based on a blueprint and a set of configuration parameters. | ||
/// </summary> | ||
/// <typeparam name="TBlueprintConfig">The type of parameter passed to the <see cref="Create(string, TBlueprintConfig)"/> function each time an object is created.</typeparam> | ||
/// <typeparam name="TProduced">The type of object this factory creates.</typeparam> | ||
public class Factory<TBlueprintConfig, TProduced> : IEnumerable<IBlueprint<TBlueprintConfig, TProduced>> | ||
where TBlueprintConfig : BlueprintConfig | ||
{ | ||
private readonly Dictionary<string, IBlueprint<TBlueprintConfig, TProduced>> _blueprints = new Dictionary<string, IBlueprint<TBlueprintConfig, TProduced>>(); | ||
|
||
/// <summary> | ||
/// Adds a blueprint to the factory. | ||
/// </summary> | ||
/// <param name="blueprint">The blueprint to add.</param> | ||
public void Add(IBlueprint<TBlueprintConfig, TProduced> blueprint) => _blueprints[blueprint.Id] = blueprint; | ||
|
||
/// <summary> | ||
/// Creates a <typeparamref name="TProduced"/> object using the blueprint with the given factory id, and the given settings object. | ||
/// </summary> | ||
/// <param name="factoryId">The factory id of a blueprint.</param> | ||
/// <param name="blueprintConfig">A settings object passed to the Create function of the blueprint.</param> | ||
/// <returns>A new object.</returns> | ||
public TProduced Create(string factoryId, TBlueprintConfig blueprintConfig) | ||
{ | ||
if (!_blueprints.ContainsKey(factoryId)) | ||
{ | ||
throw new ItemNotDefinedException(factoryId); | ||
} | ||
|
||
TProduced obj = _blueprints[factoryId].Create(blueprintConfig); | ||
if (obj is IFactoryObject factoryObj) | ||
{ | ||
factoryObj.DefinitionId = factoryId; | ||
} | ||
|
||
return obj; | ||
} | ||
|
||
/// <summary> | ||
/// Checks if a blueprint exists. | ||
/// </summary> | ||
/// <param name="factoryId">The blueprint to check for.</param> | ||
/// <returns>Returns true when the specified <paramref name="factoryId"/> exists; otherwise false.</returns> | ||
public bool BlueprintExists(string factoryId) => _blueprints.ContainsKey(factoryId); | ||
|
||
/// <summary> | ||
/// Gets a blueprint by identifier. | ||
/// </summary> | ||
/// <param name="factoryId">The blueprint identifier to get.</param> | ||
/// <returns>The blueprint of the object.</returns> | ||
/// <exception cref="ItemNotDefinedException">Thrown if the factory identifier does not exist.</exception> | ||
public IBlueprint<TBlueprintConfig, TProduced> GetBlueprint(string factoryId) | ||
{ | ||
if (!_blueprints.ContainsKey(factoryId)) | ||
{ | ||
throw new ItemNotDefinedException(factoryId); | ||
} | ||
|
||
return _blueprints[factoryId]; | ||
} | ||
|
||
/// <summary> | ||
/// Gets an enumerator of all of the blueprints in the factory. | ||
/// </summary> | ||
/// <returns>An enumeration of the blueprints.</returns> | ||
public IEnumerator<IBlueprint<TBlueprintConfig, TProduced>> GetEnumerator() => _blueprints.Values.GetEnumerator(); | ||
|
||
/// <summary> | ||
/// Gets an enumerator of all of the blueprints in the factory. | ||
/// </summary> | ||
/// <returns>An enumeration of the blueprints.</returns> | ||
IEnumerator IEnumerable.GetEnumerator() => _blueprints.Values.GetEnumerator(); | ||
} | ||
|
||
/// <summary> | ||
/// Exception thrown by <see cref="Factory{TBlueprintConfig, TProduced}"/> objects when a blueprint that doesn't exist is used. | ||
/// </summary> | ||
[Serializable] | ||
public class ItemNotDefinedException : Exception | ||
{ | ||
/// <summary> | ||
/// Creates an exception. | ||
/// </summary> | ||
/// <param name="factoryId">Factory id that caused the error.</param> | ||
public ItemNotDefinedException(string factoryId) | ||
: base($"The item '{factoryId}' has not been added to this factory.") | ||
{ } | ||
} | ||
|
||
/// <summary> | ||
/// A factory that produces a type of object based on a blueprint. | ||
/// </summary> | ||
/// <typeparam name="TProduced">The type of object this factory creates.</typeparam> | ||
public class Factory<TProduced> : Factory<BlueprintConfig, TProduced> | ||
{ | ||
/// <summary> | ||
/// Creates a <typeparamref name="TProduced"/> object using the blueprint with the given factory id. | ||
/// </summary> | ||
/// <param name="factoryId">The factory id of a blueprint.</param> | ||
/// <returns>A new object.</returns> | ||
public TProduced Create(string factoryId) => Create(factoryId, BlueprintConfig.Empty); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
namespace SadConsole.Factory | ||
{ | ||
/// <summary> | ||
/// Defines how to create a <typeparamref name="TProduced"/> object. | ||
/// </summary> | ||
/// <typeparam name="TBlueprintConfig">The type of the parameter to pass to the <see cref="Create(TBlueprintConfig)"/> function.</typeparam> | ||
/// <typeparam name="TProduced">The type of object to create.</typeparam> | ||
public interface IBlueprint<in TBlueprintConfig, out TProduced> where TBlueprintConfig : BlueprintConfig | ||
{ | ||
/// <summary> | ||
/// A unique identifier of this factory definition. | ||
/// </summary> | ||
string Id { get; } | ||
|
||
/// <summary> | ||
/// Creates a <typeparamref name="TProduced"/> object. | ||
/// </summary> | ||
/// <param name="config">Configuration parameters used to create the object.</param> | ||
/// <returns>The created object.</returns> | ||
TProduced Create(TBlueprintConfig config); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
namespace SadConsole.Factory | ||
{ | ||
/// <summary> | ||
/// Interface that can optionally be implemented by objects created via a <see cref="Factory{TBlueprintConfig, TProduced}"/>. The <see cref="DefinitionId"/> property | ||
/// will be automatically set to the ID of the blueprint used to create the object when the Factory's Create function is called. | ||
/// </summary> | ||
public interface IFactoryObject | ||
{ | ||
/// <summary> | ||
/// The identifier of the <see cref="IBlueprint{TBlueprintConfig, TProduced}"/> that created this object. Do not set manually -- <see cref="Factory{TBlueprintConfig, TProduced}"/> | ||
/// will automatically set this field when the object is created. | ||
/// </summary> | ||
string DefinitionId { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
namespace SadConsole.Factory | ||
{ | ||
/// <summary> | ||
/// A simple <see cref="IBlueprint{TBlueprintConfig, TProduced}"/> that can be used when no configuration object is necessary to create the object. | ||
/// Implements <see cref="IBlueprint{BlueprintConfig, TProduced}"/>. | ||
/// </summary> | ||
/// <typeparam name="TProduced">The type of object to create.</typeparam> | ||
public abstract class SimpleBlueprint<TProduced> : IBlueprint<BlueprintConfig, TProduced> | ||
{ | ||
/// <summary> | ||
/// A unique identifier of this factory definition. | ||
/// </summary> | ||
public string Id { get; } | ||
|
||
/// <summary> | ||
/// Creates a SimpleBlueprint with the given blueprint id. | ||
/// </summary> | ||
/// <param name="id">ID for the blueprint.</param> | ||
public SimpleBlueprint(string id) => Id = id; | ||
|
||
/// <summary> | ||
/// Calls <see cref="Create()"/>. | ||
/// </summary> | ||
/// <param name="config">Unused.</param> | ||
/// <returns>The created object.</returns> | ||
public TProduced Create(BlueprintConfig config) => Create(); | ||
|
||
/// <summary> | ||
/// Creates a <typeparamref name="TProduced"/> object. | ||
/// </summary> | ||
/// <returns>The created object.</returns> | ||
public abstract TProduced Create(); | ||
} | ||
} |