Files
sbox-public/engine/Tools/InteropGen/Writer/BaseWriter.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

152 lines
4.0 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Facepunch.InteropGen;
internal class BaseWriter : CodeWriter
{
public string TargetName;
protected Definition definitions;
public BaseWriter( Definition definitions, string targetName )
{
TargetName = targetName;
this.definitions = definitions;
}
public virtual void Generate()
{
}
public void WriteToFile( string filename, string text )
{
text = text.Replace( "( )", "()" ); // pet peeve
if ( System.IO.File.Exists( filename ) )
{
if ( System.IO.File.ReadAllText( filename ) == text )
{
return;
}
}
System.IO.File.WriteAllText( filename, text );
}
public virtual void SaveToFile( string file )
{
DirectoryInfo fullname = new( System.IO.Path.Combine( definitions.Root.FullName, file ) );
string path = System.IO.Path.GetDirectoryName( fullname.FullName );
CleanSubFiles( fullname.FullName );
foreach ( KeyValuePair<string, string> sub in SubFiles )
{
WriteToFile( System.IO.Path.Combine( path, sub.Key ), sub.Value );
}
Log.WriteLine( $"Writing File {file}" );
WriteToFile( fullname.FullName, sb.ToString() );
}
/// <summary>
/// Delete any children of this filename. Children of interop.hammer.h look like interop.hammer.childname.h.
/// We clear them out incase they're left over from a previous run - since they're quite messy they might be
/// and we'll be in the situation of our code #including stuff that only exists on our local computer.
/// </summary>
private void CleanSubFiles( string filename )
{
string folder = System.IO.Path.GetDirectoryName( filename );
string fileName = System.IO.Path.GetFileNameWithoutExtension( filename );
string extension = System.IO.Path.GetExtension( filename );
foreach ( string file in System.IO.Directory.EnumerateFiles( folder, $"{fileName}.*{extension}" ) )
{
// Don't delete active subfiles, that way we can compare and not rewrite them
if ( SubFiles.ContainsKey( System.IO.Path.GetFileName( file ) ) )
{
continue;
}
System.IO.File.Delete( file );
}
}
public bool ShouldSkip( Class def, string area = "" )
{
//
// Don't import a native class if we already have it in this assembly
//
if ( def.Native && definitions.IsIncluded( def ) )
{
return true;
}
//
// Don't import a native class if we already have it in this assembly
//
if ( definitions.SkipAll.Any( x => x.Classes.Any( y => y.ManagedNameWithNamespace == def.ManagedNameWithNamespace && y.NativeNameWithNamespace == def.NativeNameWithNamespace ) ) )
{
return true;
}
//
// Don't import a native class if we already have it in this assembly
//
return area == "managed-definition" && definitions.isRebind( def );
}
public bool ShouldStubFunction( Class c, Function f )
{
// Stub functions in classes marked with WindowsOnly on non-Windows platforms
return c.HasAttribute( "WindowsOnly" ) && !System.OperatingSystem.IsWindows();
}
public bool ShouldSkip( Struct s, string area = "" )
{
//
// Already included in an include
//
if ( definitions.IsIncluded( s ) )
{
return true;
}
//
// Don't import a native class if we already have it in this assembly
//
return definitions.SkipAll.Any( x => x.Structs.Any( y => y.ManagedNameWithNamespace == s.ManagedNameWithNamespace && y.NativeNameWithNamespace == s.NativeNameWithNamespace ) );
}
public bool ShouldSkipInclude( string include, string area = "" )
{
return definitions.SkipAll.Any( x => x.Includes.Contains( include ) );
}
private System.Text.StringBuilder previousSb;
public Dictionary<string, string> SubFiles = [];
public void StartSubFile()
{
previousSb = sb;
sb = new System.Text.StringBuilder();
}
public string EndSubFile( string moduleName )
{
string ext = System.IO.Path.GetExtension( TargetName );
string fn = System.IO.Path.GetFileNameWithoutExtension( TargetName );
string outName = $"{fn}.{moduleName}{ext}";
SubFiles[outName] = sb.ToString();
sb = previousSb;
return outName;
}
}