Skip to content

Commit

Permalink
Change over the class dependency system to attributes.
Browse files Browse the repository at this point in the history
  • Loading branch information
zorbathut committed Sep 27, 2024
1 parent 9cf6b98 commit b86d96e
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 130 deletions.
21 changes: 21 additions & 0 deletions src/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,25 @@ public class CloneWithAssignmentAttribute : Attribute
{

}

/// <summary>
/// Signals that this class should have its ConfigErrors/PostLoad run after a different class.
/// </summary>
/// <remarks>
/// Currently valid and meaningful only when applied to, and referencing, things inheriting from Dec.Dec.
///
/// Configuration order will be (mostly) stable with a fixed set of constraints into account.
/// </remarks>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class SetupDependsOnAttribute : Attribute
{
private Type type;

internal Type Type => type;

public SetupDependsOnAttribute(Type type)
{
this.type = type;
}
}
}
33 changes: 0 additions & 33 deletions src/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,6 @@ public static IEnumerable<Dec> List
}
}

/// <summary>
/// All registered dec root types.
/// </summary>
/// <remarks>
/// Types are listed in no guaranteed or stable order.
///
/// As of this writing, this will return only Dec types that have instances. This may change someday.
/// </remarks>
public static IEnumerable<Type> ListTypes
{
get
{
return Lookup.Keys.Where(type => type.GetDecDatabaseStatus() == UtilType.DecDatabaseStatus.Root);
}
}

/// <summary>
/// Retrieves a dec by base dec type and name.
/// </summary>
Expand All @@ -79,23 +63,6 @@ public static Dec Get(Type type, string name)
return typedict.TryGetValue(name);
}

/// <summary>
/// Retrieves a list of decs of a given type.
/// </summary>
/// <remarks>
/// Returns null if no such dec exists.
/// </remarks>
public static IEnumerable<Dec> ListOfType(Type type)
{
if (!Lookup.ContainsKey(type))
{
WarnOnEmpty();
return Enumerable.Empty<Dec>();
}

return Lookup[type].Values;
}

/// <summary>
/// Creates a Dec.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ public void AddStream(Parser.FileType fileType, Stream stream, string identifier
/// The `dependencies` parameter can be used to feed in dependencies for the PostLoad function.
/// This is a placeholder and is probably going to be replaced at some point, though only with something more capable.
/// </remarks>
public void Finish(List<Dag<Type>.Dependency> postLoadDependencies = null)
public void Finish()
{
parserModdable.Finish(postLoadDependencies);
parserModdable.Finish();
}
}
}
47 changes: 42 additions & 5 deletions src/ParserModular.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public Module CreateModule(string name)
/// The `dependencies` parameter can be used to feed in dependencies for the PostLoad function.
/// This is a placeholder and is probably going to be replaced at some point, though only with something more capable.
/// </remarks>
public void Finish(List<Dag<Type>.Dependency> postLoadDependencies = null)
public void Finish()
{
using (var _ = new CultureInfoScope(Config.CultureInfo))
{
Expand Down Expand Up @@ -464,12 +464,49 @@ public void Finish(List<Dag<Type>.Dependency> postLoadDependencies = null)
}
s_Status = Status.Finalizing;

// figure out our config/postload order
var postprocessOrder = Dag<Type>.CalculateOrder(Database.ListTypes, postLoadDependencies ?? new List<Dag<Type>.Dependency>(), t => t.FullName);
// figure out our config/postload order; first we just run over all the Decs and collate classes
var decTypes = new Dictionary<Type, List<Dec>>();
foreach (var dec in Database.List)
{
var list = decTypes.TryGetValue(dec.GetType());
if (list == null)
{
list = new List<Dec>();
decTypes[dec.GetType()] = list;
}

list.Add(dec);
}

List<Dag<Type>.Dependency> postLoadDependencies = new List<Dag<Type>.Dependency>();
foreach (var type in decTypes)
{
foreach (var rsaa in type.Key.GetCustomAttributes<SetupDependsOnAttribute>())
{
var dependsOn = rsaa.Type;

// make sure it inherits from Dec.Dec
if (!dependsOn.IsSubclassOf(typeof(Dec)))
{
Dbg.Err($"{type.Key} has a SetupDependsOnAttribute on {dependsOn}, but {dependsOn} is not a Dec type");
continue;
}

if (!decTypes.ContainsKey(rsaa.Type))
{
Dbg.Err($"{type.Key} has a SetupDependsOnAttribute on {dependsOn}, but {dependsOn} is not a known Dec type; this might result in weird behavior, either create an instance of {dependsOn} or pester ZorbaTHut on Discord if you need this fixed");
continue;
}

postLoadDependencies.Add(new Dag<Type>.Dependency { before = rsaa.Type, after = type.Key });
}
}

var postprocessOrder = Dag<Type>.CalculateOrder(decTypes.Keys, postLoadDependencies, t => t.Name);

foreach (var type in postprocessOrder)
{
foreach (var dec in Database.ListOfType(type))
foreach (var dec in decTypes[type])
{
try
{
Expand All @@ -484,7 +521,7 @@ public void Finish(List<Dag<Type>.Dependency> postLoadDependencies = null)

foreach (var type in postprocessOrder)
{
foreach (var dec in Database.ListOfType(type))
foreach (var dec in decTypes[type])
{
try
{
Expand Down
Loading

0 comments on commit b86d96e

Please sign in to comment.