Skip to content

Instantly share code, notes, and snippets.

@dasannikov
Last active April 21, 2019 09:49
Show Gist options
  • Save dasannikov/c68cb57adf09c125db2edf2fe82d7254 to your computer and use it in GitHub Desktop.
Save dasannikov/c68cb57adf09c125db2edf2fe82d7254 to your computer and use it in GitHub Desktop.
using System;
using System.Text;
//----------------------------------------------------------------------------
// Using:
//
// private UpdateCheckString<int, int> _updateCheck;
// ...
// if(_updateCheck.IsChanged("Time now: {0}:{1}", DateTime.UtcNow.Minute, DateTime.UtcNow.Second))
// TextObject.text = _updateCheck;
//
//----------------------------------------------------------------------------
public struct UpdateCheckString<T1> where T1 : IEquatable<T1> {
private StringBuilder _sb;
private T1 _prevValue;
public static implicit operator string(UpdateCheckString<T1> t) {
return t._sb != null ? t._sb.ToString() : "";
}
public bool IsChanged(string format, T1 value) {
// Lazy init or check update
if(_sb == null) {
_sb = new StringBuilder(20);
_prevValue = value;
} else if(_prevValue.Equals(value)) {
return false;
}
// Update Text
_prevValue = value;
_sb.Clear();
_sb.AppendFormat(format, value);
return true;
}
}
//----------------------------------------------------------------------------
public struct UpdateCheckString<T1, T2> where T1 : IEquatable<T1> where T2 : IEquatable<T2> {
private StringBuilder _sb;
private T1 _prevValue1;
private T2 _prevValue2;
public static implicit operator string(UpdateCheckString<T1, T2> t) {
return t._sb != null ? t._sb.ToString() : "";
}
public bool IsChanged(string format, T1 value1, T2 value2) {
// Lazy init or check update
if(_sb == null) {
_sb = new StringBuilder(20);
_prevValue1 = value1;
_prevValue2 = value2;
} else if(_prevValue1.Equals(value1) && _prevValue2.Equals(value2))
return false;
// Update Text
_prevValue1 = value1;
_prevValue2 = value2;
_sb.Clear();
_sb.AppendFormat(format, value1, value2);
return true;
}
}
//----------------------------------------------------------------------------
public struct UpdateCheckString<T1, T2, T3>
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3> {
private StringBuilder _sb;
private T1 _prevValue1;
private T2 _prevValue2;
private T3 _prevValue3;
public static implicit operator string(UpdateCheckString<T1, T2, T3> t) {
return t._sb != null ? t._sb.ToString() : "";
}
public bool IsChanged(string format, T1 value1, T2 value2, T3 value3) {
// Lazy init or check update
if(_sb == null) {
_sb = new StringBuilder(20);
_prevValue1 = value1;
_prevValue2 = value2;
_prevValue3 = value3;
} else if(_prevValue1.Equals(value1) && _prevValue2.Equals(value2) && _prevValue3.Equals(value3))
return false;
// Update Text
_prevValue1 = value1;
_prevValue2 = value2;
_prevValue3 = value3;
_sb.Clear();
_sb.AppendFormat(format, value1, value2, value3);
return true;
}
}
//----------------------------------------------------------------------------
public struct UpdateCheckString<T1, T2, T3, T4>
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4> {
private StringBuilder _sb;
private T1 _prevValue1;
private T2 _prevValue2;
private T3 _prevValue3;
private T4 _prevValue4;
public static implicit operator string(UpdateCheckString<T1, T2, T3, T4> t) {
return t._sb != null ? t._sb.ToString() : "";
}
public bool IsChanged(string format, T1 value1, T2 value2, T3 value3, T4 value4) {
// Lazy init or check update
if(_sb == null) {
_sb = new StringBuilder(20);
_prevValue1 = value1;
_prevValue2 = value2;
_prevValue3 = value3;
_prevValue4 = value4;
} else if(_prevValue1.Equals(value1) && _prevValue2.Equals(value2) && _prevValue3.Equals(value3) && _prevValue4.Equals(value4))
return false;
// Update Text
_prevValue1 = value1;
_prevValue2 = value2;
_prevValue3 = value3;
_prevValue4 = value4;
_sb.Clear();
_sb.AppendFormat(format, value1, value2, value3, value4);
return true;
}
}
//----------------------------------------------------------------------------
public struct UpdateCheckString<T1, T2, T3, T4, T5>
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
where T5 : IEquatable<T5> {
private StringBuilder _sb;
private T1 _prevValue1;
private T2 _prevValue2;
private T3 _prevValue3;
private T4 _prevValue4;
private T5 _prevValue5;
public static implicit operator string(UpdateCheckString<T1, T2, T3, T4, T5> t) {
return t._sb != null ? t._sb.ToString() : "";
}
public bool IsChanged(string format, T1 value1, T2 value2, T3 value3, T4 value4, T5 value5) {
// Lazy init or check update
if(_sb == null) {
_sb = new StringBuilder(20);
_prevValue1 = value1;
_prevValue2 = value2;
_prevValue3 = value3;
_prevValue4 = value4;
_prevValue5 = value5;
} else if(_prevValue1.Equals(value1) && _prevValue2.Equals(value2) && _prevValue3.Equals(value3) && _prevValue4.Equals(value4) && _prevValue5.Equals(value5))
return false;
// Update Text
_prevValue1 = value1;
_prevValue2 = value2;
_prevValue3 = value3;
_prevValue4 = value4;
_prevValue5 = value5;
_sb.Clear();
_sb.AppendFormat(format, value1, value2, value3, value4, value5);
return true;
}
}
@dasannikov
Copy link
Author

dasannikov commented Mar 23, 2018

Гипотетический пример использования

public class Player {
	public int PosX;
	public int PosY;
}

public class PlayerView {
	
	void Update1() {
		ScreenText = "Position: " + PlayerObject.PosX + ":" + PlayerObject.PosY;
	}

       void Update2() {
           if(UpdateCheck(PlayerObject.PosX, PlayerObject.PosY))
               ScreenText = "Position: " + PlayerObject.PosX + ":" + PlayerObject.PosY;
       }


	void UpdateIdeal() {
		UpdateCheck(ScreenText, "Position: ", PlayerObject.PosX, ":", PlayerObject.PosY);
	}
}

1й вариант плохой - мы создаем строку каждый раз
2й вариант - уже лучше но неудобен (см. коммент выше)
3й вариант идеальный?

Есть идеи как решить эту задачу лучше? (может быть в принципе нужен другой подход?)

@dasannikov
Copy link
Author

dasannikov commented Mar 24, 2018

Обновил. Результат вполне приемлем:

  • кэшируемые параметры могут быть произвольного типа
  • аллокаций практически нет
  • код теперь в структурах (не нужно создавать через new)
  • работает все очень быстро
  • нужно тиражировать код под разное кол-во параметров

Есть пожелания и замечания по улучшению?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment