1- using Celeste . Mod . Helpers ;
2- using Monocle ;
1+ using Monocle ;
2+ using System . Collections ;
33using System . Collections . Generic ;
44using System . Collections . ObjectModel ;
5+ using System . Linq ;
56using System . Text ;
67using System . Xml ;
78
@@ -15,20 +16,16 @@ public static class Emoji {
1516 /// A list of all registered emoji names, in order of their IDs.
1617 /// </summary>
1718 public static ReadOnlyCollection < string > Registered => new ReadOnlyCollection < string > ( _Registered ) ;
18-
1919 public static char Last => ( char ) ( '\uE000 ' + _Registered . Count - 1 ) ;
2020
2121 private static List < string > _Registered = new List < string > ( ) ;
2222 private static Dictionary < string , int > _IDs = new Dictionary < string , int > ( ) ;
2323 private static List < bool > _IsMonochrome = new List < bool > ( ) ;
2424 private static List < PixelFontCharacter > _Chars = new List < PixelFontCharacter > ( ) ;
2525
26- private static readonly CachedApply cachedApplies = new CachedApply ( ) ;
27-
2826 private static bool Initialized = false ;
2927 private static Queue < KeyValuePair < string , MTexture > > Queue = new Queue < KeyValuePair < string , MTexture > > ( ) ;
3028 private static XmlElement _FakeXML ;
31-
3229 public static XmlElement FakeXML {
3330 get {
3431 if ( _FakeXML != null )
@@ -132,7 +129,6 @@ public static void Register(string name, MTexture emoji, float scale) {
132129 }
133130
134131 _Chars . Add ( new PixelFontCharacter ( Start + id , emoji , xml ) ) ;
135- cachedApplies . Clear ( ) ;
136132 }
137133
138134 /// <summary>
@@ -178,76 +174,68 @@ public static bool TryGet(string name, out char c) {
178174 public static bool IsMonochrome ( char c )
179175 => _IsMonochrome [ c - Start ] ;
180176
181- private class CachedApply : CacheHelper < string , string > {
182- public CachedApply ( ) : base ( name : "Emoji.Apply" , maxSize : 1000 ) { }
183-
184- protected override string Compute ( string text ) {
185- if ( text == null )
186- return text ;
187-
188- // TODO: This trashes the GC and doesn't allow escaping!
189- lock ( _IDs ) {
190- StringBuilder resultBuilder = new StringBuilder ( ) ;
191- int appendStartIndex = 0 ;
192- int head = - 1 , tail = 0 ;
193- // suppose text is "aaaa:1111:2222:bbbb", and only ":2222:" is emoji name
194- // H = head, T = tail, S = appendStartIndex
195- while ( tail < text . Length ) {
196- if ( text [ tail ] == ':' ) {
197- if ( head >= 0 && text [ head ] == ':' ) {
177+ /// <summary>
178+ /// Transforms all instances of :emojiname: to \uSTART+ID
179+ /// </summary>
180+ /// <param name="text"></param>
181+ /// <returns></returns>
182+ public static string Apply ( string text ) {
183+ if ( text == null )
184+ return text ;
185+ // TODO: This trashes the GC and doesn't allow escaping!
186+ lock ( _IDs ) {
187+ StringBuilder resultBuilder = new StringBuilder ( ) ;
188+ int appendStartIndex = 0 ;
189+ int head = - 1 , tail = 0 ;
190+ // suppose text is "aaaa:1111:2222:bbbb", and only ":2222:" is emoji name
191+ // H = head, T = tail, S = appendStartIndex
192+ while ( tail < text . Length ) {
193+ if ( text [ tail ] == ':' ) {
194+ if ( head >= 0 && text [ head ] == ':' ) {
195+ /*
196+ aaaa:1111:2222:bbbb
197+ (2) ^S ^H ^T ^
198+ (4) ^S ^H ^T
199+ now head and tail are pointing to colons so we need to check if the text inside colons is an emoji name
200+ */
201+ string name = text . Substring ( head + 1 , ( tail - 1 ) - ( head + 1 ) + 1 ) ;
202+ if ( _IDs . TryGetValue ( name , out int value ) ) {
203+ // if it is, we need to first append the text before emoji
204+ resultBuilder . Append ( text , appendStartIndex , ( head - 1 ) - appendStartIndex + 1 ) ;
205+ // then append the emoji itself
206+ resultBuilder . Append ( ( char ) ( Start + value ) ) ;
207+ // the emoji name has been replaced, we need to advance tail pointer once
208+ // because the colon is used and can't belong to next emoji
209+ tail ++ ;
210+ appendStartIndex = tail ;
198211 /*
199212 aaaa:1111:2222:bbbb
200- (2) ^S ^H ^T ^
201- (4) ^S ^H ^T
202- now head and tail are pointing to colons so we need to check if the text inside colons is an emoji name
213+ (5) ^H S^T
203214 */
204- string name = text . Substring ( head + 1 , ( tail - 1 ) - ( head + 1 ) + 1 ) ;
205- if ( _IDs . TryGetValue ( name , out int value ) ) {
206- // if it is, we need to first append the text before emoji
207- resultBuilder . Append ( text , appendStartIndex , ( head - 1 ) - appendStartIndex + 1 ) ;
208- // then append the emoji itself
209- resultBuilder . Append ( ( char ) ( Start + value ) ) ;
210- // the emoji name has been replaced, we need to advance tail pointer once
211- // because the colon is used and can't belong to next emoji
212- tail ++ ;
213- appendStartIndex = tail ;
214- /*
215- aaaa:1111:2222:bbbb
216- (5) ^H S^T
217- */
218- }
219215 }
220- head = tail ;
221- /*
222- aaaa:1111:2222:bbbb
223- (1) ^S H^T ^
224- (3) ^S H^T
225- when tail is pointing to a colon, we need to let head also points to it
226- so when tail moves to next colon, text[head..tail] can be an emoji name and we can check then replace it
227- */
228216 }
229- tail ++ ;
217+ head = tail ;
218+ /*
219+ aaaa:1111:2222:bbbb
220+ (1) ^S H^T ^
221+ (3) ^S H^T
222+ when tail is pointing to a colon, we need to let head also points to it
223+ so when tail moves to next colon, text[head..tail] can be an emoji name and we can check then replace it
224+ */
230225 }
231- /*
232- aaaa:1111:2222:bbbb
233- (6) H^S ^T
234- there are still text left since last append, so we need to append them
235- */
236- if ( appendStartIndex < text . Length ) {
237- resultBuilder . Append ( text , appendStartIndex , ( text . Length - 1 ) - appendStartIndex + 1 ) ;
238- }
239- return resultBuilder . ToString ( ) ;
226+ tail ++ ;
227+ }
228+ /*
229+ aaaa:1111:2222:bbbb
230+ (6) H^S ^T
231+ there are still text left since last append, so we need to append them
232+ */
233+ if ( appendStartIndex < text . Length ) {
234+ resultBuilder . Append ( text , appendStartIndex , ( text . Length - 1 ) - appendStartIndex + 1 ) ;
240235 }
236+ return resultBuilder . ToString ( ) ;
241237 }
242238 }
243239
244- /// <summary>
245- /// Transforms all instances of :emojiname: to \uSTART+ID
246- /// </summary>
247- /// <param name="text"></param>
248- /// <returns></returns>
249- public static string Apply ( string text ) {
250- return cachedApplies . GetCached ( text ) ;
251- }
252240 }
253241}
0 commit comments