This repository has been archived on 2023-02-02. You can view files and clone it, but cannot push or open issues or pull requests.
mfgames-nitride-cil/src/MfGames.Nitride.Handlebars/HandlebarsTemplateCache.cs

66 lines
2.0 KiB
C#

using System.Collections.Generic;
using HandlebarsDotNet;
using Open.Threading;
namespace MfGames.Nitride.Handlebars;
/// <summary>
/// Implements a cache for templates to prevent compiling the same template
/// more than once.
/// </summary>
public class HandlebarsTemplateCache
{
private readonly IHandlebars handlebars;
private readonly ModificationSynchronizer locker;
private readonly Dictionary<string, HandlebarsTemplate<object, object>> templates;
public HandlebarsTemplateCache(IHandlebars handlebars)
{
this.handlebars = handlebars;
this.locker = new ModificationSynchronizer();
this.templates = new Dictionary<string, HandlebarsTemplate<object, object>>();
}
/// <summary>
/// Caches the template by name based on the contents of the disk. It
/// does it once in a multi-threaded manner to ensure it is only cached
/// once in memory.
/// </summary>
/// <param name="literal">The string that contains the template.</param>
/// <returns></returns>
public HandlebarsTemplate<object, object> GetLiteralTemplate(string literal)
{
// Start with a read lock to see if we've already compiled it.
this.locker.Modifying(
() => !this.templates.ContainsKey(literal),
() =>
{
HandlebarsTemplate<object, object> template = this.handlebars!.Compile(literal);
this.templates[literal] = template;
return true;
});
return this.locker.Reading(() => this.templates[literal]);
}
/// <summary>
/// Caches the template by name based on the contents of the disk. It
/// does it once in a multi-threaded manner to ensure it is only cached
/// once in memory.
/// </summary>
/// <param name="templateName"></param>
/// <returns></returns>
public HandlebarsTemplate<object, object> GetNamedTemplate(string templateName)
{
string template = $"{{{{> {templateName}}}}}";
return this.GetLiteralTemplate(template);
}
}