Created CodeWalker.Core

This commit is contained in:
dexyfex
2018-02-24 22:52:58 +11:00
Unverified
parent 947611765e
commit 709bf125ce
33 changed files with 581 additions and 300 deletions
+121
View File
@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace CodeWalker
{
public class Cache<TKey, TVal> where TVal : Cacheable<TKey>
{
public long MaxMemoryUsage = 536870912; //512mb
public long CurrentMemoryUsage = 0;
public double CacheTime = 5.0; //seconds to keep something that's not used
private LinkedList<TVal> loadedList = new LinkedList<TVal>();
private Dictionary<TKey, LinkedListNode<TVal>> loadedListDict = new Dictionary<TKey, LinkedListNode<TVal>>();
public Cache()
{
}
public Cache(long maxMemoryUsage, double cacheTime)
{
MaxMemoryUsage = maxMemoryUsage;
CacheTime = cacheTime;
}
public TVal TryGet(TKey key)
{
LinkedListNode<TVal> lln = null;
if (loadedListDict.TryGetValue(key, out lln))
{
loadedList.Remove(lln);
loadedList.AddLast(lln);
lln.Value.LastUseTime = DateTime.Now;
}
return (lln != null) ? lln.Value : null;
}
public bool TryAdd(TKey key, TVal item)
{
if (item.MemoryUsage == 0)
{
}
item.Key = key;
if (CanAdd())
{
var lln = loadedList.AddLast(item);
loadedListDict.Add(key, lln);
Interlocked.Add(ref CurrentMemoryUsage, item.MemoryUsage);
return true;
}
else
{
//cache full, check the front of the list for oldest..
var oldlln = loadedList.First;
var cachetime = CacheTime;
int iter = 0, maxiter = 2;
while (!CanAdd() && (iter<maxiter))
{
while ((!CanAdd()) && (oldlln != null) && ((DateTime.Now - oldlln.Value.LastUseTime).TotalSeconds > cachetime))
{
Interlocked.Add(ref CurrentMemoryUsage, -oldlln.Value.MemoryUsage);
loadedListDict.Remove(oldlln.Value.Key);
loadedList.Remove(oldlln); //gc should free up memory later..
oldlln.Value = null;
oldlln = null;
//GC.Collect();
oldlln = loadedList.First;
}
cachetime *= 0.5;
iter++;
}
if (CanAdd()) //see if there's enough memory now...
{
var newlln = loadedList.AddLast(item);
loadedListDict.Add(key, newlln);
Interlocked.Add(ref CurrentMemoryUsage, item.MemoryUsage);
return true;
}
else
{
//really shouldn't get here, but it's possible under stress.
}
}
return false;
}
public bool CanAdd()
{
return Interlocked.Read(ref CurrentMemoryUsage) < MaxMemoryUsage;
}
public void Clear()
{
loadedList.Clear();
loadedListDict.Clear();
CurrentMemoryUsage = 0;
}
public void Remove(TKey key)
{
LinkedListNode<TVal> n;
if (loadedListDict.TryGetValue(key, out n))
{
loadedListDict.Remove(key);
loadedList.Remove(n);
CurrentMemoryUsage -= n.Value.MemoryUsage;
}
}
}
public abstract class Cacheable<TKey>
{
public TKey Key;
public DateTime LastUseTime = DateTime.Now;
public long MemoryUsage;
}
}
+42
View File
@@ -0,0 +1,42 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CodeWalker
{
public static class MatrixExtensions
{
public static Vector3 MultiplyW(this Matrix m, Vector3 v)
{
float x = (((m.M11 * v.X) + (m.M21 * v.Y)) + (m.M31 * v.Z)) + m.M41;
float y = (((m.M12 * v.X) + (m.M22 * v.Y)) + (m.M32 * v.Z)) + m.M42;
float z = (((m.M13 * v.X) + (m.M23 * v.Y)) + (m.M33 * v.Z)) + m.M43;
float w = (((m.M14 * v.X) + (m.M24 * v.Y)) + (m.M34 * v.Z)) + m.M44;
float iw = 1.0f / Math.Abs(w);
return new Vector3(x * iw, y * iw, z * iw);
}
public static Vector3 Multiply(this Matrix m, Vector3 v)
{
float x = (((m.M11 * v.X) + (m.M21 * v.Y)) + (m.M31 * v.Z)) + m.M41;
float y = (((m.M12 * v.X) + (m.M22 * v.Y)) + (m.M32 * v.Z)) + m.M42;
float z = (((m.M13 * v.X) + (m.M23 * v.Y)) + (m.M33 * v.Z)) + m.M43;
return new Vector3(x, y, z);
//this quick mul ignores W...
}
public static Vector4 Multiply(this Matrix m, Vector4 v)
{
float x = (((m.M11 * v.X) + (m.M21 * v.Y)) + (m.M31 * v.Z)) + m.M41;
float y = (((m.M12 * v.X) + (m.M22 * v.Y)) + (m.M32 * v.Z)) + m.M42;
float z = (((m.M13 * v.X) + (m.M23 * v.Y)) + (m.M33 * v.Z)) + m.M43;
float w = (((m.M14 * v.X) + (m.M24 * v.Y)) + (m.M34 * v.Z)) + m.M44;
return new Vector4(x, y, z, w);
}
}
}
+74
View File
@@ -0,0 +1,74 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CodeWalker
{
public static class QuaternionExtension
{
public static Vector3 Multiply(this Quaternion a, Vector3 b)
{
float axx = a.X * 2.0f;
float ayy = a.Y * 2.0f;
float azz = a.Z * 2.0f;
float awxx = a.W * axx;
float awyy = a.W * ayy;
float awzz = a.W * azz;
float axxx = a.X * axx;
float axyy = a.X * ayy;
float axzz = a.X * azz;
float ayyy = a.Y * ayy;
float ayzz = a.Y * azz;
float azzz = a.Z * azz;
return new Vector3(((b.X * ((1.0f - ayyy) - azzz)) + (b.Y * (axyy - awzz))) + (b.Z * (axzz + awyy)),
((b.X * (axyy + awzz)) + (b.Y * ((1.0f - axxx) - azzz))) + (b.Z * (ayzz - awxx)),
((b.X * (axzz - awyy)) + (b.Y * (ayzz + awxx))) + (b.Z * ((1.0f - axxx) - ayyy)));
}
public static Matrix ToMatrix(this Quaternion q)
{
float xx = q.X * q.X;
float yy = q.Y * q.Y;
float zz = q.Z * q.Z;
float xy = q.X * q.Y;
float zw = q.Z * q.W;
float zx = q.Z * q.X;
float yw = q.Y * q.W;
float yz = q.Y * q.Z;
float xw = q.X * q.W;
Matrix result = new Matrix();
result.M11 = 1.0f - (2.0f * (yy + zz));
result.M12 = 2.0f * (xy + zw);
result.M13 = 2.0f * (zx - yw);
result.M14 = 0.0f;
result.M21 = 2.0f * (xy - zw);
result.M22 = 1.0f - (2.0f * (zz + xx));
result.M23 = 2.0f * (yz + xw);
result.M24 = 0.0f;
result.M31 = 2.0f * (zx + yw);
result.M32 = 2.0f * (yz - xw);
result.M33 = 1.0f - (2.0f * (yy + xx));
result.M34 = 0.0f;
result.M41 = 0.0f;
result.M42 = 0.0f;
result.M43 = 0.0f;
result.M44 = 1.0f;
return result;
}
public static Vector4 ToVector4(this Quaternion q)
{
return new Vector4(q.X, q.Y, q.Z, q.W);
}
}
}
+197
View File
@@ -0,0 +1,197 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace CodeWalker
{
public static class TextUtil
{
public static string GetBytesReadable(long i)
{
//shamelessly stolen from stackoverflow, and a bit mangled
// Returns the human-readable file size for an arbitrary, 64-bit file size
// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"
// Get absolute value
long absolute_i = (i < 0 ? -i : i);
// Determine the suffix and readable value
string suffix;
double readable;
if (absolute_i >= 0x1000000000000000) // Exabyte
{
suffix = "EB";
readable = (i >> 50);
}
else if (absolute_i >= 0x4000000000000) // Petabyte
{
suffix = "PB";
readable = (i >> 40);
}
else if (absolute_i >= 0x10000000000) // Terabyte
{
suffix = "TB";
readable = (i >> 30);
}
else if (absolute_i >= 0x40000000) // Gigabyte
{
suffix = "GB";
readable = (i >> 20);
}
else if (absolute_i >= 0x100000) // Megabyte
{
suffix = "MB";
readable = (i >> 10);
}
else if (absolute_i >= 0x400) // Kilobyte
{
suffix = "KB";
readable = i;
}
else
{
return i.ToString("0 bytes"); // Byte
}
// Divide by 1024 to get fractional value
readable = (readable / 1024);
string fmt = "0.### ";
if (readable > 1000)
{
fmt = "0";
}
else if (readable > 100)
{
fmt = "0.#";
}
else if (readable > 10)
{
fmt = "0.##";
}
// Return formatted number with suffix
return readable.ToString(fmt) + suffix;
}
}
public static class FloatUtil
{
public static bool TryParse(string s, out float f)
{
f = 0.0f;
if (float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out f))
{
return true;
}
return false;
}
public static float Parse(string s)
{
float f;
TryParse(s, out f);
return f;
}
public static string ToString(float f)
{
var c = CultureInfo.InvariantCulture;
return f.ToString(c);
}
public static string GetVector2String(Vector2 v)
{
var c = CultureInfo.InvariantCulture;
return v.X.ToString(c) + ", " + v.Y.ToString(c);
}
public static string GetVector3String(Vector3 v)
{
var c = CultureInfo.InvariantCulture;
return v.X.ToString(c) + ", " + v.Y.ToString(c) + ", " + v.Z.ToString(c);
}
public static string GetVector3String(Vector3 v, string format)
{
var c = CultureInfo.InvariantCulture;
return v.X.ToString(format, c) + ", " + v.Y.ToString(format, c) + ", " + v.Z.ToString(format, c);
}
public static string GetVector3XmlString(Vector3 v)
{
var c = CultureInfo.InvariantCulture;
return string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\"", v.X.ToString(c), v.Y.ToString(c), v.Z.ToString(c));
}
public static string GetVector4XmlString(Vector4 v)
{
var c = CultureInfo.InvariantCulture;
return string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\" w=\"{3}\"", v.X.ToString(c), v.Y.ToString(c), v.Z.ToString(c), v.W.ToString(c));
}
public static string GetQuaternionXmlString(Quaternion q)
{
var c = CultureInfo.InvariantCulture;
return string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\" w=\"{3}\"", q.X.ToString(c), q.Y.ToString(c), q.Z.ToString(c), q.W.ToString(c));
}
public static Vector3 ParseVector3String(string s)
{
Vector3 p = new Vector3(0.0f);
string[] ss = s.Split(',');
if (ss.Length > 0)
{
FloatUtil.TryParse(ss[0].Trim(), out p.X);
}
if (ss.Length > 1)
{
FloatUtil.TryParse(ss[1].Trim(), out p.Y);
}
if (ss.Length > 2)
{
FloatUtil.TryParse(ss[2].Trim(), out p.Z);
}
return p;
}
public static string GetVector4String(Vector4 v)
{
var c = CultureInfo.InvariantCulture;
return v.X.ToString(c) + ", " + v.Y.ToString(c) + ", " + v.Z.ToString(c) + ", " + v.W.ToString(c);
}
public static Vector4 ParseVector4String(string s)
{
Vector4 p = new Vector4(0.0f);
string[] ss = s.Split(',');
if (ss.Length > 0)
{
FloatUtil.TryParse(ss[0].Trim(), out p.X);
}
if (ss.Length > 1)
{
FloatUtil.TryParse(ss[1].Trim(), out p.Y);
}
if (ss.Length > 2)
{
FloatUtil.TryParse(ss[2].Trim(), out p.Z);
}
if (ss.Length > 3)
{
FloatUtil.TryParse(ss[3].Trim(), out p.W);
}
return p;
}
}
}
+60
View File
@@ -0,0 +1,60 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CodeWalker
{
public static class Vectors
{
public static Vector3 XYZ(this Vector4 v)
{
return new Vector3(v.X, v.Y, v.Z);
}
public static Vector4 Floor(this Vector4 v)
{
return new Vector4((float)Math.Floor(v.X), (float)Math.Floor(v.Y), (float)Math.Floor(v.Z), (float)Math.Floor(v.W));
}
}
public struct Vector2I
{
public int X;
public int Y;
public Vector2I(int x, int y)
{
X = x;
Y = y;
}
public Vector2I(Vector2 v)
{
X = (int)Math.Floor(v.X);
Y = (int)Math.Floor(v.Y);
}
public override string ToString()
{
return X.ToString() + ", " + Y.ToString();
}
public static Vector2I operator +(Vector2I a, Vector2I b)
{
return new Vector2I(a.X + b.X, a.Y + b.Y);
}
public static Vector2I operator -(Vector2I a, Vector2I b)
{
return new Vector2I(a.X - b.X, a.Y - b.Y);
}
}
}
+137
View File
@@ -0,0 +1,137 @@
using SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace CodeWalker
{
public static class Xml
{
public static string GetStringAttribute(XmlNode node, string attribute)
{
if (node == null) return null;
return node.Attributes[attribute]?.InnerText;
}
public static bool GetBoolAttribute(XmlNode node, string attribute)
{
if (node == null) return false;
string val = node.Attributes[attribute]?.InnerText;
bool b;
bool.TryParse(val, out b);
return b;
}
public static int GetIntAttribute(XmlNode node, string attribute)
{
if (node == null) return 0;
string val = node.Attributes[attribute]?.InnerText;
int i;
int.TryParse(val, out i);
return i;
}
public static float GetFloatAttribute(XmlNode node, string attribute)
{
if (node == null) return 0;
string val = node.Attributes[attribute]?.InnerText;
float f;
FloatUtil.TryParse(val, out f);
return f;
}
public static string GetChildInnerText(XmlNode node, string name)
{
if (node == null) return null;
return node.SelectSingleNode(name)?.InnerText;
}
public static bool GetChildBoolInnerText(XmlNode node, string name)
{
if (node == null) return false;
string val = node.SelectSingleNode(name)?.InnerText;
bool b;
bool.TryParse(val, out b);
return b;
}
public static int GetChildIntInnerText(XmlNode node, string name)
{
if (node == null) return 0;
string val = node.SelectSingleNode(name)?.InnerText;
int i;
int.TryParse(val, out i);
return i;
}
public static float GetChildFloatInnerText(XmlNode node, string name)
{
if (node == null) return 0;
string val = node.SelectSingleNode(name)?.InnerText;
float f;
FloatUtil.TryParse(val, out f);
return f;
}
public static bool GetChildBoolAttribute(XmlNode node, string name, string attribute)
{
if (node == null) return false;
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
bool b;
bool.TryParse(val, out b);
return b;
}
public static int GetChildIntAttribute(XmlNode node, string name, string attribute)
{
if (node == null) return 0;
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
int i;
int.TryParse(val, out i);
return i;
}
public static float GetChildFloatAttribute(XmlNode node, string name, string attribute)
{
if (node == null) return 0;
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
float f;
FloatUtil.TryParse(val, out f);
return f;
}
public static string GetChildStringAttribute(XmlNode node, string name, string attribute)
{
if (node == null) return string.Empty;
string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
return val;
}
public static Vector3 GetChildVector3Attributes(XmlNode node, string name, string x, string y, string z)
{
float fx = GetChildFloatAttribute(node, name, x);
float fy = GetChildFloatAttribute(node, name, y);
float fz = GetChildFloatAttribute(node, name, z);
return new Vector3(fx, fy, fz);
}
public static XmlElement GetChild(XmlElement element, string name)
{
return element.SelectSingleNode(name) as XmlElement;
}
public static XmlElement AddChild(XmlDocument doc, XmlNode node, string name)
{
XmlElement child = doc.CreateElement(name);
node.AppendChild(child);
return child;
}
public static XmlElement AddChildWithInnerText(XmlDocument doc, XmlNode node, string name, string innerText)
{
XmlElement child = AddChild(doc, node, name);
child.InnerText = innerText;
return child;
}
public static XmlElement AddChildWithAttribute(XmlDocument doc, XmlNode node, string name, string attributeName, string attributeValue)
{
XmlElement child = AddChild(doc, node, name);
child.SetAttribute(attributeName, attributeValue);
return child;
}
}
}