Whitespace fixes

This commit is contained in:
Marc Hernandez 2021-06-19 00:04:20 -07:00
parent 1f495bfd0e
commit 2acdb68828

View File

@ -1,357 +1,357 @@
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)>;
[Serializable] [Serializable]
public class Ref: lib.I_Serialize public class Ref : lib.I_Serialize
{ {
public string filename { get { return m_filename; } } public string filename { get { return m_filename; } }
//For construction //For construction
public Ref() public Ref()
{ {
} }
public Ref( string filename ) public Ref( string filename )
{ {
m_filename = filename; m_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()
{ {
} }
private string m_filename; private string m_filename;
} }
[Serializable] [Serializable]
public class Ref<T>: Ref where T : class 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 //For serialization
public Ref() 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] [NonSerialized]
private T m_res; private T m_res;
}
public class Resource
{
static public Mgr mgr;
} }
/*
public class Loader<T>
{ public class Resource
static public T load( string filename ) {
{ static public Mgr mgr;
Debug.Assert( false, "Specialize Loader for your type for file" );
return default(T); }
}
}
/*
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 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> _dlgtLoad ) public LoadHolder( Load<T> _dlgtLoad )
{ {
dlgtLoad = _dlgtLoad; dlgtLoad = _dlgtLoad;
} }
public Load<T> dlgtLoad; public Load<T> dlgtLoad;
internal override object load() internal override object load()
{ {
return load(); return load();
} }
} }
//generic classes make a new static per generic type //generic classes make a new static per generic type
class ResCache<T> where T : class class ResCache<T> where T : class
{ {
public static T s_default = default; public static T s_default = default;
public static ImmutableDictionary<string, WeakReference<T>> s_cache = ImmutableDictionary<string, WeakReference<T>>.Empty; 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 //Register all subclasses of a particular type
//???? Should we just always do this? //???? Should we just always do this?
static public void registerSub( Type baseType ) static public void registerSub( Type baseType )
{
Type[] typeParams = new Type[1];
foreach( var mi in baseType.GetMethods() )
{
if( mi.Name == "res_load" && mi.IsGenericMethod )
{
foreach( var ass in AppDomain.CurrentDomain.GetAssemblies() )
{
foreach( var t in ass.GetTypes() )
{
if( t.IsSubclassOf( baseType ) )
{
typeParams[0] = t;
var mi_ng = mi.MakeGenericMethod( typeParams );
var loadGenType = typeof(Load<>);
var loadType = loadGenType.MakeGenericType( t );
var loader = Delegate.CreateDelegate( loadType, mi_ng );
var lhGenType = typeof(LoadHolder<>);
var lhType = lhGenType.MakeGenericType( t );
var lh = Activator.CreateInstance( lhType, loader ) as LoadHolder;
ImmutableInterlocked.TryAdd( ref Resource.mgr.m_loaders, t, lh );
}
}
}
return;
}
}
}
static public Ref<T> lookup<T>( string filename ) where T : class
{ {
/*
LoadHolder loader_gen; Type[] typeParams = new Type[1];
Resource.mgr.m_loaders.TryGetValue( typeof( T ), out loader_gen ); foreach( var mi in baseType.GetMethods() )
{
var loaderHolder = loader_gen as LoadHolder<T>; if( mi.Name == "res_load" && mi.IsGenericMethod )
{
if( loaderHolder != null ) foreach( var ass in AppDomain.CurrentDomain.GetAssemblies() )
{ {
var rf_raw = loaderHolder.dlgtLoad( filename ); foreach( var t in ass.GetTypes() )
Ref<T> rf = rf_raw as Ref<T>; {
return rf; if( t.IsSubclassOf( baseType ) )
} {
typeParams[0] = t;
var mi_ng = mi.MakeGenericMethod( typeParams );
var loadGenType = typeof(Load<>);
var loadType = loadGenType.MakeGenericType( t );
var loader = Delegate.CreateDelegate( loadType, mi_ng );
var lhGenType = typeof(LoadHolder<>);
var lhType = lhGenType.MakeGenericType( t );
var lh = Activator.CreateInstance( lhType, loader ) as LoadHolder;
ImmutableInterlocked.TryAdd( ref Resource.mgr.m_loaders, t, lh );
}
}
}
return;
}
}
}
static public Ref<T> lookup<T>( string filename ) where T : class
{
/*
LoadHolder loader_gen;
Resource.mgr.m_loaders.TryGetValue( typeof( T ), out loader_gen );
var loaderHolder = loader_gen as LoadHolder<T>;
if( loaderHolder != null )
{
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; LoadHolder loader_gen;
Resource.mgr.m_loaders.TryGetValue( t, out loader_gen ); Resource.mgr.m_loaders.TryGetValue( t, out loader_gen );
var lhGenType = typeof(LoadHolder<>); var lhGenType = typeof(LoadHolder<>);
if( loaderHolder != null ) if( loaderHolder != null )
{ {
var rf_raw = loaderHolder.load( filename ); var rf_raw = loaderHolder.load( filename );
return rf_raw; return rf_raw;
} }
*/ */
return new Ref( filename ); return new Ref( filename );
} }
//*/ //*/
static public T load<T>( string filename ) where T : class static public T load<T>( string filename ) where T : class
{ {
if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) ) if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) )
{ {
if( wr.TryGetTarget( out var v ) ) if( wr.TryGetTarget( out var v ) )
return v; return v;
log.info( $"{filename} was in cache, but its been dropped, reloading." ); lib.Log.info( $"{filename} was in cache, but its been dropped, reloading." );
} }
log.warn( $"Block Loading {filename}." ); lib.Log.warn( $"Block Loading {filename}." );
var newV = actualLoad<T>( filename ); var newV = actualLoad<T>( filename );
return newV; return newV;
} }
static public T actualLoad<T>( string filename ) where T : class static public T actualLoad<T>( string filename ) where T : class
{ {
if( s_loading.TryGetValue( filename, out var evt ) ) if( s_loading.TryGetValue( filename, out var evt ) )
{ {
evt.WaitOne(); evt.WaitOne();
if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) ) if( ResCache<T>.s_cache.TryGetValue( filename, out var wr ) )
{ {
if( wr.TryGetTarget( out var v ) ) if( wr.TryGetTarget( out var v ) )
return v; return v;
log.error( $"{filename} was in cache, but its been dropped, reloading." ); lib.Log.error( $"{filename} was in cache, but its been dropped, reloading." );
} }
} }
var evtNew = new AutoResetEvent( false ); var evtNew = new AutoResetEvent( false );
if( ImmutableInterlocked.TryAdd( ref s_loading, filename, evtNew ) ) if( ImmutableInterlocked.TryAdd( ref s_loading, filename, evtNew ) )
{ {
if( Resource.mgr.m_loaders.TryGetValue( typeof( T ), out var loaderGen ) ) if( Resource.mgr.m_loaders.TryGetValue( typeof( T ), out var loaderGen ) )
{ {
var loader = loaderGen as LoadHolder<T>; var loader = loaderGen as LoadHolder<T>;
var v = loader.dlgtLoad( filename ); var v = loader.dlgtLoad( filename );
var weak = new WeakReference<T>( v ); var weak = new WeakReference<T>( v );
var alreadyAdded = !ImmutableInterlocked.TryAdd( ref ResCache<T>.s_cache, filename, weak ); var alreadyAdded = !ImmutableInterlocked.TryAdd( ref ResCache<T>.s_cache, filename, weak );
evtNew.Set(); evtNew.Set();
//Done loading //Done loading
if( !ImmutableInterlocked.TryRemove( ref s_loading, filename, out var oldEvt ) ) if( !ImmutableInterlocked.TryRemove( ref s_loading, filename, out var oldEvt ) )
{ {
log.error( $"Error removing loading event for {filename}" ); lib.Log.error( $"Error removing loading event for {filename}" );
} }
if( alreadyAdded ) if( alreadyAdded )
{ {
log.error( $"Key {filename} already existed, though it shouldnt." ); lib.Log.error( $"Key {filename} already existed, though it shouldnt." );
} }
return v; return v;
} }
else else
{ {
log.error( $"Loader could not be found for type {typeof( T )}" ); lib.Log.error( $"Loader could not be found for type {typeof( T )}" );
return ResCache<T>.s_default; return ResCache<T>.s_default;
} }
} }
return actualLoad<T>( filename ); return actualLoad<T>( filename );
} }
static object s_loadingLock = new object(); static object s_loadingLock = new object();
static ImmutableDictionary< string, AutoResetEvent > s_loading = ImmutableDictionary< string, AutoResetEvent >.Empty; static ImmutableDictionary< string, AutoResetEvent > s_loading = ImmutableDictionary< string, AutoResetEvent >.Empty;
static ImmDefLoad s_deferredLoad = ImmDefLoad.Empty; static ImmDefLoad s_deferredLoad = ImmDefLoad.Empty;
Mgr() Mgr()
{ {
var ts = new ThreadStart( deferredLoader ); var ts = new ThreadStart( deferredLoader );
m_deferredLoader = new Thread( ts ); m_deferredLoader = new Thread( ts );
m_deferredLoader.Start(); m_deferredLoader.Start();
} }
void deferredLoader() void deferredLoader()
{ {
while( true ) while( true )
{ {
Thread.Sleep( 1 ); Thread.Sleep( 1 );
if( ImmutableInterlocked.TryDequeue( ref s_deferredLoad, out var v ) ) if( ImmutableInterlocked.TryDequeue( ref s_deferredLoad, out var v ) )
{ {
v.Item2.load(); v.Item2.load();
} }
} }
} }
ImmutableDictionary<Type, LoadHolder> m_loaders = ImmutableDictionary<Type, LoadHolder>.Empty; ImmutableDictionary<Type, LoadHolder> m_loaders = ImmutableDictionary<Type, LoadHolder>.Empty;
Thread m_deferredLoader; Thread m_deferredLoader;
} }
} }