[ProtoMember(1)]
public Vec2i Location;
+ [ProtoIgnore]
[DisplayName(0, "Coords.")]
public string PrettyLocation;
[ProtoMember(2)]
public TimeSpan ChunkAge;//OLDEST CHUNK. from chunk last edit
- [DisplayName(1, "Age")]
- public string ShortChunkAge { get => ChunkAge.ToString("c"); }
+ //[DisplayName(1, "Age")]
+ //public string ShortChunkAge { get => ChunkAge.ToString("c"); }
[ProtoMember(3)]
[DisplayName(2, "Temp.")]
[DisplayName(3, "Y Max.")]
public ushort YMax;// Y feature height
- [ProtoMember(5)]
- public Dictionary<int, uint> RockRatio;//[Column] Geographic region (rock) Ratio. [BlockID * count]
+ //[ProtoMember(5)]
+ //public Dictionary<int, uint> RockRatio;//[Column] Geographic region (rock) Ratio. [BlockID * count]
//[DisplayName(10, "Rocks")]
//public JArray FlatRocks
public byte ChunkSize;
- [ProtoIgnore]
- public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization
+ //[ProtoIgnore]
+ //public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization
- [ProtoMember(13)]
- private ushort[] _flattened_HeightMap;
+ //[ProtoMember(13)]
+ //private ushort[] _flattened_HeightMap;
public ColumnMeta(Vec2i loc, ICoreClientAPI clientAPI, byte chunkSize = 32)
{
ChunkAge = TimeSpan.Zero;
Temperature = 0f;
YMax = 0;
- RockRatio = new Dictionary<int, uint>(10);
+ //RockRatio = new Dictionary<int, uint>(10);
Fertility = 0f;
ForestDensity = 0f;
Rainfall = 0f;
AirBlocks = 0;
NonAirBlocks = 0;
ChunkSize = chunkSize;
- HeightMap = new ushort[ChunkSize, ChunkSize];
- _flattened_HeightMap = null;
+ //HeightMap = new ushort[ChunkSize, ChunkSize];
+ //_flattened_HeightMap = null;
}
internal void UpdateFieldsFrom(ClimateCondition climate, IMapChunk mapChunk, TimeSpan chunkAge)
private void PrepareData()
{
- if (HeightMap != null)
- {
- _flattened_HeightMap = new ushort[ChunkSize * ChunkSize];
- int flatIndex = 0;
-
- for (byte col = 0; col < ChunkSize; col++)
- {
- for (byte row = 0; row < ChunkSize; row++)
- {
- _flattened_HeightMap[flatIndex] = HeightMap[col, row];
- flatIndex++;
- }
- }
+ //if (HeightMap != null)
+ //{
+ // _flattened_HeightMap = new ushort[ChunkSize * ChunkSize];
+ // int flatIndex = 0;
- }
+ // for (byte col = 0; col < ChunkSize; col++)
+ // {
+ // for (byte row = 0; row < ChunkSize; row++)
+ // {
+ // _flattened_HeightMap[flatIndex] = HeightMap[col, row];
+ // flatIndex++;
+ // }
+ // }
+
+ //}
}
[ProtoAfterDeserialization]
private void PostProcess()
{
- ChunkSize = (ChunkSize == byte.MinValue) ? (byte)32 : ChunkSize;//Not good - if chunk wasn't 32 orignally!
+ //if (this.HeightMap == null) this.HeightMap = new ushort[ChunkSize, ChunkSize];
- if (this.HeightMap == null || this.HeightMap.Length != (ChunkSize * ChunkSize)) {
- this.HeightMap = new ushort[ChunkSize, ChunkSize];
- }
+ //if (_flattened_HeightMap != null)
+ //{
+ // int col, row;
+ // _ = new BitVector32(0);
+ // var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1));
+ // var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection);
- if (_flattened_HeightMap != null)
- {
- int col, row;
- var bitMasker = new BitVector32(0);
- var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1));
- var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection);
-
- for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++)
- {
- bitMasker = new BitVector32(data: (int) rowcol);
- row = bitMasker[rowSection];
- col = bitMasker[colSection];
- HeightMap[col, row] = _flattened_HeightMap[rowcol];
- }
+ // for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++)
+ // {
+ // BitVector32 bitMasker = new BitVector32(data: (int) rowcol);
+ // row = bitMasker[rowSection];
+ // col = bitMasker[colSection];
+ // HeightMap[col, row] = _flattened_HeightMap[rowcol];
+ // }
- }
+ //}
}
-
internal ColumnMeta Reload(ICoreClientAPI clientAPI)
{
this.PrettyLocation = Location.PrettyCoords(clientAPI);
- Console.Write(PrettyLocation == null ? "*" : ",");
return this;
}
}
}
public new void Add(ColumnMeta newItem)
- {
+ { // south and east are positive
if (North_mostChunk > newItem.Location.Y)
- {
North_mostChunk = newItem.Location.Y;
- }
if (South_mostChunk < newItem.Location.Y)
- {
South_mostChunk = newItem.Location.Y;
- }
if (East_mostChunk < newItem.Location.X)
- {
East_mostChunk = newItem.Location.X;
- }
if (West_mostChunk > newItem.Location.X)
- {
West_mostChunk = newItem.Location.X;
- }
base.Add(newItem);
}
- public void ClearMetadata( )
+ public void ClearMetadata()
{
- for (int i = 0, maxItemsCount = this.Items.Count; i < maxItemsCount; i++) {
- ColumnMeta entry = this.Items[i];
- entry.HeightMap = null;
- entry.RockRatio = null;//Also regenerated when any chunk in a column is changed...
- }
+ for (int i = 0, maxItemsCount = this.Items.Count; i < maxItemsCount; i++)
+ {
+ ColumnMeta entry = this.Items[i];
+ //entry.HeightMap = null;
+ //entry.RockRatio = null;//Also regenerated when any chunk in a column is changed...
+ }
}
}
StringBuilder textTarget = new StringBuilder();
//translocatorEntity.GetBlockInfo(clientAPI.World.Player, textTarget);
- textTarget.Append(te.Activated ? "Online " : "offline ");
+ textTarget.Append(te.Activated ? "Online " : "Offline ");
textTarget.Append(" Dest.: ");
- textTarget.Append(te.TargetLocation != null ? te.TargetLocation.PrettyCoords(clientAPI) : "???");//Or ABS coords?
+ textTarget.Append(te.TargetLocation != null ? te.TargetLocation.ToString() : "???");//Or ABS coords?
poi.AddReplace(
new PointOfInterest
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
-
+using System.Reflection;
using Hjg.Pngcs.Chunks;
using Vintagestory.API.Client;
//Chunk masked
return ((blockPos.Y & 31) * 32 + (blockPos.Z & 31)) * 32 + (blockPos.X & 31);
}
+
+ internal static object GetValue(MemberInfo member, object property)
+ { // copied from https://stackoverflow.com/questions/12680341/how-to-get-both-fields-and-properties-in-single-call-via-reflection
+ if (member.MemberType == MemberTypes.Property)
+ return ((PropertyInfo) member).GetValue(property, null);
+ else if (member.MemberType == MemberTypes.Field)
+ return ((FieldInfo) member).GetValue(property);
+ else
+ throw new Exception("Property must be of type FieldInfo or PropertyInfo");
+ }
+
+ internal static bool IsFloatingType(object o)
+ {
+ if (o == null) return false;
+ switch (Type.GetTypeCode(o.GetType()))
+ {
+ case TypeCode.Decimal:
+ case TypeCode.Double:
+ case TypeCode.Single:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ internal static bool IsIntegralType(object o)
+ {
+ if (o == null) return false;
+ switch (Type.GetTypeCode(o.GetType()))
+ {
+ case TypeCode.Byte:
+ case TypeCode.SByte:
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ case TypeCode.UInt64:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ case TypeCode.Int64:
+ return true;
+ default:
+ return false;
+ }
+ }
}
}
private ILogger Logger { get; set; }
private string Path { get; set; }
private readonly int chunkSize;
+ private Dictionary<Vec2i, string> memoizedChunks = new Dictionary<Vec2i, string>();
internal JArray ColumnMeta_Names, PointsOfInterest_Names, EntitiesOfInterest_Names;
internal MemberInfo[] ColumnMeta_Vals, PointsOfInterest_Vals, EntitiesOfInterest_Vals;
jsonWriter.QuoteChar = '\'';
jsonWriter.DateFormatHandling = DateFormatHandling.IsoDateFormat;
jsonWriter.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
-
+ var stringWriter = new StringWriter();
+ JsonTextWriter memoizer = new JsonTextWriter(stringWriter);
+ memoizer.Formatting = Formatting.None;
+ memoizer.StringEscapeHandling = StringEscapeHandling.EscapeHtml;
+ memoizer.Indentation = 0;
+ memoizer.QuoteChar = '\'';
+ memoizer.DateFormatHandling = DateFormatHandling.IsoDateFormat;
+ memoizer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
using (jsonWriter)
{
jsonWriter.WriteRaw("ViewFrame.chunks=");
//MAP object format - [key, value]: key is "x_y"
jsonWriter.WriteMapForeach("chunkMetadata", chunkTopMetadata, (shard) =>
{
- //Console.WriteLine($"188 {chunkTopMetadata.Count}");
- jsonWriter.WriteMapTupleForeach(
- $"{shard.Location.X}_{shard.Location.Y}",
- ColumnMeta_Vals,
- (mem) =>
+ // check if it needs to be made!
+ if (!memoizedChunks.ContainsKey(shard.Location))
+ {
+ memoizer.WriteStartArray();
+ foreach (var mem in ColumnMeta_Vals)
{
- var val = GetValue(mem, shard);
- if (IsFloatingType(val))
- jsonWriter.WriteValue($"{val:F3}");
- else if (IsIntegralType(val))
- jsonWriter.WriteValue($"{val}");
+ var val = Helpers.GetValue(mem, shard);
+ if (Helpers.IsFloatingType(val))
+ memoizer.WriteValue($"{val:F3}");
+ else if (Helpers.IsIntegralType(val))
+ memoizer.WriteValue($"{val}");
else
- jsonWriter.WriteValue(val);
+ memoizer.WriteValue(val);
}
- );
+ memoizer.WriteEndArray();
+ memoizedChunks.Add(shard.Location, stringWriter.ToString());
+ stringWriter.GetStringBuilder().Clear();
+ }
+ jsonWriter.WriteRawMapTuple(
+ $"{shard.Location.X}_{shard.Location.Y}",
+ memoizedChunks[shard.Location]
+ );
});
#if DEBUG
jsonWriter.WriteWhitespace("\n");
$"{poi.Location.X}_{poi.Location.Z}",
PointsOfInterest_Vals,
(mem) => {
- var dasField = GetValue(mem, poi);
+ var dasField = Helpers.GetValue(mem, poi);
jsonWriter.WriteRawValue(JsonConvert.SerializeObject(dasField));
}
);
jsonWriter.WriteMapTupleForeach(
$"{poi.Location.X}_{poi.Location.Z}",
EntitiesOfInterest_Vals,
- (el) => jsonWriter.WriteValue(GetValue(el, poi))
+ (el) => jsonWriter.WriteValue(Helpers.GetValue(el, poi))
);
});
#if DEBUG
return memberVals.OrderBy(kf => kf.Key).Select(kf => kf.Value).ToArray();
}
- internal static object GetValue(MemberInfo member, object property)
- { // copied from https://stackoverflow.com/questions/12680341/how-to-get-both-fields-and-properties-in-single-call-via-reflection
- if (member.MemberType == MemberTypes.Property)
- return ((PropertyInfo) member).GetValue(property, null);
- else if (member.MemberType == MemberTypes.Field)
- return ((FieldInfo) member).GetValue(property);
- else
- throw new Exception("Property must be of type FieldInfo or PropertyInfo");
- }
- internal static bool IsFloatingType(object o)
- {
- if (o == null) return false;
- switch (Type.GetTypeCode(o.GetType()))
- {
- case TypeCode.Decimal:
- case TypeCode.Double:
- case TypeCode.Single:
- return true;
- default:
- return false;
- }
- }
-
- internal static bool IsIntegralType(object o)
- {
- if (o == null) return false;
- switch (Type.GetTypeCode(o.GetType()))
- {
- case TypeCode.Byte:
- case TypeCode.SByte:
- case TypeCode.UInt16:
- case TypeCode.UInt32:
- case TypeCode.UInt64:
- case TypeCode.Int16:
- case TypeCode.Int32:
- case TypeCode.Int64:
- return true;
- default:
- return false;
- }
- }
}
public static class JsonWriterExtentions
{
-
+
/// <summary>
- /// Writes an array in the form of key: [...ar] by calling .ToString() on all elements in ar.
+ /// Writes an array in the form of key: [...ar].
/// </summary>
/// <param name="writer"></param>
/// <param name="key"></param>
}
/// <summary>
+ /// Writes a Map tuple in the form of [key, value]. Identical to WriteMapTuple but uses .WriteRawValue
+ /// </summary>
+ /// <param name="writer"></param>
+ /// <param name="key"></param>
+ /// <param name="value"></param>
+ public static void WriteRawMapTuple(this JsonTextWriter writer, string key, string value)
+ {
+ writer.WriteStartArray();
+ writer.WriteValue(key);
+ writer.WriteRawValue(value);
+ writer.WriteEndArray();
+ }
+
+ /// <summary>
/// Writes a Map tuple in the form of [key, [val, val]]. Where each val is given by the passed function.
/// </summary>
/// <param name="writer"></param>