Skip to content

Commit

Permalink
Finish renaming to CancelPriority. Update docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
derrickcreamer committed Mar 1, 2020
1 parent 4236bdd commit 76c7096
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 53 deletions.
68 changes: 59 additions & 9 deletions Hemlock/StatusInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,39 +79,89 @@ public TStatus GetStatus<TStatus>() {
internal int? overrideSetIndex;
public int? OverrideSetIndex => overrideSetIndex;

/// <summary>Serialize this StatusInstance, which must NOT currently belong to a StatusTracker.</summary>
/// <param name="stream">Serialize to this stream. The stream will NOT be automatically closed.</param>
public void Serialize(System.IO.Stream stream){
if(tracker != null) throw new InvalidOperationException("Can't directly serialize a StatusInstance inside a StatusTracker. Serialize the entire StatusTracker instead.");
using(var writer = new System.IO.BinaryWriter(stream, System.Text.Encoding.UTF8, true)){
SerializeInternal(writer);
}
}
/// <summary>Serialize this StatusInstance, which must NOT currently belong to a StatusTracker.</summary>
/// <param name="writer">Serialize using this BinaryWriter. The underlying stream will NOT be automatically closed.</param>
public void Serialize(System.IO.BinaryWriter writer){
if(tracker != null) throw new InvalidOperationException("Can't directly serialize a StatusInstance inside a StatusTracker. Serialize the entire StatusTracker instead.");
if(writer == null) throw new ArgumentNullException(nameof(writer));
SerializeInternal(writer);
}
internal void SerializeInternal(System.IO.BinaryWriter writer){
writer.Write(Status);
writer.Write((int)InstanceType);
writer.Write(Value);
writer.Write(CancelPriority);
if(OverrideSetIndex == null){
writer.Write(false);
}
else{
writer.Write(true);
writer.Write(OverrideSetIndex.Value);
}
}
/// <summary>Deserialize and return a StatusInstance that was serialized outside of a StatusTracker.</summary>
/// <param name="stream">Deserialize from this stream. The stream will NOT be automatically closed.</param>
public static StatusInstance<TObject> Deserialize(System.IO.Stream stream){
using(var reader = new System.IO.BinaryReader(stream, System.Text.Encoding.UTF8, true)){
return Deserialize(reader);
}
}
/// <summary>Deserialize and return a StatusInstance that was serialized outside of a StatusTracker.</summary>
/// <param name="reader">Deserialize from this BinaryReader. The underlying stream will NOT be automatically closed.</param>
public static StatusInstance<TObject> Deserialize(System.IO.BinaryReader reader){
if(reader == null) throw new ArgumentNullException(nameof(reader));
int status = reader.ReadInt32();
int type = reader.ReadInt32();
int value = reader.ReadInt32();
int priority = reader.ReadInt32();
int? overrideIdx = null;
if(reader.ReadBoolean()){
overrideIdx = reader.ReadInt32();
}
StatusInstance<TObject> instance = new StatusInstance<TObject>(status, value, priority, (InstanceType)type, overrideIdx);
return instance;
}
/// <summary>
/// Create a (shallow) copy of this StatusInstance. If any non-null arguments are provided to this method,
/// those values will be used in the copy.
/// </summary>
/// <param name="value">If provided, the copy will be created with this value.</param>
/// <param name="priority">If provided, the copy will be created with this priority.</param>
/// <param name="cancelPriority">If provided, the copy will be created with this priority.</param>
/// <param name="type">If provided, the copy will be created with this InstanceType.</param>
/// <param name="overrideSetIndex">If provided, the copy will be created with this override set index.</param>
public StatusInstance<TObject> Clone(int? value = null, int? priority = null, InstanceType? type = null, int? overrideSetIndex = null) {
return new StatusInstance<TObject>(this, value, priority, type, overrideSetIndex);
public StatusInstance<TObject> Clone(int? value = null, int? cancelPriority = null, InstanceType? type = null, int? overrideSetIndex = null) {
return new StatusInstance<TObject>(this, value, cancelPriority, type, overrideSetIndex);
}
/// <param name="status">The status to which this instance will add its value</param>
/// <param name="value">The amount by which this instance will increase its status</param>
/// <param name="priority">An instance with lower priority will be cancelled before an instance with
/// <param name="cancelPriority">An instance with lower cancel priority will be cancelled before an instance with
/// higher priority when Cancel() is called on this status.</param>
/// <param name="type">
/// The InstanceType determines whether this instance will feed, suppress, or prevent its status.
/// (Feed is the default and most common. When a status is cancelled, its "Feed" StatusInstances are removed.)
/// </param>
public StatusInstance(TBaseStatus status, int value = 1, int priority = 0, InstanceType type = InstanceType.Feed, int? overrideSetIndex = null) {
public StatusInstance(TBaseStatus status, int value = 1, int cancelPriority = 0, InstanceType type = InstanceType.Feed, int? overrideSetIndex = null) {
Status = status;
internalValue = value;
CancelPriority = priority;
CancelPriority = cancelPriority;
InstanceType = type;
this.overrideSetIndex = overrideSetIndex;
}
protected StatusInstance(StatusInstance<TObject> copyFrom, int? value = null, int? priority = null, InstanceType? type = null, int? overrideSetIndex = null) {
protected StatusInstance(StatusInstance<TObject> copyFrom, int? value = null, int? cancelPriority = null, InstanceType? type = null, int? overrideSetIndex = null) {
if(copyFrom == null) throw new ArgumentNullException("copyFrom");
Status = copyFrom.Status;
if(value == null) internalValue = copyFrom.internalValue;
else internalValue = value.Value;
if(priority == null) CancelPriority = copyFrom.CancelPriority;
else CancelPriority = priority.Value;
if(cancelPriority == null) CancelPriority = copyFrom.CancelPriority;
else CancelPriority = cancelPriority.Value;
if(type == null) InstanceType = copyFrom.InstanceType;
else InstanceType = type.Value;
if(overrideSetIndex == null) this.overrideSetIndex = copyFrom.overrideSetIndex;
Expand Down
12 changes: 6 additions & 6 deletions Hemlock/StatusSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -548,33 +548,33 @@ public StatusTracker<TObject> CreateStatusTracker(TObject obj) {
/// </summary>
/// <param name="status">The status to which the instance will add its value</param>
/// <param name="value">The amount by which the instance will increase its status</param>
/// <param name="priority">An instance with lower priority will be cancelled before an instance with
/// <param name="cancelPriority">An instance with lower cancel priority will be cancelled before an instance with
/// higher priority when Cancel() is called on this status.</param>
/// <param name="type">
/// The InstanceType determines whether the instance will feed, suppress, or prevent its status.
/// (Feed is the default and most common. When a status is cancelled, its "Feed" StatusInstances are removed.)
/// </param>
public StatusInstance<TObject> CreateStatusInstance(TBaseStatus status, int value = 1, int priority = 0,
public StatusInstance<TObject> CreateStatusInstance(TBaseStatus status, int value = 1, int cancelPriority = 0,
InstanceType type = InstanceType.Feed, int? overrideSetIndex = null)
{
return new StatusInstance<TObject>(status, value, priority, type, overrideSetIndex);
return new StatusInstance<TObject>(status, value, cancelPriority, type, overrideSetIndex);
}
/// <summary>
/// Conveniently create a StatusInstance compatible with all trackers spawned from this object.
/// </summary>
/// <param name="status">The status to which the instance will add its value</param>
/// <param name="value">The amount by which the instance will increase its status</param>
/// <param name="priority">An instance with lower priority will be cancelled before an instance with
/// <param name="cancelPriority">An instance with lower cancel priority will be cancelled before an instance with
/// higher priority when Cancel() is called on this status.</param>
/// <param name="type">
/// The InstanceType determines whether the instance will feed, suppress, or prevent its status.
/// (Feed is the default and most common. When a status is cancelled, its "Feed" StatusInstances are removed.)
/// </param>
public StatusInstance<TObject> CreateStatusInstance<TStatus>(TStatus status, int value = 1, int priority = 0,
public StatusInstance<TObject> CreateStatusInstance<TStatus>(TStatus status, int value = 1, int cancelPriority = 0,
InstanceType type = InstanceType.Feed, int? overrideSetIndex = null)
where TStatus : struct
{
return new StatusInstance<TObject>(Convert(status), value, priority, type, overrideSetIndex);
return new StatusInstance<TObject>(Convert(status), value, cancelPriority, type, overrideSetIndex);
}
protected static TBaseStatus Convert<TStatus>(TStatus status) where TStatus : struct {
try {
Expand Down
53 changes: 20 additions & 33 deletions Hemlock/StatusTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,7 @@ private void SerializeStatusInstances(InstanceType type, System.IO.BinaryWriter
List<StatusInstance<TObject>> values = pair.Value.ToList();
writer.Write(values.Count);
foreach(StatusInstance<TObject> instance in values){
writer.Write(instance.Status);
writer.Write((int)instance.InstanceType);
writer.Write(instance.Value);
writer.Write(instance.CancelPriority);
if(instance.OverrideSetIndex == null){
writer.Write(false);
}
else{
writer.Write(true);
writer.Write(instance.OverrideSetIndex.Value);
}
instance.SerializeInternal(writer);
statusInstanceCallback?.Invoke(writer, instance, this);
}
}
Expand All @@ -191,15 +181,7 @@ private void DeserializeStatusInstances(MultiValueDictionary<TBaseStatus, Status
int key = reader.ReadInt32();
int count = reader.ReadInt32();
for(int j=0;j<count;++j){
int status = reader.ReadInt32();
int type = reader.ReadInt32();
int value = reader.ReadInt32();
int priority = reader.ReadInt32();
int? overrideIdx = null;
if(reader.ReadBoolean()){
overrideIdx = reader.ReadInt32();
}
StatusInstance<TObject> instance = new StatusInstance<TObject>(status, value, priority, (InstanceType)type, overrideIdx);
StatusInstance<TObject> instance = StatusInstance<TObject>.Deserialize(reader);
instance.tracker = this;
dict.Add(key, instance);
statusInstanceCallback?.Invoke(reader, instance, obj);
Expand Down Expand Up @@ -236,33 +218,33 @@ private static void DeserializeInternalFeeds(Dictionary<TBaseStatus, Dictionary<
/// </summary>
/// <param name="status">The status to which the instance will add its value</param>
/// <param name="value">The amount by which the instance will increase its status</param>
/// <param name="priority">An instance with lower priority will be cancelled before an instance with
/// <param name="cancelPriority">An instance with lower cancel priority will be cancelled before an instance with
/// higher priority when Cancel() is called on this status.</param>
/// <param name="type">
/// The InstanceType determines whether the instance will feed, suppress, or prevent its status.
/// (Feed is the default and most common. When a status is cancelled, its "Feed" StatusInstances are removed.)
/// </param>
public StatusInstance<TObject> CreateStatusInstance(TBaseStatus status, int value = 1, int priority = 0,
public StatusInstance<TObject> CreateStatusInstance(TBaseStatus status, int value = 1, int cancelPriority = 0,
InstanceType type = InstanceType.Feed, int? overrideSetIndex = null)
{
return new StatusInstance<TObject>(status, value, priority, type, overrideSetIndex);
return new StatusInstance<TObject>(status, value, cancelPriority, type, overrideSetIndex);
}
/// <summary>
/// Conveniently create a StatusInstance compatible with this tracker. Does not add the StatusInstance to the tracker automatically.
/// </summary>
/// <param name="status">The status to which the instance will add its value</param>
/// <param name="value">The amount by which the instance will increase its status</param>
/// <param name="priority">An instance with lower priority will be cancelled before an instance with
/// <param name="cancelPriority">An instance with lower cancel priority will be cancelled before an instance with
/// higher priority when Cancel() is called on this status.</param>
/// <param name="type">
/// The InstanceType determines whether the instance will feed, suppress, or prevent its status.
/// (Feed is the default and most common. When a status is cancelled, its "Feed" StatusInstances are removed.)
/// </param>
public StatusInstance<TObject> CreateStatusInstance<TStatus>(TStatus status, int value = 1, int priority = 0,
public StatusInstance<TObject> CreateStatusInstance<TStatus>(TStatus status, int value = 1, int cancelPriority = 0,
InstanceType type = InstanceType.Feed, int? overrideSetIndex = null)
where TStatus : struct
{
return new StatusInstance<TObject>(Convert(status), value, priority, type, overrideSetIndex);
return new StatusInstance<TObject>(Convert(status), value, cancelPriority, type, overrideSetIndex);
}
/// <summary>
/// Add a StatusInstance to this tracker, updating the value of the status associated with the given instance.
Expand All @@ -282,7 +264,12 @@ public bool AddStatusInstance(StatusInstance<TObject> instance) {
}
}
}
if(rules.SingleInstance[status]) statusInstances[InstanceType.Feed].Clear(status);
if(rules.SingleInstance[status]) {
foreach(StatusInstance<TObject> removedInstance in statusInstances[InstanceType.Feed][status]) {
removedInstance.tracker = null;
}
statusInstances[InstanceType.Feed].Clear(status);
}
}
if(statusInstances[type].AddUnique(status, instance)) {
instance.tracker = this;
Expand All @@ -297,16 +284,16 @@ public bool AddStatusInstance(StatusInstance<TObject> instance) {
/// </summary>
/// <param name="status">The status to which the instance will add its value</param>
/// <param name="value">The amount by which the instance will increase the given status</param>
/// <param name="priority">An instance with lower priority will be cancelled before an instance with
/// <param name="cancelPriority">An instance with lower cancel priority will be cancelled before an instance with
/// higher priority when Cancel() is called on its status.</param>
/// <param name="type">
/// The InstanceType determines whether the instance will feed, suppress, or prevent its status.
/// (Feed is the default and most common. When a status is cancelled, its "Feed" StatusInstances are removed.)
/// </param>
public StatusInstance<TObject> Add(TBaseStatus status, int value = 1, int priority = 0,
public StatusInstance<TObject> Add(TBaseStatus status, int value = 1, int cancelPriority = 0,
InstanceType type = InstanceType.Feed, int? overrideSetIndex = null)
{
var instance = new StatusInstance<TObject>(status, value, priority, type, overrideSetIndex);
var instance = new StatusInstance<TObject>(status, value, cancelPriority, type, overrideSetIndex);
if(AddStatusInstance(instance)) return instance;
else return null;
}
Expand All @@ -316,17 +303,17 @@ public StatusInstance<TObject> Add(TBaseStatus status, int value = 1, int priori
/// </summary>
/// <param name="status">The status to which the instance will add its value</param>
/// <param name="value">The amount by which the instance will increase the given status</param>
/// <param name="priority">An instance with lower priority will be cancelled before an instance with
/// <param name="cancelPriority">An instance with lower cancel priority will be cancelled before an instance with
/// higher priority when Cancel() is called on its status.</param>
/// <param name="type">
/// The InstanceType determines whether the instance will feed, suppress, or prevent its status.
/// (Feed is the default and most common. When a status is cancelled, its "Feed" StatusInstances are removed.)
/// </param>
public StatusInstance<TObject> Add<TStatus>(TStatus status, int value = 1, int priority = 0,
public StatusInstance<TObject> Add<TStatus>(TStatus status, int value = 1, int cancelPriority = 0,
InstanceType type = InstanceType.Feed, int? overrideSetIndex = null)
where TStatus : struct
{
var instance = new StatusInstance<TObject>(Convert(status), value, priority, type, overrideSetIndex);
var instance = new StatusInstance<TObject>(Convert(status), value, cancelPriority, type, overrideSetIndex);
if(AddStatusInstance(instance)) return instance;
else return null;
}
Expand Down
29 changes: 27 additions & 2 deletions HemlockTests/StatusSystemTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ [TestCase] public void CancelsPriority() {
var s = new StatusInstance<TestObj>[4];
for(int i=0;i<4;++i) {
int ii = i;
s[i] = new StatusInstance<TestObj>((int)TestStatus.A, priority: ii*ii, overrideSetIndex: i); //0, 1, 4, & 9 priority
s[i] = new StatusInstance<TestObj>((int)TestStatus.A, cancelPriority: ii*ii, overrideSetIndex: i); //0, 1, 4, & 9 priority

rules.GetOverrideSet(i).Overrides(TestStatus.A).Messages.Decreased = (obj, st, ov, nv) => {
message = $"Status A is no longer true: Instance {ii}";
Expand Down Expand Up @@ -610,7 +610,6 @@ [TestCase] public void BytesMatchAfterRoundTrip() {
byte[] bytes;
using(System.IO.MemoryStream stream = new MemoryStream()) {
tracker.Serialize(stream);

bytes = stream.ToArray();
}
StatusTracker<TestObj, TestStatus> tracker2;
Expand All @@ -628,6 +627,32 @@ [TestCase] public void BytesMatchAfterRoundTrip() {
Assert.AreEqual(bytes[i], bytes2[i], $"Byte array differs at index {i}");
}
}
[TestCase] public void SerializingInstanceInTrackerThrows(){
var instanceInTracker = tracker.Add(TestStatus.B);
Assert.Throws<InvalidOperationException>(() => instanceInTracker.Serialize(new MemoryStream()));
}
[TestCase] public void LoneStatusInstance(){
StatusInstance<TestObj> instance = tracker.CreateStatusInstance(TestStatus.C, value: 6, cancelPriority: 3, type: InstanceType.Prevent, overrideSetIndex: -2);
byte[] bytes;
using(System.IO.MemoryStream stream = new MemoryStream()) {
instance.Serialize(stream);
bytes = stream.ToArray();
}
StatusInstance<TestObj> instance2;
using(System.IO.MemoryStream stream = new MemoryStream(bytes)) {
instance2 = StatusInstance<TestObj>.Deserialize(stream);
}
byte[] bytes2;
using(System.IO.MemoryStream stream = new MemoryStream()) {
instance2.Serialize(stream);
bytes2 = stream.ToArray();
}
Assert.AreEqual(bytes.Length, bytes2.Length, "Byte array lengths did not match");
for(int i=0;i<bytes.Length;++i){
Assert.AreEqual(bytes[i], bytes2[i], $"Byte array differs at index {i}");
}

}
}
}
}
Loading

0 comments on commit 76c7096

Please sign in to comment.