Formatting

This commit is contained in:
Marc Hernandez 2024-04-28 17:31:24 -07:00
parent dcd15a2663
commit c18c106b72
4 changed files with 391 additions and 400 deletions

View File

@ -11,9 +11,12 @@
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<NoWarn>$(NoWarn);SYSLIB0050</NoWarn>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" />
<PackageReference Include="Optional" Version="4.0.0" /> <PackageReference Include="Optional" Version="4.0.0" />

View File

@ -53,26 +53,12 @@ namespace lib
#region SaveLoad #region SaveLoad
/*
static public res.Ref<Config> res_load( string filename )
{
return new res.Ref<Config>( filename, load( filename ) );
}
*/
static public T res_load<T>( string filename ) where T : Config static public T res_load<T>( string filename ) where T : Config
{ {
return load<T>( filename ); return 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 ) static public Config load( string filename )
{ {
return load( filename, null ); return load( filename, null );

View File

@ -1,369 +1,371 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
//using System.Threading.Tasks; //using System.Threading.Tasks;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Threading; using System.Threading;
namespace res namespace res
{ {
using ImmDefLoad = ImmutableQueue<(string name, Ref)>; using ImmDefLoad = ImmutableQueue<(string name, Ref)>;
public interface Res_old public interface Res_old
{ {
} }
[Serializable] [Serializable]
public class Ref : lib.I_Serialize public class Ref : lib.I_Serialize
{ {
public string filename { get { return m_filename; } } public string Filename =>_filename;
//For construction //For construction
public Ref() public Ref()
{ {
} _filename = "{UNSET_CONS}";
}
public Ref( string filename )
{ public Ref( string filename )
m_filename = filename; {
} _filename = filename;
}
virtual public void OnSerialize()
{ virtual public void OnSerialize()
} {
}
virtual public void OnDeserialize( object enclosing )
{ virtual public void OnDeserialize( object enclosing )
} {
}
virtual public void OnChange()
{ virtual public void OnChange()
} {
}
virtual internal void load()
{ virtual internal void load()
{
}
}
protected string m_filename;
} protected string _filename = "{UNSET_INLINE}";
}
[Serializable]
public class Ref<T> : Ref where T : class [Serializable]
{ public class Ref<T> : Ref where T : class
public T res => m_res != null ? m_res : (m_res = Mgr.load<T>( filename )); {
public T res => m_res != null ? m_res : ( m_res = Mgr.load<T>( Filename ) );
//For serialization
public Ref() //For serialization
: public Ref()
base( "{unknown}" ) :
{ base( "{unknown}" )
} {
}
public Ref( string filename )
: public Ref( string filename )
base( filename ) :
{ base( filename )
} {
}
/*
public Ref( string filename, T res ) : base( filename ) /*
{ public Ref( string filename, T res ) : base( filename )
m_res = res; {
} m_res = res;
*/ }
*/
override internal void load()
{ override internal void load()
m_res = Mgr.load<T>( filename ); {
} m_res = Mgr.load<T>( Filename );
}
[NonSerialized]
private T m_res; [NonSerialized]
private T m_res;
}
}
public class Resource
{ public class Resource
static public Mgr mgr; {
static public Mgr mgr;
}
}
/*
public class Loader<T> /*
{ public class Loader<T>
static public T load( string filename ) {
{ static public T load( string filename )
Debug.Assert( false, "Specialize Loader for your type for file" ); {
return default(T); Debug.Assert( false, "Specialize Loader for your type for file" );
} return default(T);
} }
*/ }
*/
public delegate T Load<out T>( string filename );
public delegate T Load<out T>( string filename );
class LoadHolder
{ class LoadHolder
internal virtual object load() {
{ internal virtual object load()
return null; {
} return null;
} }
}
class LoadHolder<T> : LoadHolder
{ class LoadHolder<T> : LoadHolder
public LoadHolder( Load<T> fnLoad ) {
{ public LoadHolder( Load<T> fnLoad )
m_fnLoad = fnLoad; {
} m_fnLoad = fnLoad;
}
public Load<T> m_fnLoad;
public Load<T> m_fnLoad;
internal override object load()
{ internal override object load()
return load(); {
} return load();
} }
}
//generic classes make a new static per generic type
class ResCache<T> where T : class //generic classes make a new static per generic type
{ class ResCache<T> where T : class
public static T s_default = default; {
public static ImmutableDictionary<string, WeakReference<T>> s_cache = ImmutableDictionary<string, WeakReference<T>>.Empty; public static T s_default = default;
public static ImmutableDictionary<string, WeakReference<T>> s_cache = ImmutableDictionary<string, WeakReference<T>>.Empty;
}
}
public class Mgr
{ public class Mgr
{
static public void startup()
{ static public void startup()
Resource.mgr = new Mgr(); {
} Resource.mgr = new Mgr();
}
static public void register<T>( Load<T> loader )
{ static public void register<T>( Load<T> loader )
Debug.Assert( !Resource.mgr.m_loaders.ContainsKey( typeof( T ) ) ); {
Debug.Assert( !Resource.mgr.m_loaders.ContainsKey( typeof( T ) ) );
var lh = new LoadHolder<T>( loader );
var lh = new LoadHolder<T>( loader );
ImmutableInterlocked.TryAdd( ref Resource.mgr.m_loaders, typeof( T ), lh );
} ImmutableInterlocked.TryAdd( ref Resource.mgr.m_loaders, typeof( T ), lh );
}
//Register all subclasses of a particular type
//???? Should we just always do this? //Register all subclasses of a particular type
static public void registerSub( Type baseType ) //???? Should we just always do this?
{ static public void registerSub( Type baseType )
log.info( $"Registering loader for {baseType.Name}" ); {
log.info( $"Registering loader for {baseType.Name}" );
Type[] typeParams = new Type[1];
foreach( var mi in baseType.GetMethods() ) Type[] typeParams = new Type[1];
{ foreach( var mi in baseType.GetMethods() )
if( mi.Name == "res_load" && mi.IsGenericMethod ) {
{ if( mi.Name == "res_load" && mi.IsGenericMethod )
foreach( var ass in AppDomain.CurrentDomain.GetAssemblies() ) {
{ foreach( var ass in AppDomain.CurrentDomain.GetAssemblies() )
foreach( var t in ass.GetTypes() ) {
{ foreach( var t in ass.GetTypes() )
if( !baseType.IsAssignableFrom( t ) ) continue; {
if( !baseType.IsAssignableFrom( t ) )
log.debug( $"Making a lodaer for {t.Name}" ); continue;
typeParams[0] = t; log.debug( $"Making a lodaer for {t.Name}" );
var mi_ng = mi.MakeGenericMethod( typeParams );
typeParams[0] = t;
var loadGenType = typeof(Load<>); var mi_ng = mi.MakeGenericMethod( typeParams );
var loadType = loadGenType.MakeGenericType( t ); var loadGenType = typeof( Load<> );
var loader = Delegate.CreateDelegate( loadType, mi_ng ); var loadType = loadGenType.MakeGenericType( t );
var lhGenType = typeof(LoadHolder<>); var loader = Delegate.CreateDelegate( loadType, mi_ng );
var lhType = lhGenType.MakeGenericType( t ); var lhGenType = typeof( LoadHolder<> );
var lh = Activator.CreateInstance( lhType, loader ) as LoadHolder; var lhType = lhGenType.MakeGenericType( t );
ImmutableInterlocked.TryAdd( ref Resource.mgr.m_loaders, t, lh ); var lh = Activator.CreateInstance( lhType, loader ) as LoadHolder;
}
} ImmutableInterlocked.TryAdd( ref Resource.mgr.m_loaders, t, lh );
return; }
} }
} return;
} }
}
}
static public Ref<T> lookup<T>( string filename ) where T : class
{
/* static public Ref<T> lookup<T>( string filename ) where T : class
LoadHolder loader_gen; {
Resource.mgr.m_loaders.TryGetValue( typeof( T ), out loader_gen ); /*
LoadHolder loader_gen;
var loaderHolder = loader_gen as LoadHolder<T>; Resource.mgr.m_loaders.TryGetValue( typeof( T ), out loader_gen );
if( loaderHolder != null ) var loaderHolder = loader_gen as LoadHolder<T>;
{
var rf_raw = loaderHolder.dlgtLoad( filename ); if( loaderHolder != null )
Ref<T> rf = rf_raw as Ref<T>; {
return rf; var rf_raw = loaderHolder.dlgtLoad( filename );
} Ref<T> rf = rf_raw as Ref<T>;
*/ return rf;
}
return new Ref<T>( filename ); */
}
return new Ref<T>( filename );
//* }
static public Ref lookup( string filename, Type t )
{ //*
/* static public Ref lookup( string filename, Type t )
LoadHolder loader_gen; {
Resource.mgr.m_loaders.TryGetValue( t, out loader_gen ); /*
LoadHolder loader_gen;
var lhGenType = typeof(LoadHolder<>); Resource.mgr.m_loaders.TryGetValue( t, out loader_gen );
var lhGenType = typeof(LoadHolder<>);
if( loaderHolder != null )
{
var rf_raw = loaderHolder.load( filename ); if( loaderHolder != null )
return rf_raw; {
} var rf_raw = loaderHolder.load( filename );
*/ return rf_raw;
}
return new Ref( filename ); */
}
//*/ return new Ref( filename );
}
static public T load<T>( string filename ) where T : class //*/
{
if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) ) static public T load<T>( string filename ) where T : class
{ {
if( wr.TryGetTarget( out var v ) ) if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) )
return v; {
if( wr.TryGetTarget( out var v ) )
log.info( $"{filename} was in cache, but its been dropped, reloading." ); return v;
}
log.info( $"{filename} was in cache, but its been dropped, reloading." );
log.warn( $"Block Loading {filename}." ); }
var newV = actualLoad<T>( filename ); log.warn( $"Block Loading {filename}." );
return newV; var newV = actualLoad<T>( filename );
}
return newV;
static public T actualLoad<T>( string filename ) where T : class }
{
if( s_loading.TryGetValue( filename, out var evt ) ) static public T actualLoad<T>( string filename ) where T : class
{ {
evt.WaitOne(); if( s_loading.TryGetValue( filename, out var evt ) )
{
if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) ) evt.WaitOne();
{
if( wr.TryGetTarget( out var v ) ) if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) )
return v; {
if( wr.TryGetTarget( out var v ) )
log.error( $"{filename} was in cache, but its been dropped, reloading." ); return v;
}
} log.error( $"{filename} was in cache, but its been dropped, reloading." );
}
var evtNew = new AutoResetEvent( false ); }
if( ImmutableInterlocked.TryAdd( ref s_loading, filename, evtNew ) ) var evtNew = new AutoResetEvent( false );
{
if( Resource.mgr.m_loaders.TryGetValue( typeof( T ), out var loaderGen ) ) if( ImmutableInterlocked.TryAdd( ref s_loading, filename, evtNew ) )
{ {
var loader = loaderGen as LoadHolder<T>; if( Resource.mgr.m_loaders.TryGetValue( typeof( T ), out var loaderGen ) )
{
var v = loader.m_fnLoad( filename ); var loader = loaderGen as LoadHolder<T>;
var weak = new WeakReference<T>( v ); var v = loader.m_fnLoad( filename );
var alreadyAdded = !ImmutableInterlocked.TryAdd( ref ResCache<T>.s_cache, filename, weak ); var weak = new WeakReference<T>( v );
evtNew.Set(); var alreadyAdded = !ImmutableInterlocked.TryAdd( ref ResCache<T>.s_cache, filename, weak );
//Done loading evtNew.Set();
if( !ImmutableInterlocked.TryRemove( ref s_loading, filename, out var oldEvt ) )
{ //Done loading
log.error( $"Error removing loading event for {filename}" ); if( !ImmutableInterlocked.TryRemove( ref s_loading, filename, out var oldEvt ) )
} {
log.error( $"Error removing loading event for {filename}" );
if( alreadyAdded ) }
{
log.error( $"Key {filename} already existed, though it shouldnt." ); if( alreadyAdded )
} {
log.error( $"Key {filename} already existed, though it shouldnt." );
return v; }
}
else return v;
{ }
log.error( $"Loader could not be found for type {typeof( T )}" ); else
{
return ResCache<T>.s_default; log.error( $"Loader could not be found for type {typeof( T )}" );
}
} return ResCache<T>.s_default;
}
return actualLoad<T>( filename ); }
}
return actualLoad<T>( filename );
static object s_loadingLock = new object(); }
static ImmutableDictionary< string, AutoResetEvent > s_loading = ImmutableDictionary< string, AutoResetEvent >.Empty; static object s_loadingLock = new object();
static ImmDefLoad s_deferredLoad = ImmDefLoad.Empty;
static ImmutableDictionary<string, AutoResetEvent> s_loading = ImmutableDictionary<string, AutoResetEvent>.Empty;
static ImmDefLoad s_deferredLoad = ImmDefLoad.Empty;
Mgr()
{
log.info( $"Creating Res.Mgr" ); Mgr()
{
var ts = new ThreadStart( deferredLoader ); log.info( $"Creating Res.Mgr" );
m_deferredLoader = new Thread( ts ); var ts = new ThreadStart( deferredLoader );
m_deferredLoader.Start(); m_deferredLoader = new Thread( ts );
}
m_deferredLoader.Start();
void deferredLoader() }
{
while( true ) void deferredLoader()
{ {
Thread.Sleep( 1 ); while( true )
{
if( ImmutableInterlocked.TryDequeue( ref s_deferredLoad, out var v ) ) Thread.Sleep( 1 );
{
v.Item2.load(); if( ImmutableInterlocked.TryDequeue( ref s_deferredLoad, out var v ) )
} {
} v.Item2.load();
} }
}
}
ImmutableDictionary<Type, LoadHolder> m_loaders = ImmutableDictionary<Type, LoadHolder>.Empty;
Thread m_deferredLoader; ImmutableDictionary<Type, LoadHolder> m_loaders = ImmutableDictionary<Type, LoadHolder>.Empty;
} Thread m_deferredLoader;
}
}
}

View File

@ -175,7 +175,7 @@ namespace lib
} }
#region Deserialize #region Deserialize
private static FormatterConverter s_conv = new FormatterConverter(); private static FormatterConverter s_conv = new();
public object Deserialize( Stream stream ) public object Deserialize( Stream stream )
@ -188,7 +188,7 @@ namespace lib
public object DeserializeKnownType( Stream stream, Type t ) public object DeserializeKnownType( Stream stream, Type t )
{ {
XmlTextReader reader = new XmlTextReader( stream ); XmlTextReader reader = new( stream );
object obj = Deserialize( reader, t ); object obj = Deserialize( reader, t );
@ -262,7 +262,7 @@ namespace lib
private object Deserialize( XmlElement elem, MemberInfo mi, Type type, object existing /*, object enclosing = null*/ ) private object Deserialize( XmlElement elem, MemberInfo mi, Type type, object existing /*, object enclosing = null*/ )
{ {
string name = mi?.Name ?? "{NOT_FOUND}"; var name = mi?.Name ?? "{NOT_FOUND}";
return Deserialize( elem, mi, type, name, existing ); return Deserialize( elem, mi, type, name, existing );
} }
@ -312,17 +312,17 @@ namespace lib
return existing; return existing;
} }
Type[] mm_types = new Type[1];
private object GetDefault( Type t ) private object GetDefault( Type t )
{ {
mm_types[0] = t; var types = new Type[1];
types[0] = t;
var fn = GetType().GetMethod( "GetDefaultGeneric" ).MakeGenericMethod( mm_types ); var fn = GetType().GetMethod( "GetDefaultGeneric" ).MakeGenericMethod( types );
return fn.Invoke( this, null ); return fn.Invoke( this, null );
} }
public T GetDefaultGeneric<T>() static public T GetDefaultGeneric<T>()
{ {
return default( T ); return default( T );
} }
@ -436,9 +436,9 @@ namespace lib
{ {
var node = objNode as XmlElement; var node = objNode as XmlElement;
String name = node.Name; string name = node.Name;
String childType = node.GetAttribute( "_.t" ); string childType = node.GetAttribute( "_.t" );
name = refl.TypeToIdentifier( name ); name = refl.TypeToIdentifier( name );
@ -455,7 +455,7 @@ namespace lib
//object objUn = FormatterServices.GetSafeUninitializedObject( finalType ); //object objUn = FormatterServices.GetSafeUninitializedObject( finalType );
IDeserializationCallback objUnOnDeser = obj as IDeserializationCallback; var objUnOnDeser = obj as IDeserializationCallback;
mm_consType[0] = typeof( SerializationInfo ); mm_consType[0] = typeof( SerializationInfo );
mm_consType[1] = typeof( StreamingContext ); mm_consType[1] = typeof( StreamingContext );
@ -479,7 +479,7 @@ namespace lib
foreach( var serMember in serInfo ) foreach( var serMember in serInfo )
{ {
String name = serMember.Name; string name = serMember.Name;
name = refl.TypeToIdentifier( name ); name = refl.TypeToIdentifier( name );
@ -512,7 +512,7 @@ namespace lib
foreach( FieldInfo childFi in fields ) foreach( FieldInfo childFi in fields )
{ {
String name = childFi.Name; string name = childFi.Name;
var dontAtt = childFi.GetCustomAttributes<lib.Dont>(); var dontAtt = childFi.GetCustomAttributes<lib.Dont>();
@ -581,7 +581,7 @@ namespace lib
foreach( var childPi in props ) foreach( var childPi in props )
{ {
String name = childPi.Name; string name = childPi.Name;
var dontAtt = childPi.GetCustomAttributes<lib.Dont>(); var dontAtt = childPi.GetCustomAttributes<lib.Dont>();
if( dontAtt.Any() ) if( dontAtt.Any() )
{ {
@ -1155,7 +1155,7 @@ namespace lib
foreach( var serMember in serInfo ) foreach( var serMember in serInfo )
{ {
String name = serMember.Name; string name = serMember.Name;
name = refl.TypeToIdentifier( name ); name = refl.TypeToIdentifier( name );
@ -1206,7 +1206,7 @@ namespace lib
foreach( var childFi in fields ) foreach( var childFi in fields )
{ {
String name = childFi.Name; string name = childFi.Name;
var dontAtt = childFi.GetCustomAttributes<lib.Dont>(); var dontAtt = childFi.GetCustomAttributes<lib.Dont>();
string propName = ""; string propName = "";
@ -1255,7 +1255,7 @@ namespace lib
foreach( var childPi in props ) foreach( var childPi in props )
{ {
String name = childPi.Name; string name = childPi.Name;
var dontAtt = childPi.GetCustomAttributes<lib.Dont>(); var dontAtt = childPi.GetCustomAttributes<lib.Dont>();
if( dontAtt.Any() ) if( dontAtt.Any() )