Initial stuff
This commit is contained in:
parent
7c64f0a2b5
commit
46b76f68ed
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
###################################
|
||||
# Git ignore file for Molyjam2012 #
|
||||
###################################
|
||||
|
||||
#Folders
|
||||
Library/
|
||||
Temp/
|
||||
Builds/
|
||||
Libraries/
|
||||
Debug/
|
||||
Release/
|
||||
run/
|
||||
bin/
|
||||
obj/
|
||||
|
||||
#Project/User Preference Files
|
||||
*.csproj
|
||||
*.pidb
|
||||
*.userprefs
|
||||
*.user
|
||||
*.suo
|
||||
|
||||
#OS Junk
|
||||
Thumbs.db
|
||||
.DS_Store*
|
||||
ehthumbs.db
|
||||
Icon7
|
||||
|
||||
|
||||
|
||||
#*.sln
|
||||
52
Clock.cs
Normal file
52
Clock.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
public class Clock
|
||||
{
|
||||
public Clock( long timeOffset )
|
||||
{
|
||||
m_timer = new Timer();
|
||||
|
||||
m_lastTime = m_timer.Current;
|
||||
|
||||
m_totalMillis = timeOffset;
|
||||
m_totalSeconds= (double)m_totalMillis / 1000.0;
|
||||
}
|
||||
|
||||
public void tick()
|
||||
{
|
||||
long current = m_timer.Current;
|
||||
|
||||
m_dtMillis = (int)(current - m_lastTime);
|
||||
|
||||
m_dtSeconds = (double)m_dtMillis / 1000.0;
|
||||
|
||||
m_totalMillis += m_dtMillis;
|
||||
m_totalSeconds = (double)m_totalMillis / 1000.0;
|
||||
|
||||
m_lastTime = current;
|
||||
}
|
||||
|
||||
public int dtMs { get { return m_dtMillis; } }
|
||||
public double dtSec { get { return m_dtSeconds; } }
|
||||
|
||||
public long ms { get { return m_totalMillis; } }
|
||||
public double sec{ get { return m_totalSeconds; } }
|
||||
|
||||
|
||||
Timer m_timer;
|
||||
|
||||
long m_lastTime = 0;
|
||||
|
||||
int m_dtMillis = 0;
|
||||
double m_dtSeconds = 0;
|
||||
|
||||
long m_totalMillis = 0;
|
||||
double m_totalSeconds = 0;
|
||||
|
||||
}
|
||||
}
|
||||
158
Config.cs
Normal file
158
Config.cs
Normal file
@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Reflection;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
public class ResRefConfig<T> : res.Ref<T> where T: Config
|
||||
{
|
||||
public ResRefConfig()
|
||||
{
|
||||
}
|
||||
|
||||
public ResRefConfig( string filename, T cfg )
|
||||
: base( filename, cfg )
|
||||
{
|
||||
}
|
||||
|
||||
override public void OnDeserialize( object enclosing )
|
||||
{
|
||||
base.OnDeserialize( enclosing );
|
||||
|
||||
var cfg = Config.load<T>( filename );
|
||||
|
||||
res = cfg;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Config
|
||||
{
|
||||
/*
|
||||
static public Config Load( string filename )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
static public void startup()
|
||||
{
|
||||
res.Mgr.register<Config>( res_load );
|
||||
res.Mgr.registerSub<Config>( res_load );
|
||||
}
|
||||
|
||||
|
||||
#region SaveLoad
|
||||
static public ResRefConfig<Config> res_load( string filename )
|
||||
{
|
||||
return new ResRefConfig<Config>( filename, load( filename ) );
|
||||
}
|
||||
|
||||
static public ResRefConfig<T> res_load<T>( string filename ) where T : Config
|
||||
{
|
||||
return new ResRefConfig<T>( filename, load<T>( filename ) );
|
||||
}
|
||||
|
||||
/*
|
||||
static public ResRefConfig res_load( string filename, Type t )
|
||||
{
|
||||
return new ResRefConfig( filename, load( filename, t ) );
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
static public Config load( string filename )
|
||||
{
|
||||
FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read );
|
||||
|
||||
XmlFormatter2 formatter = new XmlFormatter2();
|
||||
|
||||
Config cfg = (Config)formatter.Deserialize( fs );
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static public T load<T>( string filename ) where T : Config
|
||||
{
|
||||
return (T)load( filename, typeof( T ) );
|
||||
}
|
||||
|
||||
static public Config load( string filename, Type t )
|
||||
{
|
||||
Config cfg = null;
|
||||
|
||||
try
|
||||
{
|
||||
FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read );
|
||||
|
||||
XmlFormatter2 formatter = new XmlFormatter2();
|
||||
|
||||
cfg = (Config)( t != null ? formatter.DeserializeKnownType( fs,t ) : formatter.Deserialize( fs ) );
|
||||
|
||||
cfg.SetFilename( filename );
|
||||
}
|
||||
catch( FileNotFoundException )
|
||||
{
|
||||
Type[] types = new Type[ 0 ];
|
||||
object[] parms = new object[ 0 ];
|
||||
|
||||
//types[ 0 ] = typeof( string );
|
||||
//parms[ 0 ] = filename;
|
||||
|
||||
ConstructorInfo cons = t.GetConstructor( types );
|
||||
|
||||
try
|
||||
{
|
||||
cfg = (Config)cons.Invoke( parms );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Log.error( "Caught exception {0}", e );
|
||||
}
|
||||
|
||||
cfg.SetFilename( filename );
|
||||
|
||||
Config.save( cfg, filename );
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static public void save( Config cfg )
|
||||
{
|
||||
Config.save( cfg, cfg.m_filename );
|
||||
}
|
||||
|
||||
static public void save( Config cfg, String filename )
|
||||
{
|
||||
FileStream fs = new FileStream( filename, FileMode.Create, FileAccess.Write );
|
||||
|
||||
XmlFormatter2 formatter = new XmlFormatter2();
|
||||
|
||||
formatter.Serialize( fs, cfg );
|
||||
|
||||
fs.Close();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private string m_filename = "";
|
||||
|
||||
public Config()
|
||||
{
|
||||
}
|
||||
|
||||
public Config( string filename )
|
||||
{
|
||||
m_filename = filename;
|
||||
}
|
||||
|
||||
public String Filename { get { return m_filename; } }
|
||||
|
||||
protected void SetFilename( String filename ) { m_filename = filename; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
106
Conn.cs
Normal file
106
Conn.cs
Normal file
@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Net.Sockets;
|
||||
using System.IO;
|
||||
|
||||
//using Util;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
|
||||
|
||||
|
||||
public class Conn
|
||||
{
|
||||
public Socket Sock { get { return m_socket; } }
|
||||
public Stream Stream { get { return m_streamNet; } }
|
||||
public IFormatter Formatter { get { return m_formatter; } }
|
||||
|
||||
|
||||
public Conn( Socket sock, IFormatter formatter )
|
||||
{
|
||||
m_socket = sock;
|
||||
|
||||
//sock.DontFragment = true;
|
||||
sock.NoDelay = true;
|
||||
|
||||
m_streamNet = new NetworkStream( m_socket );
|
||||
//m_streamBufIn = new BufferedStream( m_streamNet );
|
||||
|
||||
m_formatter = formatter;
|
||||
//m_formatter = new VersionFormatter();
|
||||
|
||||
//mm_memStream = new MemoryStream( mm_buffer );
|
||||
|
||||
|
||||
}
|
||||
|
||||
public object recieveObject()
|
||||
{
|
||||
return recieveObject( Stream );
|
||||
}
|
||||
|
||||
public object recieveObject( Stream stream )
|
||||
{
|
||||
object obj = null;
|
||||
lock( this )
|
||||
{
|
||||
try
|
||||
{
|
||||
obj = m_formatter.Deserialize( stream );
|
||||
}
|
||||
catch( System.Xml.XmlException e )
|
||||
{
|
||||
lib.Log.error( "Outer Exception {0}", e.ToString() );
|
||||
//lib.Log.error( "Inner Exception {0}", e.InnerException.ToString() );
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void send( object obj )
|
||||
{
|
||||
lock( this )
|
||||
{
|
||||
try
|
||||
{
|
||||
var ms = new MemoryStream( 1024 );
|
||||
m_formatter.Serialize( ms, obj );
|
||||
|
||||
//var str = System.Text.Encoding.Default.GetString( mm_buffer, 0, (int)ms.Position );
|
||||
//lib.Log.info( "Sent data {0} of length {1}", str, ms.Position );
|
||||
|
||||
byte[] byteSize = BitConverter.GetBytes( (uint)ms.Position );
|
||||
m_streamNet.Write( byteSize, 0, 4 );
|
||||
m_streamNet.Write( ms.GetBuffer(), 0, (int)ms.Position );
|
||||
|
||||
m_streamNet.Flush();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
//m_streamNet.Close();
|
||||
//m_socket.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void recieve( object obj )
|
||||
{
|
||||
//Log.log.msg( "Recieved " + obj.ToString() );
|
||||
}
|
||||
|
||||
private Socket m_socket;
|
||||
|
||||
private NetworkStream m_streamNet;
|
||||
//private BufferedStream m_streamBufIn;
|
||||
//private BufferedStream m_streamBufOut;
|
||||
|
||||
private IFormatter m_formatter;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
179
Helpers.cs
Normal file
179
Helpers.cs
Normal file
@ -0,0 +1,179 @@
|
||||
|
||||
/*
|
||||
* TODO: Need to verify types are correct when deserializing.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
public class Helpers
|
||||
{
|
||||
public void XmlSave( String filename, Object obj )
|
||||
{
|
||||
FileStream fs = new FileStream( filename, FileMode.Create, FileAccess.Write );
|
||||
|
||||
XmlSerializer xs = new XmlSerializer( obj.GetType() );
|
||||
//MemoryStream memoryStream = new MemoryStream( StringToUTF8ByteArray( pXmlizedString ) );
|
||||
//XmlTextReader reader = new XmlTextReader( fs, Encoding.UTF8 );
|
||||
|
||||
xs.Serialize( fs, obj );
|
||||
}
|
||||
|
||||
public Object XmlLoad<TType>( String filename )
|
||||
{
|
||||
FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read );
|
||||
|
||||
XmlSerializer xs = new XmlSerializer( typeof( TType ) );
|
||||
//MemoryStream memoryStream = new MemoryStream( StringToUTF8ByteArray( pXmlizedString ) );
|
||||
//XmlTextReader reader = new XmlTextReader( fs, Encoding.UTF8 );
|
||||
|
||||
return xs.Deserialize( fs );
|
||||
}
|
||||
|
||||
|
||||
static public MethodInfo FindConvertFunction( string typeName )
|
||||
{
|
||||
Type t = typeof( Convert );
|
||||
|
||||
|
||||
MethodInfo[] allMethods = t.GetMethods();
|
||||
|
||||
foreach( MethodInfo mi in allMethods )
|
||||
{
|
||||
if( mi.GetParameters().Length == 1 )
|
||||
{
|
||||
string paramName = mi.GetParameters()[ 0 ].ParameterType.Name;
|
||||
|
||||
if( paramName == "String" )
|
||||
{
|
||||
if( mi.ReturnType.FullName == typeName )
|
||||
{
|
||||
return mi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
static public void SerializeDict<TKey, TVal>( string filename, Dictionary<TKey, TVal> dict )
|
||||
{
|
||||
XmlTextWriter xmlWriter = new XmlTextWriter( filename, null );
|
||||
|
||||
xmlWriter.Formatting = Formatting.Indented;
|
||||
|
||||
//xmlWriter.WriteStartDocument();
|
||||
|
||||
xmlWriter.WriteStartElement( "dictionary" );
|
||||
|
||||
Type[] types = dict.GetType().GetGenericArguments();
|
||||
|
||||
xmlWriter.WriteAttributeString( "keyType", types[ 0 ].FullName );
|
||||
xmlWriter.WriteAttributeString( "valType", types[ 1 ].FullName );
|
||||
|
||||
foreach( KeyValuePair<TKey, TVal> kvp in dict )
|
||||
{
|
||||
xmlWriter.WriteStartElement( "kvp" );
|
||||
|
||||
xmlWriter.WriteAttributeString( "key", kvp.Key.ToString() );
|
||||
xmlWriter.WriteAttributeString( "value", kvp.Value.ToString() );
|
||||
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
|
||||
xmlWriter.WriteEndElement();
|
||||
|
||||
//xmlWriter.WriteEndDocument();
|
||||
|
||||
xmlWriter.Close();
|
||||
}
|
||||
|
||||
static public void DeserializeDict<TKey, TVal>( string filename, Dictionary<TKey, TVal> dict )
|
||||
{
|
||||
FileStream fs = new FileStream( filename, FileMode.Open, FileAccess.Read );
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
doc.Load( fs );
|
||||
|
||||
//CreateTypeFor()
|
||||
|
||||
XmlElement docElem = doc.DocumentElement;
|
||||
|
||||
if( docElem.Name == "dictionary" )
|
||||
{
|
||||
string keyType = docElem.GetAttribute( "keyType" );
|
||||
string valType = docElem.GetAttribute( "valType" );
|
||||
|
||||
MethodInfo keyMI = FindConvertFunction( keyType );
|
||||
MethodInfo valMI = FindConvertFunction( valType );
|
||||
|
||||
|
||||
if( keyMI != null && valMI != null )
|
||||
{
|
||||
XmlNodeList nodeList = docElem.ChildNodes;
|
||||
|
||||
object[] args = new object[ 1 ];
|
||||
|
||||
//fi.SetValue( newObj, obj );
|
||||
|
||||
foreach( XmlElement node in nodeList )
|
||||
{
|
||||
if( node.Name == "kvp" )
|
||||
{
|
||||
if( node.Attributes != null )
|
||||
{
|
||||
args[ 0 ] = node.GetAttribute( "key" );
|
||||
|
||||
TKey key = (TKey)keyMI.Invoke( null, args );
|
||||
|
||||
args[ 0 ] = node.GetAttribute( "value" );
|
||||
|
||||
TVal val = (TVal)valMI.Invoke( null, args );
|
||||
|
||||
dict[ key ] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.error( String.Format( "No attributes in node while loading file {0}", filename ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.error( String.Format( "Incorrect key {0} found while loading file {1}", node.Name, filename ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( keyMI == null )
|
||||
Log.error( String.Format( "Key type conversion not found for type {0}", keyType ) );
|
||||
|
||||
if( valMI == null )
|
||||
Log.error( String.Format( "Val type conversion not found for type {0}", valType ) );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.error( String.Format( "No dictionary element found while loading file {0}", filename ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
239
Log.cs
Normal file
239
Log.cs
Normal file
@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
//using System.Threading.Tasks;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
|
||||
public delegate void Log_delegate( String type, String cat, String msg );
|
||||
|
||||
public class Log : TraceListener
|
||||
{
|
||||
static public void create( String filename )
|
||||
{
|
||||
s_log = new Log( filename );
|
||||
}
|
||||
|
||||
static public void destroy()
|
||||
{
|
||||
string msg = "==============================================================================\nLogfile shutdown at " + DateTime.Now.ToString();
|
||||
|
||||
s_log.writeToAll( "info", "log", msg );
|
||||
|
||||
s_log.stop();
|
||||
|
||||
s_log = null;
|
||||
}
|
||||
|
||||
static private Log s_log;
|
||||
|
||||
static public Log log
|
||||
{
|
||||
get
|
||||
{
|
||||
return s_log;
|
||||
}
|
||||
}
|
||||
|
||||
// Forwards.
|
||||
static public void error( String msg, params object[] args ) { lock( s_log ) { log.error_i( msg, args ); } }
|
||||
static public void warn( String msg, params object[] args ) { lock( s_log ) { log.warn_i( msg, args ); } }
|
||||
static public void info( String msg, params object[] args ) { lock( s_log ) { log.info_i( msg, args ); } }
|
||||
|
||||
|
||||
private Log( String filename )
|
||||
{
|
||||
//TODO: Fix this so itll work without a directory.
|
||||
Directory.CreateDirectory( Path.GetDirectoryName( filename ) );
|
||||
|
||||
m_stream = new FileStream( filename, FileMode.Append, FileAccess.Write );
|
||||
m_writer = new StreamWriter( m_stream );
|
||||
|
||||
m_errorStream = new FileStream( filename + ".error", FileMode.Append, FileAccess.Write );
|
||||
m_errorWriter = new StreamWriter( m_errorStream );
|
||||
|
||||
Debug.Listeners.Add( this );
|
||||
|
||||
string msg = "\n==============================================================================\nLogfile " + filename + " startup at " + DateTime.Now.ToString();
|
||||
|
||||
writeToAll( "info", "log", msg );
|
||||
}
|
||||
|
||||
public override void Write( string msg )
|
||||
{
|
||||
WriteLine( msg );
|
||||
}
|
||||
|
||||
public override void WriteLine( string msg )
|
||||
{
|
||||
error( msg );
|
||||
//base.WriteLine( msg );
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
m_writer.Close();
|
||||
m_stream.Close();
|
||||
|
||||
m_errorWriter.Close();
|
||||
m_errorStream.Close();
|
||||
}
|
||||
|
||||
public void addDelegate( Log_delegate cb )
|
||||
{
|
||||
m_delegates.Add( cb );
|
||||
}
|
||||
|
||||
private void writeFileAndLine( StackTrace st )
|
||||
{
|
||||
StackFrame frame = st.GetFrame( 1 );
|
||||
|
||||
String srcFile = frame.GetFileName();
|
||||
String srcLine = frame.GetFileLineNumber().ToString();
|
||||
|
||||
Console.WriteLine( "{0} ({1}):", srcFile, srcLine );
|
||||
}
|
||||
|
||||
private void writeStack( StackTrace st )
|
||||
{
|
||||
for( int i=0; i<st.FrameCount; ++i )
|
||||
{
|
||||
StackFrame frame = st.GetFrame( i );
|
||||
|
||||
String srcFile = frame.GetFileName();
|
||||
String srcLine = frame.GetFileLineNumber().ToString();
|
||||
|
||||
if( srcFile != null )
|
||||
{
|
||||
Console.WriteLine( "{0} ({1})", srcFile, srcLine );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private char getSymbol( String type )
|
||||
{
|
||||
if( type == "info" )
|
||||
return ' ';
|
||||
if( type == "warn" )
|
||||
return '-';
|
||||
if( type == "error" )
|
||||
return '*';
|
||||
|
||||
return '?';
|
||||
}
|
||||
|
||||
private void writeToAll( String type, String cat, String msg )
|
||||
{
|
||||
try
|
||||
{
|
||||
lock( this )
|
||||
{
|
||||
char sym = getSymbol( type );
|
||||
|
||||
String finalMsg = String.Format( "{0,-10}{1}| {2}", type, sym, msg );
|
||||
|
||||
//Console.WriteLine( finalMsg );
|
||||
//Console.Out.Write( finalMsg );
|
||||
|
||||
foreach( var l_obj in Debug.Listeners )
|
||||
{
|
||||
var l = l_obj as TraceListener;
|
||||
if( l != null && l != this )
|
||||
{
|
||||
l.WriteLine( finalMsg );
|
||||
}
|
||||
}
|
||||
|
||||
m_writer.WriteLine( finalMsg );
|
||||
|
||||
m_writer.Flush();
|
||||
|
||||
foreach( Log_delegate cb in m_delegates )
|
||||
{
|
||||
//lock( cb )
|
||||
{
|
||||
cb( type, cat, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception )
|
||||
{
|
||||
//oops.
|
||||
//int dummy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void error_i( String msg, params object[] args )
|
||||
{
|
||||
//var t = Task.Run( () => {
|
||||
StackTrace st = new StackTrace( true );
|
||||
|
||||
writeStack( st );
|
||||
|
||||
String msgPrint = msg;
|
||||
|
||||
if( args.Length > 0 )
|
||||
{
|
||||
msgPrint = String.Format( msg, args );
|
||||
}
|
||||
|
||||
writeToAll( "error", "log", msgPrint );
|
||||
//} );
|
||||
}
|
||||
|
||||
private void warn_i( String msg, params object[] args )
|
||||
{
|
||||
//var t = Task.Run( () => {
|
||||
StackTrace st = new StackTrace( true );
|
||||
|
||||
writeStack( st );
|
||||
|
||||
String msgPrint = msg;
|
||||
|
||||
if( args.Length > 0 )
|
||||
{
|
||||
msgPrint = String.Format( msg, args );
|
||||
}
|
||||
|
||||
writeToAll( "warn", "log", msgPrint );
|
||||
//});
|
||||
}
|
||||
|
||||
private void info_i( String msg, params object[] args )
|
||||
{
|
||||
//var t = Task.Run( () => {
|
||||
StackTrace st = new StackTrace( true );
|
||||
|
||||
String msgPrint = msg;
|
||||
|
||||
if( args.Length > 0 )
|
||||
{
|
||||
msgPrint = String.Format( msg, args );
|
||||
}
|
||||
|
||||
writeToAll( "info", "log", msgPrint );
|
||||
//} );
|
||||
}
|
||||
|
||||
|
||||
private Stream m_stream;
|
||||
private StreamWriter m_writer;
|
||||
|
||||
private Stream m_errorStream;
|
||||
private StreamWriter m_errorWriter;
|
||||
|
||||
private ArrayList m_delegates = new ArrayList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
103
NetMsg.cs
Normal file
103
NetMsg.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using System;
|
||||
|
||||
namespace lib.Net
|
||||
{
|
||||
[Serializable]
|
||||
public class Msg
|
||||
{
|
||||
public Msg()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Login
|
||||
{
|
||||
public Login( String name, String pass )
|
||||
{
|
||||
m_username = name;
|
||||
m_password = pass;
|
||||
}
|
||||
|
||||
public readonly String m_username;
|
||||
public readonly String m_password;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class LoginResp
|
||||
{
|
||||
public LoginResp( bool resp )
|
||||
{
|
||||
m_resp = resp;
|
||||
}
|
||||
|
||||
public readonly bool m_resp;
|
||||
}
|
||||
|
||||
#region Admin Messages
|
||||
//Subclasses of this need to be on an admin client.
|
||||
[Serializable]
|
||||
public class Admin
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
[Serializable]
|
||||
public class CreateEntity : Admin
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class MoveEntity : Admin
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
[Serializable]
|
||||
public class EntityBase
|
||||
{
|
||||
public EntityBase( int id )
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
public readonly int m_id;
|
||||
};
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class EntityPos : EntityBase
|
||||
{
|
||||
public EntityPos( int id, float x, float y, float z ) :
|
||||
base( id )
|
||||
{
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_z = z;
|
||||
}
|
||||
|
||||
public readonly float m_x;
|
||||
public readonly float m_y;
|
||||
public readonly float m_z;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class EntityDesc : EntityBase
|
||||
{
|
||||
public EntityDesc( int id ) :
|
||||
base( id )
|
||||
{
|
||||
}
|
||||
|
||||
//Should an entity have a mesh? Be made up of multiple meshes?
|
||||
public readonly String m_mesh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
52
Pos.cs
Normal file
52
Pos.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
public struct Pos
|
||||
{
|
||||
public float x { get; private set; }
|
||||
public float y { get; private set; }
|
||||
public float z { get; private set; }
|
||||
|
||||
|
||||
public Pos( float _x, float _y, float _z ) : this()
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
}
|
||||
|
||||
// overload operator +
|
||||
public static Pos operator +( Pos a, Pos b )
|
||||
{
|
||||
return new Pos( a.x + b.x, a.y + b.y, a.z + b.z );
|
||||
}
|
||||
|
||||
public static Pos operator -( Pos a, Pos b )
|
||||
{
|
||||
return new Pos( a.x - b.x, a.y - b.y, a.z - b.z );
|
||||
}
|
||||
|
||||
public static Pos operator /( Pos a, float val )
|
||||
{
|
||||
return new Pos( a.x / val, a.y / val, a.z / val );
|
||||
}
|
||||
|
||||
public static Pos operator *( Pos a, float val )
|
||||
{
|
||||
return new Pos( a.x * val, a.y * val, a.z * val );
|
||||
}
|
||||
|
||||
public float distSqr( Pos other )
|
||||
{
|
||||
float dx = x - other.x;
|
||||
float dy = y - other.y;
|
||||
float dz = z - other.z;
|
||||
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
36
Properties/AssemblyInfo.cs
Normal file
36
Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle( "Common" )]
|
||||
[assembly: AssemblyDescription( "" )]
|
||||
[assembly: AssemblyConfiguration( "" )]
|
||||
[assembly: AssemblyCompany( "Allusion Studio, Inc" )]
|
||||
[assembly: AssemblyProduct( "Common" )]
|
||||
[assembly: AssemblyCopyright( "Copyright © Allusion Studio, Inc 2008" )]
|
||||
[assembly: AssemblyTrademark( "" )]
|
||||
[assembly: AssemblyCulture( "" )]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible( false )]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid( "fbc724c2-ea86-47cf-ae0b-f15e11ba6701" )]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion( "1.0.0.0" )]
|
||||
[assembly: AssemblyFileVersion( "1.0.0.0" )]
|
||||
157
SerializableDictionary.cs
Normal file
157
SerializableDictionary.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using System.Xml;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.IO;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
[Serializable]
|
||||
public class SerializableDictionary<TKey, TVal> : Dictionary<TKey, TVal>, IXmlSerializable, ISerializable
|
||||
{
|
||||
#region Constants
|
||||
private const string DictionaryNodeName = "Dictionary";
|
||||
private const string ItemNodeName = "Item";
|
||||
private const string KeyNodeName = "Key";
|
||||
private const string ValueNodeName = "Value";
|
||||
#endregion
|
||||
#region Constructors
|
||||
public SerializableDictionary()
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(IDictionary<TKey,TVal> dictionary)
|
||||
: base(dictionary)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(IEqualityComparer<TKey> comparer)
|
||||
: base(comparer)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(int capacity)
|
||||
: base(capacity)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(IDictionary<TKey,TVal> dictionary, IEqualityComparer<TKey> comparer)
|
||||
: base(dictionary, comparer)
|
||||
{
|
||||
}
|
||||
|
||||
public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
|
||||
: base(capacity, comparer)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region ISerializable Members
|
||||
|
||||
protected SerializableDictionary(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
int itemCount = info.GetInt32("ItemCount");
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
KeyValuePair<TKey, TVal> kvp = (KeyValuePair<TKey, TVal>)info.GetValue(String.Format("Item{0}", i), typeof(KeyValuePair<TKey, TVal>));
|
||||
this.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
|
||||
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("ItemCount", this.Count);
|
||||
int itemIdx = 0;
|
||||
foreach (KeyValuePair<TKey, TVal> kvp in this) {
|
||||
info.AddValue(String.Format("Item{0}", itemIdx), kvp, typeof(KeyValuePair<TKey, TVal>));
|
||||
itemIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region IXmlSerializable Members
|
||||
|
||||
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
|
||||
{
|
||||
//writer.WriteStartElement(DictionaryNodeName);
|
||||
foreach (KeyValuePair<TKey, TVal> kvp in this) {
|
||||
writer.WriteStartElement(ItemNodeName);
|
||||
writer.WriteStartElement(KeyNodeName);
|
||||
KeySerializer.Serialize(writer, kvp.Key);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteStartElement(ValueNodeName);
|
||||
ValueSerializer.Serialize(writer, kvp.Value);
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
//writer.WriteEndElement();
|
||||
}
|
||||
|
||||
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
|
||||
{
|
||||
if (reader.IsEmptyElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move past container
|
||||
if (!reader.Read()){
|
||||
throw new XmlException("Error in Deserialization of Dictionary");
|
||||
}
|
||||
|
||||
//reader.ReadStartElement(DictionaryNodeName);
|
||||
while (reader.NodeType != XmlNodeType.EndElement) {
|
||||
reader.ReadStartElement(ItemNodeName);
|
||||
reader.ReadStartElement(KeyNodeName);
|
||||
TKey key = (TKey)KeySerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
reader.ReadStartElement(ValueNodeName);
|
||||
TVal value = (TVal)ValueSerializer.Deserialize(reader);
|
||||
reader.ReadEndElement();
|
||||
reader.ReadEndElement();
|
||||
this.Add(key, value);
|
||||
reader.MoveToContent();
|
||||
}
|
||||
//reader.ReadEndElement();
|
||||
|
||||
reader.ReadEndElement(); // Read End Element to close Read of containing node
|
||||
}
|
||||
|
||||
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region Private Properties
|
||||
protected XmlSerializer ValueSerializer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (valueSerializer == null) {
|
||||
valueSerializer = new XmlSerializer(typeof(TVal));
|
||||
}
|
||||
return valueSerializer;
|
||||
}
|
||||
}
|
||||
|
||||
private XmlSerializer KeySerializer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (keySerializer == null) {
|
||||
keySerializer = new XmlSerializer(typeof(TKey));
|
||||
}
|
||||
return keySerializer;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Private Members
|
||||
private XmlSerializer keySerializer = null;
|
||||
private XmlSerializer valueSerializer = null;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
20
SharpLib.sln
Normal file
20
SharpLib.sln
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpLib", "SharpLib.csproj", "{DED134FC-C282-49C9-BA02-3CE6257E91FC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{DED134FC-C282-49C9-BA02-3CE6257E91FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DED134FC-C282-49C9-BA02-3CE6257E91FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DED134FC-C282-49C9-BA02-3CE6257E91FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DED134FC-C282-49C9-BA02-3CE6257E91FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
95
Timer.cs
Normal file
95
Timer.cs
Normal file
@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
public class Timer
|
||||
{
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern bool QueryPerformanceCounter(
|
||||
out long lpPerformanceCount);
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
private static extern bool QueryPerformanceFrequency(
|
||||
out long lpFrequency);
|
||||
|
||||
private long startTime;
|
||||
private long stopTime;
|
||||
private long freq;
|
||||
private long freq_millis;
|
||||
|
||||
// Constructor
|
||||
|
||||
public Timer()
|
||||
{
|
||||
startTime = 0;
|
||||
stopTime = 0;
|
||||
|
||||
if (QueryPerformanceFrequency(out freq) == false)
|
||||
{
|
||||
// high-performance counter not supported
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
||||
freq_millis = freq / 1000;
|
||||
|
||||
}
|
||||
|
||||
// Start the timer
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// lets do the waiting threads there work
|
||||
|
||||
//Thread.Sleep(0);
|
||||
|
||||
QueryPerformanceCounter(out startTime);
|
||||
}
|
||||
|
||||
// Stop the timer
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
QueryPerformanceCounter(out stopTime);
|
||||
}
|
||||
|
||||
public double Seconds
|
||||
{
|
||||
get
|
||||
{
|
||||
long current;
|
||||
|
||||
QueryPerformanceCounter( out current );
|
||||
|
||||
return (double)( current - startTime ) / freq;
|
||||
}
|
||||
}
|
||||
|
||||
public long Current
|
||||
{
|
||||
get
|
||||
{
|
||||
long current;
|
||||
|
||||
QueryPerformanceCounter( out current );
|
||||
|
||||
return ( current - startTime ) / freq_millis;
|
||||
}
|
||||
}
|
||||
|
||||
public double Duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return (double)( stopTime - startTime ) / (double)freq;
|
||||
}
|
||||
}
|
||||
|
||||
public long DurationMS
|
||||
{
|
||||
get { return (stopTime - startTime) / freq_millis; }
|
||||
}
|
||||
}
|
||||
}
|
||||
46
Token.cs
Normal file
46
Token.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
[Serializable]
|
||||
public struct Token
|
||||
{
|
||||
public string str { get{ return m_str; } }
|
||||
|
||||
public Token( String str )
|
||||
{
|
||||
m_str = str;
|
||||
m_hash = m_str.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals( object obj )
|
||||
{
|
||||
if( !( obj is Token ) )
|
||||
return false;
|
||||
|
||||
//This doesnt use as because Token is a struct
|
||||
var otherId = (Token)obj;
|
||||
|
||||
if( m_hash != otherId.m_hash )
|
||||
return false;
|
||||
|
||||
return m_str == otherId.m_str;
|
||||
}
|
||||
|
||||
|
||||
public bool Equals_fast( Token other )
|
||||
{
|
||||
return m_hash == other.m_hash && m_str == other.m_str;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
int m_hash;
|
||||
String m_str;
|
||||
}
|
||||
|
||||
}
|
||||
BIN
UpgradeLog.XML
Normal file
BIN
UpgradeLog.XML
Normal file
Binary file not shown.
BIN
UpgradeLog.htm
Normal file
BIN
UpgradeLog.htm
Normal file
Binary file not shown.
670
VersionFormatter.cs
Normal file
670
VersionFormatter.cs
Normal file
@ -0,0 +1,670 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
//using System.Globalization;
|
||||
//using System.ComponentModel;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class VersionFormatter : IFormatter
|
||||
{
|
||||
public enum ETypes
|
||||
{
|
||||
Array,
|
||||
Int32,
|
||||
Ref,
|
||||
Object,
|
||||
EndObject,
|
||||
Single,
|
||||
Double,
|
||||
Char,
|
||||
String,
|
||||
Boolean,
|
||||
EndStream,
|
||||
}
|
||||
|
||||
|
||||
public VersionFormatter()
|
||||
{
|
||||
//
|
||||
// TODO: Add constructor logic here
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
#region Useless
|
||||
public ISurrogateSelector SurrogateSelector
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public SerializationBinder Binder
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public StreamingContext Context
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StreamingContext();
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
#endregion Useless
|
||||
|
||||
Queue m_objectsToBeDeserialized = new Queue();
|
||||
Hashtable m_alreadyDeserialzied = new Hashtable();
|
||||
//int m_GUID = 0;
|
||||
|
||||
#region Serialize
|
||||
public void Serialize( Stream stream, object obj )
|
||||
{
|
||||
//Default is 4k
|
||||
//BufferedStream bufStream = new BufferedStream( stream );
|
||||
|
||||
BinaryWriter writer = new BinaryWriter( stream );
|
||||
|
||||
writeObject( writer, obj );
|
||||
|
||||
while( m_objectsToBeDeserialized.Count != 0 )
|
||||
{
|
||||
object objToDes = m_objectsToBeDeserialized.Dequeue();
|
||||
|
||||
writeObject( writer, objToDes );
|
||||
}
|
||||
|
||||
writer.Write( (char)ETypes.EndStream );
|
||||
}
|
||||
|
||||
void writeRefAndSched( BinaryWriter writer, object obj )
|
||||
{
|
||||
//if( m_alreadyDeserialzied[ obj.GetType().GetArrayRank(
|
||||
|
||||
if( obj == null )
|
||||
{
|
||||
writer.Write( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//Now write the address.
|
||||
//Bad bad. Need to do this correctly.
|
||||
int objRef = obj.GetHashCode();
|
||||
writer.Write( objRef );
|
||||
|
||||
if( m_alreadyDeserialzied[ obj ] == null )
|
||||
{
|
||||
m_alreadyDeserialzied[ obj ] = obj;
|
||||
m_objectsToBeDeserialized.Enqueue( obj );
|
||||
}
|
||||
}
|
||||
|
||||
void dispatchWrite( BinaryWriter writer, object parentObj, FieldInfo fi )
|
||||
{
|
||||
string typeName = fi.FieldType.Name;
|
||||
|
||||
string name = fi.Name;
|
||||
|
||||
if( fi.IsNotSerialized )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( fi.FieldType.IsArray )
|
||||
{
|
||||
writer.Write( (char)ETypes.Array );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
writeArray( writer, (Array)fi.GetValue( parentObj ) );
|
||||
}
|
||||
else if( ( fi.FieldType.IsClass || fi.FieldType.IsInterface ) && typeName != "String" )
|
||||
{
|
||||
writer.Write( (char)ETypes.Ref );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
writeRefAndSched( writer, fi.GetValue( parentObj ) );
|
||||
}
|
||||
else if( fi.FieldType.IsEnum )
|
||||
{
|
||||
writer.Write( (char)ETypes.Int32 );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
write( writer, Convert.ToInt32( fi.GetValue( parentObj ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( typeName )
|
||||
{
|
||||
case "Int32":
|
||||
writer.Write( (char)ETypes.Int32 );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
write( writer, Convert.ToInt32( fi.GetValue( parentObj ) ) );
|
||||
break;
|
||||
case "Single":
|
||||
writer.Write( (char)ETypes.Single );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
write( writer, Convert.ToSingle( fi.GetValue( parentObj ) ) );
|
||||
break;
|
||||
case "Double":
|
||||
writer.Write( (char)ETypes.Double );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
write( writer, Convert.ToDouble( fi.GetValue( parentObj ) ) );
|
||||
break;
|
||||
case "Char":
|
||||
writer.Write( (char)ETypes.Char );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
write( writer, Convert.ToChar( fi.GetValue( parentObj ) ) );
|
||||
break;
|
||||
case "String":
|
||||
writer.Write( (char)ETypes.String );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
write( writer, Convert.ToString( fi.GetValue( parentObj ) ) );
|
||||
break;
|
||||
case "Boolean":
|
||||
writer.Write( (char)ETypes.Boolean );
|
||||
writer.Write( name.GetHashCode() );
|
||||
|
||||
writer.Write( Convert.ToBoolean( fi.GetValue( parentObj ) ) );
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine( "VersionFormatter does not understand type " + typeName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeArray( BinaryWriter writer, Array array )
|
||||
{
|
||||
if( array == null )
|
||||
{
|
||||
writer.Write( (int)-1 );
|
||||
return;
|
||||
}
|
||||
|
||||
writer.Write( array.Length );
|
||||
|
||||
foreach( object obj in array )
|
||||
{
|
||||
writeRefAndSched( writer, obj );
|
||||
}
|
||||
}
|
||||
|
||||
void getAllFields( object obj, ArrayList list )
|
||||
{
|
||||
Type t = obj.GetType();
|
||||
|
||||
while( t != null )
|
||||
{
|
||||
FieldInfo[] fiArr = t.GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly );
|
||||
list.AddRange( fiArr );
|
||||
|
||||
t = t.BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeObject( BinaryWriter writer, object obj )
|
||||
{
|
||||
Type objType = obj.GetType();
|
||||
|
||||
writer.Write( (char)ETypes.Object );
|
||||
writer.Write( objType.FullName );
|
||||
|
||||
int objRef = obj.GetHashCode();
|
||||
writer.Write( objRef );
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
getAllFields( obj, list );
|
||||
|
||||
foreach( FieldInfo fi in list )
|
||||
{
|
||||
dispatchWrite( writer, obj, fi );
|
||||
}
|
||||
|
||||
writer.Write( (char)ETypes.EndObject );
|
||||
}
|
||||
|
||||
void write<TType>( BinaryWriter wr, TType val )
|
||||
{
|
||||
//wr.Write( val );
|
||||
}
|
||||
|
||||
/*
|
||||
void writeInt( BinaryWriter writer, int val )
|
||||
{
|
||||
writer.Write( val );
|
||||
}
|
||||
|
||||
void writeSingle( BinaryWriter writer, float val )
|
||||
{
|
||||
writer.Write( val );
|
||||
}
|
||||
|
||||
void writeDouble( BinaryWriter writer, double val )
|
||||
{
|
||||
writer.Write( val );
|
||||
}
|
||||
|
||||
void writeChar( BinaryWriter writer, char val )
|
||||
{
|
||||
writer.Write( val );
|
||||
}
|
||||
|
||||
void writeString( BinaryWriter writer, string val )
|
||||
{
|
||||
writer.Write( val );
|
||||
}
|
||||
|
||||
void writeBool( BinaryWriter writer, bool val )
|
||||
{
|
||||
writer.Write( val );
|
||||
}
|
||||
*/
|
||||
#endregion Serialize
|
||||
|
||||
|
||||
#region Deserialize
|
||||
|
||||
class Fixup
|
||||
{
|
||||
public Fixup( int guid, object obj, FieldInfo fi )
|
||||
{
|
||||
m_guid= guid;
|
||||
m_obj = obj;
|
||||
m_fi = fi;
|
||||
}
|
||||
|
||||
public Fixup( int guid, object obj, int index )
|
||||
{
|
||||
m_guid = guid;
|
||||
m_obj = obj;
|
||||
m_index= index;
|
||||
}
|
||||
|
||||
public readonly int m_guid = 0;
|
||||
public readonly object m_obj = null;
|
||||
|
||||
public readonly FieldInfo m_fi = null;
|
||||
public readonly int m_index= -1;
|
||||
|
||||
}
|
||||
|
||||
Hashtable m_mapGUIDToObject = new Hashtable();
|
||||
ArrayList m_fixupList = new ArrayList();
|
||||
|
||||
ArrayList m_desObjects = new ArrayList();
|
||||
|
||||
public object Deserialize( Stream stream )
|
||||
{
|
||||
BinaryReader reader = new BinaryReader( stream );
|
||||
|
||||
object objRoot = null;
|
||||
|
||||
//Read in the first object.
|
||||
{
|
||||
ETypes type = (ETypes)reader.ReadChar();
|
||||
|
||||
Debug.Assert( type == ETypes.Object );
|
||||
|
||||
objRoot = readObject( reader );
|
||||
|
||||
m_desObjects.Add( objRoot );
|
||||
}
|
||||
|
||||
bool readObjects = true;
|
||||
|
||||
while( readObjects )
|
||||
{
|
||||
ETypes type = (ETypes)reader.ReadChar();
|
||||
|
||||
Debug.Assert( type == ETypes.Object || type == ETypes.EndStream );
|
||||
|
||||
if( type == ETypes.Object )
|
||||
{
|
||||
object obj = readObject( reader );
|
||||
|
||||
m_desObjects.Add( obj );
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert( type == ETypes.EndStream );
|
||||
|
||||
readObjects = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( Fixup fu in m_fixupList )
|
||||
{
|
||||
//Fixup fix = m_fixups[
|
||||
|
||||
object obj = m_mapGUIDToObject[ fu.m_guid ];
|
||||
|
||||
if( obj != null )
|
||||
{
|
||||
if( fu.m_fi != null )
|
||||
{
|
||||
fu.m_fi.SetValue( fu.m_obj, obj );
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert( fu.m_index >= 0 );
|
||||
|
||||
object []array = (object [])fu.m_obj;
|
||||
|
||||
array[ fu.m_index ] = obj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine( "Obj to ref is null." );
|
||||
}
|
||||
}
|
||||
|
||||
foreach( object obj in m_desObjects )
|
||||
{
|
||||
if( typeof( IDeserializationCallback ).IsAssignableFrom( obj.GetType() ) )
|
||||
{
|
||||
IDeserializationCallback desCB = (IDeserializationCallback)obj;
|
||||
|
||||
if( desCB != null )
|
||||
{
|
||||
desCB.OnDeserialization( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return objRoot;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool dispatchRead( BinaryReader reader, object obj, Hashtable ht )
|
||||
{
|
||||
|
||||
//Read the type
|
||||
ETypes type = (ETypes)reader.ReadChar();
|
||||
|
||||
if( type == ETypes.EndObject )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int nameHash = reader.ReadInt32();
|
||||
|
||||
FieldInfo fi = (FieldInfo)ht[ nameHash ];
|
||||
|
||||
if( fi == null )
|
||||
{
|
||||
Console.WriteLine( "Field no longer exists" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case ETypes.Array:
|
||||
readArray( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.Int32:
|
||||
readInt( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.Single:
|
||||
readSingle( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.Double:
|
||||
readDouble( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.Char:
|
||||
readChar( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.Boolean:
|
||||
readBool( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.String:
|
||||
readString( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.Ref:
|
||||
readRef( reader, obj, fi );
|
||||
break;
|
||||
case ETypes.Object:
|
||||
readObject( reader );
|
||||
break;
|
||||
default:
|
||||
Debug.Fail( "Unknown type on read." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
Console.WriteLine( "Exception: " + ex.Message );
|
||||
Console.WriteLine( "Stack: " + ex.StackTrace );
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
object createObject( string objTypeName )
|
||||
{
|
||||
Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
foreach( Assembly a in ass )
|
||||
{
|
||||
Type t = a.GetType( objTypeName );
|
||||
|
||||
if( t != null )
|
||||
{
|
||||
object obj = FormatterServices.GetUninitializedObject( t );
|
||||
|
||||
if( obj != null )
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
object readObject( BinaryReader reader )
|
||||
{
|
||||
//ETypes type = (ETypes)reader.ReadChar();
|
||||
|
||||
//Debug.Assert( type == ETypes.Object, "Expecting type Object" );
|
||||
|
||||
string objTypeName = reader.ReadString();
|
||||
int objGUID = reader.ReadInt32();
|
||||
|
||||
try
|
||||
{
|
||||
object obj = createObject( objTypeName );
|
||||
|
||||
m_mapGUIDToObject[ objGUID ] = obj;
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
Hashtable ht = new Hashtable();
|
||||
|
||||
if( obj != null )
|
||||
{
|
||||
getAllFields( obj, list );
|
||||
|
||||
foreach( FieldInfo fi in list )
|
||||
{
|
||||
ht[ fi.Name.GetHashCode() ] = fi;
|
||||
}
|
||||
}
|
||||
|
||||
while( dispatchRead( reader, obj, ht ) )
|
||||
{
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
Console.WriteLine( "Exception: " + ex.Message );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void readArray( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
int length = reader.ReadInt32();
|
||||
|
||||
if( length < 0 )
|
||||
{
|
||||
if( fi == null ) return;
|
||||
|
||||
fi.SetValue( obj, null );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
object[] array = new object[length];
|
||||
|
||||
if( fi != null )
|
||||
{
|
||||
fi.SetValue( obj, array );
|
||||
}
|
||||
|
||||
for( int i=0; i<length; ++i )
|
||||
{
|
||||
int val = reader.ReadInt32();
|
||||
|
||||
//m_fixups[ val ] = new Fixup( obj, fi );
|
||||
|
||||
if( fi != null )
|
||||
{
|
||||
m_fixupList.Add( new Fixup( val, array, i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readRef( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
int val = reader.ReadInt32();
|
||||
|
||||
//m_fixups[ val ] = new Fixup( obj, fi );
|
||||
|
||||
m_fixupList.Add( new Fixup( val, obj, fi ) );
|
||||
}
|
||||
|
||||
void readInt( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
int val = reader.ReadInt32();
|
||||
|
||||
if( fi == null ) return;
|
||||
|
||||
if( !fi.FieldType.IsEnum )
|
||||
{
|
||||
fi.SetValue( obj, val );
|
||||
}
|
||||
else
|
||||
{
|
||||
object enumVal = Enum.Parse( fi.FieldType, val.ToString() );
|
||||
fi.SetValue( obj, Convert.ChangeType( enumVal, fi.FieldType ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void readSingle( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
float val = reader.ReadSingle();
|
||||
|
||||
if( fi == null ) return;
|
||||
|
||||
fi.SetValue( obj, val );
|
||||
}
|
||||
|
||||
void readDouble( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
double val = reader.ReadDouble();
|
||||
|
||||
if( fi == null ) return;
|
||||
|
||||
fi.SetValue( obj, val );
|
||||
}
|
||||
|
||||
void readChar( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
char val = reader.ReadChar();
|
||||
|
||||
if( fi == null ) return;
|
||||
|
||||
fi.SetValue( obj, val );
|
||||
}
|
||||
|
||||
void readString( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
string val = reader.ReadString();
|
||||
|
||||
if( fi == null ) return;
|
||||
|
||||
fi.SetValue( obj, val );
|
||||
}
|
||||
|
||||
void readBool( BinaryReader reader, object obj, FieldInfo fi )
|
||||
{
|
||||
bool val = reader.ReadBoolean();
|
||||
|
||||
if( fi == null ) return;
|
||||
|
||||
fi.SetValue( obj, val );
|
||||
}
|
||||
|
||||
#endregion Deserialize
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1096
XmlFormatter.cs
Normal file
1096
XmlFormatter.cs
Normal file
File diff suppressed because it is too large
Load Diff
605
XmlFormatter2.cs
Normal file
605
XmlFormatter2.cs
Normal file
@ -0,0 +1,605 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Web.Configuration;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace lib
|
||||
{
|
||||
|
||||
public interface I_Serialize
|
||||
{
|
||||
void OnSerialize();
|
||||
void OnDeserialize( object enclosing );
|
||||
}
|
||||
|
||||
|
||||
public class XmlFormatter2 : IFormatter
|
||||
{
|
||||
public StreamingContext Context { get; set; }
|
||||
|
||||
static private Random s_rnd = new Random();
|
||||
private int m_rndVal = s_rnd.Next();
|
||||
|
||||
#region Unimplimented
|
||||
public ISurrogateSelector SurrogateSelector
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public SerializationBinder Binder
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
public XmlFormatter2()
|
||||
{
|
||||
Context = new StreamingContext( StreamingContextStates.All );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region Deserialize
|
||||
private static FormatterConverter s_conv = new FormatterConverter();
|
||||
|
||||
public object Deserialize( Stream stream )
|
||||
{
|
||||
//lib.log.info( "Deserialize( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
return DeserializeKnownType( stream, null );
|
||||
//lib.log.info( "Deserialize END ( Stream stream ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
}
|
||||
|
||||
public object DeserializeKnownType( Stream stream, Type t )
|
||||
{
|
||||
//lib.log.info( "DeserializeKnownType( Stream stream, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
XmlTextReader reader = new XmlTextReader( stream );
|
||||
//reader.Settings = System.Text.Encoding.ASCII;
|
||||
|
||||
object obj = Deserialize( reader, t );
|
||||
//lib.log.info( "DeserializeKnownType END( Stream stream, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
return obj;
|
||||
}
|
||||
|
||||
private object Deserialize( XmlReader reader, Type t )
|
||||
{
|
||||
//lib.log.info( "Deserialize( XmlReader reader, Type t ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
m_alreadySerialized.Clear();
|
||||
m_objectID = new ObjectIDGenerator();
|
||||
|
||||
reader.Read();
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
doc.Load( reader );
|
||||
|
||||
////lib.log.info( "What to deserialize {0}", doc.OuterXml.ToString() );
|
||||
|
||||
if( t == null ) return Deserialize( doc.DocumentElement );
|
||||
|
||||
return Deserialize( doc.DocumentElement, t );
|
||||
}
|
||||
|
||||
private object Deserialize( XmlElement elem )
|
||||
{
|
||||
//lib.log.info( "object Deserialize( XmlElement elem ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
string typename = elem.HasAttribute( "t" ) ? elem.GetAttribute( "t" ) : elem.Name;
|
||||
|
||||
return Deserialize( elem, typename );
|
||||
}
|
||||
|
||||
private object Deserialize( XmlElement elem, string typename )
|
||||
{
|
||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||
Assembly[] assems = currentDomain.GetAssemblies();
|
||||
|
||||
Type type = null;
|
||||
|
||||
// @@@@: This should go backwards, we tend to lookup our own stuff, then builtins.
|
||||
// Also, cache a typename into its assembly.
|
||||
foreach(Assembly a in assems)
|
||||
{
|
||||
type = a.GetType( typename );
|
||||
|
||||
if(type != null) break;
|
||||
}
|
||||
|
||||
if( type == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Deserialize( elem, type );
|
||||
}
|
||||
|
||||
private object Deserialize( XmlElement elem, Type type, object enclosing = null )
|
||||
{
|
||||
TypeCode typeCode = Type.GetTypeCode( type );
|
||||
|
||||
if( typeCode != TypeCode.Object )
|
||||
{
|
||||
return DeserializeConcrete( elem, type );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !type.IsArray )
|
||||
{
|
||||
object obj = DeserializeObject( elem, type );
|
||||
|
||||
if( obj is I_Serialize )
|
||||
{
|
||||
var iser = obj as I_Serialize;
|
||||
|
||||
iser.OnDeserialize( enclosing );
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DeserializeArray( elem, type );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type[] mm_types = new Type[1];
|
||||
private object GetDefault( Type t )
|
||||
{
|
||||
mm_types[0] = t;
|
||||
|
||||
var fn = GetType().GetMethod( "GetDefaultGeneric" ).MakeGenericMethod( mm_types );
|
||||
|
||||
return fn.Invoke( this, null );
|
||||
}
|
||||
|
||||
public T GetDefaultGeneric<T>()
|
||||
{
|
||||
return default( T );
|
||||
}
|
||||
|
||||
private object DeserializeConcrete( XmlElement elem, Type type )
|
||||
{
|
||||
string val = elem.GetAttribute( "v" );
|
||||
|
||||
if( !type.IsEnum )
|
||||
{
|
||||
try
|
||||
{
|
||||
return s_conv.Convert( val, type );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
return GetDefault( type );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Enum.Parse( type, val );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private XmlElement getNamedChild( XmlNodeList list, string name )
|
||||
{
|
||||
foreach( XmlNode node in list )
|
||||
{
|
||||
if( node.Name == name )
|
||||
{
|
||||
return (XmlElement)node;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Type FindType( string shortname )
|
||||
{
|
||||
Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
|
||||
|
||||
foreach( Assembly a in ass )
|
||||
{
|
||||
Type t = a.GetType( shortname );
|
||||
|
||||
if( t != null )
|
||||
{
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private object DeserializeObject( XmlElement elem, Type type )
|
||||
{
|
||||
string refString = elem.GetAttribute( "ref" );
|
||||
|
||||
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
||||
|
||||
var finalType = type;
|
||||
if( elem.HasAttribute( "t" ) )
|
||||
{
|
||||
var typename = elem.GetAttribute( "t" );
|
||||
finalType = FindType( typename );
|
||||
|
||||
if( finalType == null ) finalType = type;
|
||||
}
|
||||
|
||||
object obj = createObject( finalType, refInt );
|
||||
|
||||
if( obj is IList )
|
||||
{
|
||||
var list = obj as IList;
|
||||
|
||||
return DeserializeList( elem, type, list );
|
||||
}
|
||||
|
||||
Type typeISerializable = typeof( ISerializable );
|
||||
|
||||
//*
|
||||
/*
|
||||
if( obj is ISerializable ) // type.IsSubclassOf( typeISerializable ) )
|
||||
{
|
||||
XmlNodeList allChildren = elem.ChildNodes;
|
||||
|
||||
ISerializable ser = obj as ISerializable;
|
||||
|
||||
var serInfo = new SerializationInfo( type, new FormatterConverter() );
|
||||
|
||||
ser.GetObjectData( serInfo, Context );
|
||||
|
||||
//var serEnum = ;
|
||||
|
||||
foreach( var serMember in serInfo )
|
||||
{
|
||||
String name = serMember.Name;
|
||||
|
||||
name = name.Replace( '+', '-' );
|
||||
name = name.Replace( '`', '_' );
|
||||
|
||||
XmlElement childElem = getNamedChild( allChildren, name );
|
||||
|
||||
var des = Deserialize( childElem, name );
|
||||
}
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
MemberInfo[] miArr = FormatterServices.GetSerializableMembers( finalType );
|
||||
|
||||
XmlNodeList allChildren = elem.ChildNodes;
|
||||
|
||||
for( int i = 0; i < miArr.Length; ++i )
|
||||
{
|
||||
FieldInfo childFi = (FieldInfo)miArr[ i ];
|
||||
|
||||
String name = childFi.Name;
|
||||
|
||||
name = name.Replace( '+', '-' );
|
||||
name = name.Replace( '`', '_' );
|
||||
|
||||
XmlElement childElem = getNamedChild( allChildren, name );
|
||||
|
||||
if( childElem != null )
|
||||
{
|
||||
object childObj = Deserialize( childElem, childFi.FieldType, obj );
|
||||
|
||||
childFi.SetValue( obj, childObj );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private object DeserializeList( XmlElement elem, Type type, IList list )
|
||||
{
|
||||
XmlNodeList arrNodeList = elem.ChildNodes;
|
||||
|
||||
Type t = list.GetType();
|
||||
|
||||
Type[] genT = t.GetGenericArguments();
|
||||
|
||||
Debug.Assert( genT.Length == 1 );
|
||||
|
||||
for( int i = 0; i < arrNodeList.Count; ++i )
|
||||
{
|
||||
if( arrNodeList.Item( i ) is XmlElement )
|
||||
{
|
||||
XmlElement arrElem = (XmlElement)arrNodeList.Item( i );
|
||||
|
||||
list.Add( Deserialize( arrElem, genT[0] ) );
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private object DeserializeArray( XmlElement elem, Type type )
|
||||
{
|
||||
Type typeElem = type.GetElementType();
|
||||
|
||||
string refString = elem.GetAttribute( "ref" );
|
||||
int refInt = refString.Length > 0 ? Convert.ToInt32( refString ) : -1;
|
||||
|
||||
XmlNodeList arrNodeList = elem.ChildNodes;
|
||||
|
||||
int length = arrNodeList.Count;
|
||||
|
||||
Array arr = createArray( typeElem, refInt, length );
|
||||
|
||||
for( int i = 0; i < arr.Length; ++i )
|
||||
{
|
||||
if( arrNodeList.Item( i ) is XmlElement )
|
||||
{
|
||||
XmlElement arrElem = (XmlElement)arrNodeList.Item( i );
|
||||
|
||||
arr.SetValue( Deserialize( arrElem, typeElem ), i );
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
private object createObject( string typename, int refInt )
|
||||
{
|
||||
Type type = Type.GetType( typename );
|
||||
|
||||
return createObject( type, refInt );
|
||||
}
|
||||
|
||||
private object createObject( Type type, int refInt )
|
||||
{
|
||||
TypeCode tc = Type.GetTypeCode( type );
|
||||
|
||||
if( refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
|
||||
{
|
||||
//lib.log.info( "Reusing object for {0}", refInt );
|
||||
return m_alreadySerialized[ refInt ];
|
||||
}
|
||||
else
|
||||
{
|
||||
//lib.log.info( "Creating new object for {0}", refInt );
|
||||
object obj = Activator.CreateInstance( type );
|
||||
|
||||
if( refInt > 0 )
|
||||
{
|
||||
m_alreadySerialized[ refInt ] = obj;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
private Array createArray( string elemTypename, int refInt, int length )
|
||||
{
|
||||
Type elemType = Type.GetType( elemTypename );
|
||||
|
||||
return createArray( elemType, refInt, length );
|
||||
}
|
||||
|
||||
private Array createArray( Type elemType, int refInt, int length )
|
||||
{
|
||||
TypeCode elemTC = Type.GetTypeCode( elemType );
|
||||
|
||||
if( refInt > 0 && m_alreadySerialized.ContainsKey( refInt ) )
|
||||
{
|
||||
return (Array)m_alreadySerialized[ refInt ];
|
||||
}
|
||||
else
|
||||
{
|
||||
Array arr = Array.CreateInstance( elemType, length ) ;
|
||||
|
||||
m_alreadySerialized[ refInt ] = arr;
|
||||
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectIDGenerator m_objectID = new ObjectIDGenerator();
|
||||
private Dictionary<long, object> m_alreadySerialized = new Dictionary<long, object>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialize
|
||||
|
||||
private string getTypeName( Type type )
|
||||
{
|
||||
//Assembly ass = type.Assembly;
|
||||
|
||||
//string assName = ass.GetName().Name;
|
||||
|
||||
return type.FullName; // + ", " + assName;
|
||||
}
|
||||
|
||||
public void Serialize( Stream stream, object root )
|
||||
{
|
||||
//lib.log.info( "Serialize( Stream stream, object root ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
|
||||
m_alreadySerialized.Clear();
|
||||
m_objectID = new ObjectIDGenerator();
|
||||
|
||||
XmlTextWriter writer = new XmlTextWriter( stream, System.Text.Encoding.ASCII );
|
||||
|
||||
writer.Formatting = Formatting.Indented;
|
||||
|
||||
Serialize( writer, root );
|
||||
|
||||
//Rely on the parent closing the stream.
|
||||
//writer.Close();
|
||||
writer.Flush();
|
||||
|
||||
//lib.log.info( "Serialize END ( Stream stream, object root ) {0} {1}", m_rndVal, m_alreadySerialized.Count );
|
||||
}
|
||||
|
||||
private void Serialize( XmlWriter writer, object root )
|
||||
{
|
||||
//writer.WriteStartDocument();
|
||||
Serialize( writer, root, "root" );
|
||||
//writer.WriteEndDocument();
|
||||
}
|
||||
|
||||
private void Serialize( XmlWriter writer, object root, string name )
|
||||
{
|
||||
writer.WriteStartElement( name );
|
||||
|
||||
if( root != null )
|
||||
{
|
||||
Type type = root.GetType();
|
||||
|
||||
TypeCode typeCode = Type.GetTypeCode( type );
|
||||
|
||||
if( typeCode != TypeCode.Object )
|
||||
{
|
||||
SerializeConcrete( writer, root );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !type.IsArray )
|
||||
{
|
||||
SerializeObject( writer, root );
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializeArray( writer, root );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteAttributeString( "v", "null" );
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void SerializeConcrete( XmlWriter writer, object root )
|
||||
{
|
||||
//TODO: Only write this out if debugging.
|
||||
//writer.WriteAttributeString( "t", getTypeName( root.GetType() ) );
|
||||
writer.WriteAttributeString( "v", root.ToString() );
|
||||
}
|
||||
|
||||
private void SerializeObject( XmlWriter writer, object root )
|
||||
{
|
||||
writer.WriteAttributeString( "t", getTypeName( root.GetType() ) );
|
||||
|
||||
/*
|
||||
if( root is IList )
|
||||
{
|
||||
var list = root as IList;
|
||||
|
||||
Type t = root.GetType();
|
||||
|
||||
Type[] genT = t.GetGenericArguments();
|
||||
}
|
||||
*/
|
||||
|
||||
bool first;
|
||||
|
||||
long refInt = m_objectID.GetId( root, out first );
|
||||
|
||||
writer.WriteAttributeString( "ref", refInt.ToString() );
|
||||
|
||||
if( first )
|
||||
{
|
||||
m_alreadySerialized[ refInt ] = root;
|
||||
|
||||
Type type = root.GetType();
|
||||
|
||||
//*
|
||||
Type typeISerializable = typeof( ISerializable );
|
||||
|
||||
if( root is ISerializable ) // type.IsSubclassOf( typeISerializable ) )
|
||||
{
|
||||
ISerializable ser = root as ISerializable;
|
||||
|
||||
var serInfo = new SerializationInfo( type, new FormatterConverter() );
|
||||
|
||||
ser.GetObjectData( serInfo, Context );
|
||||
|
||||
//var serEnum = ;
|
||||
|
||||
foreach( var serMember in serInfo )
|
||||
{
|
||||
String name = serMember.Name;
|
||||
|
||||
name = name.Replace( '+', '-' );
|
||||
name = name.Replace( '`', '_' );
|
||||
|
||||
Serialize( writer, serMember.Value, name );
|
||||
}
|
||||
|
||||
//var sc = new SerializationContext(
|
||||
|
||||
//ser.GetObjectData(
|
||||
}
|
||||
else
|
||||
//*/
|
||||
{
|
||||
MemberInfo[] miArr = FormatterServices.GetSerializableMembers( type, Context );
|
||||
|
||||
for( int i = 0; i < miArr.Length; ++i )
|
||||
{
|
||||
FieldInfo childFi = (FieldInfo)miArr[ i ];
|
||||
|
||||
object[] objs = childFi.GetCustomAttributes( typeof( NonSerializedAttribute ), true );
|
||||
|
||||
if( objs.Length > 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = childFi.Name;
|
||||
|
||||
name = name.Replace( '+', '-' );
|
||||
name = name.Replace( '`', '_' );
|
||||
|
||||
Serialize( writer, childFi.GetValue( root ), name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SerializeArray( XmlWriter writer, object root )
|
||||
{
|
||||
Array arr = (Array)root;
|
||||
|
||||
Type typeElem = arr.GetType().GetElementType();
|
||||
|
||||
writer.WriteAttributeString( "t", getTypeName( typeElem ) );
|
||||
|
||||
bool first;
|
||||
|
||||
long refInt = m_objectID.GetId( root, out first );
|
||||
|
||||
writer.WriteAttributeString( "ref", refInt.ToString() );
|
||||
|
||||
if( first )
|
||||
{
|
||||
m_alreadySerialized[ refInt ] = root;
|
||||
|
||||
|
||||
for( int i = 0; i < arr.Length; ++i )
|
||||
{
|
||||
Serialize( writer, arr.GetValue( i ), "i" + i.ToString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
167
res/Resource.cs
Normal file
167
res/Resource.cs
Normal file
@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
//using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
namespace res
|
||||
{
|
||||
|
||||
[Serializable]
|
||||
public class Ref : lib.I_Serialize
|
||||
{
|
||||
public string filename { get { return m_filename; } }
|
||||
|
||||
//For construction
|
||||
public Ref()
|
||||
{
|
||||
}
|
||||
|
||||
public Ref( string filename )
|
||||
{
|
||||
m_filename = filename;
|
||||
}
|
||||
|
||||
virtual public void OnSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
virtual public void OnDeserialize( object enclosing )
|
||||
{
|
||||
}
|
||||
|
||||
virtual public void OnChange()
|
||||
{
|
||||
}
|
||||
|
||||
private string m_filename;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Ref<T> : Ref
|
||||
{
|
||||
public T res{ get{ return m_res; } set{ m_res = value; } }
|
||||
|
||||
//For construction
|
||||
public Ref()
|
||||
{
|
||||
}
|
||||
|
||||
public Ref( string filename )
|
||||
: base( filename )
|
||||
{
|
||||
}
|
||||
|
||||
public Ref( string filename, T res ) : base( filename )
|
||||
{
|
||||
m_res = res;
|
||||
}
|
||||
|
||||
[NonSerialized]
|
||||
private T m_res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public class Resource
|
||||
{
|
||||
static public Mgr mgr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public class Loader<T>
|
||||
{
|
||||
static public T load( string filename )
|
||||
{
|
||||
Debug.Assert( false, "Specialize Loader for your type for file" );
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
*/
|
||||
public delegate Ref Load( string filename );
|
||||
public delegate Ref LoadType( string filename, Type t );
|
||||
|
||||
|
||||
public class Mgr
|
||||
{
|
||||
|
||||
|
||||
static public void startup()
|
||||
{
|
||||
Resource.mgr = new Mgr();
|
||||
}
|
||||
|
||||
static public void register<T>( Load loader )
|
||||
{
|
||||
Debug.Assert( !Resource.mgr.m_loaders.ContainsKey( typeof( T ) ) );
|
||||
Resource.mgr.m_loaders[ typeof( T ) ] = loader;
|
||||
}
|
||||
|
||||
static public void registerSub<T>( Load loaderOfType )
|
||||
{
|
||||
|
||||
Type[] typeParams = new Type[1];
|
||||
foreach( var mi in typeof( T ).GetMethods() )
|
||||
{
|
||||
if( mi.Name == "res_load" && mi.IsGenericMethod )
|
||||
{
|
||||
foreach( var ass in AppDomain.CurrentDomain.GetAssemblies() )
|
||||
{
|
||||
foreach( var t in ass.GetTypes() )
|
||||
{
|
||||
if( t.IsSubclassOf( typeof( T ) ) )
|
||||
{
|
||||
typeParams[0] = t;
|
||||
var mi_ng = mi.MakeGenericMethod( typeParams );
|
||||
Resource.mgr.m_loaders[ t ] = (Load)Delegate.CreateDelegate( typeof(Load), mi_ng );
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public Ref<T> load<T>( string filename ) where T : class
|
||||
{
|
||||
Load loader;
|
||||
Resource.mgr.m_loaders.TryGetValue( typeof( T ), out loader );
|
||||
|
||||
if( loader != null )
|
||||
{
|
||||
var rf_raw = loader( filename );
|
||||
Ref<T> rf = rf_raw as Ref<T>;
|
||||
return rf;
|
||||
}
|
||||
|
||||
return new Ref<T>( filename );
|
||||
}
|
||||
|
||||
static public Ref load( string filename, Type t )
|
||||
{
|
||||
Load loader;
|
||||
Resource.mgr.m_loaders.TryGetValue( t, out loader );
|
||||
|
||||
if( loader != null )
|
||||
{
|
||||
var rf_raw = loader( filename );
|
||||
return rf_raw;
|
||||
}
|
||||
|
||||
return new Ref<object>( filename );
|
||||
}
|
||||
|
||||
private Dictionary<Type, Load> m_loaders = new Dictionary<Type, Load>();
|
||||
//private Dictionary<Type, LoadType> m_loadersOfType = new Dictionary<Type, LoadType>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user