mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2026-05-14 21:53:49 +08:00
Created CodeWalker.Core
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user