/* Copyright 2017-2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com Copyright 2020 Robert Xiao - https://robertxiao.ca All rights reserved. */ using System; using System.Collections.Generic; using System.Text; namespace Il2CppInspector.Outputs { /// /// A utility class for managing names in a common namespace. /// public class Namespace { private readonly Dictionary renameCount = new Dictionary(); public void ReserveName(string name) { if (renameCount.ContainsKey(name)) { throw new Exception($"Can't reserve {name}: already taken!"); } renameCount[name] = 0; } public Namer MakeNamer(Namer.KeyFunc keyFunc) { return new Namer(this, keyFunc); } /// /// A class for managing objects of a common type within a namespace. /// /// public class Namer { private Namespace ns; private readonly Dictionary names = new Dictionary(); public delegate string KeyFunc(T t); private readonly KeyFunc keyFunc; public Namer(Namespace ns, KeyFunc keyFunc) { this.ns = ns; this.keyFunc = keyFunc; } public string GetName(T t) { string name; if (names.TryGetValue(t, out name)) return name; name = keyFunc(t); // This approach avoids linear scan (quadratic blowup) if there are a lot of similarly-named objects. if (ns.renameCount.ContainsKey(name)) { int v = ns.renameCount[name] + 1; while (ns.renameCount.ContainsKey(name + "_" + v)) v++; ns.renameCount[name] = v; name = name + "_" + v; } ns.renameCount[name] = 0; names[t] = name; return name; } } } }