2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-07-01 00:31:56 +00:00

Import code from previous AssetBuilder version

This commit is contained in:
Jan
2019-09-24 10:45:09 +02:00
parent 5609557516
commit 0d8432d4f7
919 changed files with 154412 additions and 26 deletions

View File

@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.IO;
using ZoneCodeGenerator.Domain.StructureInformation;
using ZoneCodeGenerator.Interface;
using ZoneCodeGenerator.Persistence;
namespace ZoneCodeGenerator.Generating
{
static class CodeGenerator
{
private class GeneratorPreset
{
public string FileName { get; }
public string TemplateName { get; }
public GeneratorPreset(string fileName, string templateName)
{
FileName = fileName;
TemplateName = templateName;
}
}
private static readonly Dictionary<string, GeneratorPreset> presets =
new Dictionary<string, GeneratorPreset>(StringComparer.CurrentCultureIgnoreCase)
{
{
"ZoneLoad", new GeneratorPreset("$asset/$asset_load_db", "ZoneLoad.stg")
},
{
"ZoneWrite", new GeneratorPreset("$asset/$asset_write_db", "ZoneWrite.stg")
}
};
public static IEnumerable<string> Presets => presets.Keys;
public static bool GenerateCodeForPreset(string presetName, StructureInformation asset, CUISession session)
{
if (!presets.ContainsKey(presetName))
return false;
var preset = presets[presetName];
try
{
if (!Directory.Exists(session.GeneratorOutputPath))
Directory.CreateDirectory(session.GeneratorOutputPath);
var codeTemplate = CodeTemplate.FromResources(preset.TemplateName);
if (codeTemplate == null)
{
Console.WriteLine($"Could not find template '{preset.TemplateName}'");
return false;
}
var resolvedFileName = preset.FileName.Replace("$asset", asset.Type.Name.ToLower());
var fullPath = Path.Combine(session.GeneratorOutputPath, resolvedFileName);
var folderOfFile = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(folderOfFile))
Directory.CreateDirectory(folderOfFile);
var renderingContext = RenderingContext.BuildContext(session, asset);
if (renderingContext == null)
return false;
var generatedCode = false;
if (codeTemplate.HasHeaderTemplate)
{
generatedCode = true;
using (var fileStream = new FileStream(fullPath + ".h", FileMode.Create))
{
codeTemplate.RenderHeaderFile(fileStream, renderingContext);
fileStream.Close();
}
}
if (codeTemplate.HasSourceTemplate)
{
generatedCode = true;
using (var fileStream = new FileStream(fullPath + ".cpp", FileMode.Create))
{
codeTemplate.RenderSourceFile(fileStream, renderingContext);
fileStream.Close();
}
}
return generatedCode;
}
catch (Exception)
{
return false;
}
}
}
}

View File

@ -0,0 +1,54 @@
using System.IO;
using Antlr4.StringTemplate;
namespace ZoneCodeGenerator.Generating
{
class CodeTemplate
{
private const string SourceTemplateName = "source";
private const string HeaderTemplateName = "header";
private readonly TemplateGroup templateGroup;
public bool HasSourceTemplate => templateGroup.IsDefined(SourceTemplateName);
public bool HasHeaderTemplate => templateGroup.IsDefined(HeaderTemplateName);
private CodeTemplate(TemplateGroup templateGroup)
{
this.templateGroup = templateGroup;
templateGroup.RegisterRenderer(typeof(string), new StringRenderer());
}
public static CodeTemplate FromResources(string fileName)
{
var templateGroup = new TemplateGroupResources(fileName);
templateGroup.Load();
return new CodeTemplate(templateGroup);
}
public void RenderSourceFile(Stream stream, RenderingContext context)
{
RenderTemplate(stream, templateGroup.GetInstanceOf(SourceTemplateName), context);
}
public void RenderHeaderFile(Stream stream, RenderingContext context)
{
RenderTemplate(stream, templateGroup.GetInstanceOf(HeaderTemplateName), context);
}
private static void RenderTemplate(Stream stream, Template template, RenderingContext context)
{
if (template == null)
return;
template.Add("context", context);
using (var writer = new StreamWriter(stream))
{
template.Write(new AutoIndentWriter(writer));
}
}
}
}

View File

@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ZoneCodeGenerator.Domain;
using ZoneCodeGenerator.Domain.FastFileStructure;
using ZoneCodeGenerator.Domain.StructureInformation;
using ZoneCodeGenerator.Interface;
using ZoneCodeGenerator.Persistence;
namespace ZoneCodeGenerator.Generating
{
class RenderingContext
{
public string Game { get; set; }
public StructureInformation Asset { get; set; }
public HashSet<StructureInformation> Structures { get; }
public IEnumerable<StructureInformation> ReferencedAssets => Structures.Where(inf => inf.IsAsset && inf != Asset);
public List<FastFileBlock> Blocks { get; private set; }
public FastFileBlock DefaultNormalBlock => Blocks.FirstOrDefault(block => block.IsDefault && block.IsNormal) ??
Blocks.FirstOrDefault(block => block.IsNormal);
private RenderingContext()
{
Structures = new HashSet<StructureInformation>();
}
private void AddToContext(StructureInformation structureInformation)
{
if (!Structures.Add(structureInformation))
return;
if (structureInformation.IsAsset && structureInformation != Asset)
return;
foreach (var member in structureInformation.OrderedMembers)
{
if(member.StructureType != null)
AddToContext(member.StructureType);
}
}
public static RenderingContext BuildContext(CUISession session, StructureInformation asset)
{
var context = new RenderingContext
{
Asset = asset,
Game = session.Game,
Blocks = session.Repository.GetAllFastFileBlocks().ToList()
};
context.AddToContext(asset);
return context;
}
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.IO;
using System.Reflection;
using Antlr.Runtime;
using Antlr4.StringTemplate;
using Antlr4.StringTemplate.Compiler;
using Antlr4.StringTemplate.Misc;
namespace ZoneCodeGenerator.Generating
{
public class TemplateGroupResources : TemplateGroup
{
private const string ResourceBasePath = "ZoneCodeGenerator.Generating.Templates";
private const char DefaultDelimiterStart = '<';
private const char DefaultDelimiterStop = '>';
private bool alreadyLoaded;
private readonly string fileName;
public TemplateGroupResources(string fileName, char delimiterStartChar, char delimiterStopChar) : base(delimiterStartChar, delimiterStopChar)
{
this.fileName = fileName;
alreadyLoaded = false;
}
public TemplateGroupResources(string fileName) : this(fileName, DefaultDelimiterStart, DefaultDelimiterStop)
{
}
public override void ImportTemplates(IToken fileNameToken)
{
var text = Utility.Strip(fileNameToken.Text, 1);
TemplateGroup importingGroup = null;
if (text.EndsWith(GroupFileExtension))
{
importingGroup = new TemplateGroupResources(text, DelimiterStartChar, DelimiterStopChar);
}
else if (text.EndsWith(TemplateFileExtension))
{
importingGroup = new TemplateGroup(DelimiterStartChar, DelimiterStopChar);
using (var resourceStream = StreamFromResources(text))
{
if (resourceStream != null)
{
using (var textStream = new StreamReader(resourceStream))
{
var inputStream = new ANTLRReaderStream(textStream)
{
name = fileName
};
importingGroup.LoadTemplateFile("/", fileName, inputStream);
}
}
}
}
if (importingGroup != null)
{
importingGroup.Load();
ImportTemplates(importingGroup);
}
else
{
ErrorManager.CompiletimeError(ErrorType.CANT_IMPORT, null, fileNameToken, text);
}
}
public override void Load()
{
if (alreadyLoaded)
return;
alreadyLoaded = true;
if (Verbose)
Console.WriteLine($"loading group file '{fileName}'");
using (var resourceStream = StreamFromResources(fileName))
{
if (resourceStream == null)
{
if (Verbose)
Console.WriteLine($"Resource '{fileName}' doesn't exist");
return;
}
using (var textStream = new StreamReader(resourceStream))
{
var inputStream = new ANTLRReaderStream(textStream)
{
name = fileName
};
try
{
var lexer = new GroupLexer(inputStream);
var tokenStream = new CommonTokenStream(lexer);
var parser = new GroupParser(tokenStream);
parser.group(this, "/");
}
catch (Exception ex)
{
ErrorManager.IOError(null, ErrorType.CANT_LOAD_GROUP_FILE, ex, FileName);
}
}
}
}
private static Stream StreamFromResources(string fileName)
{
var resourceName = $"{ResourceBasePath}.{fileName}";
var assembly = Assembly.GetExecutingAssembly();
return assembly.GetManifestResourceStream(resourceName);
}
public override string Name => "TemplateGroupResources";
public override string FileName => Name;
}
}

View File

@ -0,0 +1,2 @@
test() ::= <<
>>

View File

@ -0,0 +1,225 @@
delimiters "$", "$"
import "Common.stg"
Capital(name) ::= "$name; format=\"cap\"$"
LoaderClassName(asset) ::= "Loader_$asset.Type.Name$"
HeaderConstructor(context) ::= "$LoaderClassName(context.Asset)$(IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream);"
HeaderPtrLoadMethodDeclaration(structure) ::= "void LoadPtr_$structure.Type.Name$($structure.Type.FullName$** pPtr);"
HeaderArrayLoadMethodDeclaration(structure) ::= "void LoadArray_$structure.Type.Name$($structure.Type.FullName$** pArray, size_t count, bool atStreamStart);"
HeaderLoadMethodDeclaration(structure) ::= "void Load_$structure.Type.Name$($structure.Type.FullName$** p$structure.Type.Name$, bool atStreamStart);"
HeaderGetNameMethodDeclaration(asset) ::= "static std::string GetAssetName($asset.Type.FullName$* p$asset.Type.Name$);"
HeaderAssetLoadMethodDeclaration(asset) ::= "void LoadAsset_$asset.Type.Name$($asset.Type.FullName$** pPtr);"
HeaderDeclaration(structure) ::= <%
$if(structure.PointerReferenceExists)$
$HeaderPtrLoadMethodDeclaration(structure)$
$\n$
$endif$
$if(structure.ArrayReferenceExists)$
$HeaderArrayLoadMethodDeclaration(structure)$
$\n$
$endif$
$if(structure.NonEmbeddedReferenceExists)$
$HeaderLoadMethodDeclaration(structure)$
$\n$
$endif$
%>
// =======================
// Header file entry point
// =======================
header(context) ::= <<
// ====================================================================
// This file has been generated by ZoneCodeGenerator.
// Do not modify.
// Any changes will be discarded when regenerating.
// ====================================================================
#pragma once
#include "Loading/AssetLoader.h"
#include "Game/$context.Game$/$context.Game$.h"
#include <string>
namespace $context.Game$
{
class $LoaderClassName(context.Asset)$
{
$context.Structures:{structure | $if(!structure.IsAsset)$$HeaderDeclaration(structure)$$endif$}$
$HeaderLoadMethodDeclaration(context.Asset)$
$HeaderAssetLoadMethodDeclaration(context.Asset)$
public:
$HeaderConstructor(context)$
$HeaderPtrLoadMethodDeclaration(context.Asset)$
$HeaderGetNameMethodDeclaration(context.Asset)$
};
}
>>
IncludeHeaderOfOtherAsset(asset) ::= <<
#include "../$asset.Type.Name$/$asset.Type.Name; format="lower"$_load_db.h"
>>
LoadMethod(structure, context) ::= <<
void $LoaderClassName(context.Asset)$::Load_$structure.Type.Name$($structure.Type.FullName$* p$structure.Type.Name$, const bool atStreamStart)
{
assert(p$structure.Type.Name$ != nullptr);
if(atStreamStart)
m_stream->Load<$structure.Type.FullName$>();
$if(structure.Block.IsTemp)$
m_stream->PushBlock($context.DefaultNormalBlock.Name$);
$endif$
// Load content here
$if(structure.Block.IsTemp)$
m_stream->PopBlock();
$endif$
}
>>
LoadPtrMethod(structure, context) ::= <<
void $LoaderClassName(context.Asset)$::LoadPtr_$structure.Type.Name$($structure.Type.FullName$** pPtr)
{
assert(pPtr != nullptr);
m_stream->PushBlock($structure.Block.Name$);
if(*pPtr != nullptr)
{
$if(structure.Block.IsTemp)$
if(*pPtr == PTR_FOLLOWING || *pPtr == PTR_INSERT)
$else$
if(*pPtr == PTR_FOLLOWING)
$endif$
{
$if(structure.Block.IsTemp)$
$structure.Type.FullName$** toInsert = nullptr;
if(*pPtr == PTR_INSERT)
toInsert = m_stream->InsertPointer<$structure.Type.FullName$>();
$endif$
$if(structure.HasNonDefaultAlign)$
*pPtr = m_stream->Alloc<$structure.Type.FullName$>($structure.FastFileAlign$);
$else$
*pPtr = m_stream->Alloc<$structure.Type.FullName$>();
$endif$
Load_$structure.Type.Name$(*pPtr, true);
$if(structure.IsAsset)$
LoadAsset_$structure.Type.Name$(pPtr);
$endif$
$if(structure.Block.IsTemp)$
if(toInsert != nullptr)
*toInsert = *pPtr;
$endif$
}
else
{
$if(structure.Block.IsTemp)$
*pPtr = m_stream->ConvertOffsetToAlias(*ptr);
$else$
*pPtr = m_stream->ConvertOffsetToPointer(*ptr);
$endif$
}
}
m_stream->PopBlock();
}
>>
LoadArrayMethod(structure, context) ::= <<
void $LoaderClassName(context.Asset)$::LoadArray_$structure.Type.Name$($structure.Type.FullName$** pArray, const size_t count, const bool atStreamStart)
{
assert(pArray != nullptr);
if(atStreamStart)
m_stream->Load<$structure.Type.FullName$>(count);
for(size_t index = 0; index < count; index++)
{
Load_$structure.Type.Name$(&pArray[index], false);
}
}
>>
SourceDefinition(structure, context) ::= <<
$if(structure.NonEmbeddedReferenceExists)$
$LoadMethod(structure, context)$
$endif$
$if(structure.PointerReferenceExists)$
$LoadPtrMethod(structure, context)$
$endif$
$if(structure.ArrayReferenceExists)$
$LoadArrayMethod(structure, context)$
$endif$
>>
ConstructorMethod(context) ::= <<
$LoaderClassName(context.Asset)$::$LoaderClassName(context.Asset)$(IZoneScriptStringProvider* scriptStringProvider, Zone* zone, IZoneInputStream* stream)
: AssetLoader($context.Asset.AssetEnumEntry.Name$, scriptStringProvider, zone, stream){}
>>
LoadAssetMethod(structure, context) ::= <<
void $LoaderClassName(context.Asset)$::LoadAsset_$structure.Type.Name$($structure.Type.FullName$** pPtr)
{
assert(pPtr != nullptr);
*pPtr = static_cast<$structure.Type.FullName$*>(LinkAsset(GetAssetName(*pPtr), *pPtr));
}
>>
GetNameMethod(context) ::= <<
std::string $LoaderClassName(context.Asset)$::GetAssetName($context.Asset.Type.FullName$* p$context.Asset.Type.Name$)
{
$if(context.Asset.HasNameMember)$
return p$context.Asset.Type.Name$->name;
$else$
return "$context.Asset.Type.Name$";
$endif$
}
>>
// =======================
// Source file entry point
// =======================
source(context) ::= <<
// ====================================================================
// This file has been generated by ZoneCodeGenerator.
// Do not modify.
// Any changes will be discarded when regenerating.
// ====================================================================
#include "$context.Asset.Type.Name; format="lower"$_load_db.h"
#include <cassert>
// Referenced Assets:
$context.ReferencedAssets:IncludeHeaderOfOtherAsset()$
using namespace $context.Game$;
$ConstructorMethod(context)$
$context.Structures:{structure | $if(!structure.IsAsset)$$SourceDefinition(structure, context)$$endif$}$
$LoadMethod(context.Asset, context)$
$LoadAssetMethod(context.Asset, context)$
$LoadPtrMethod(context.Asset, context)$
$GetNameMethod(context)$
>>

View File

@ -0,0 +1,38 @@
delimiters "$", "$"
import "Common.stg"
WriterClassName(asset) ::= "$asset.Type.Name; format=\"cap\"$ZoneWriter"
// =======================
// Header file entry point
// =======================
header(context) ::= <<
#pragma once
namespace ZoneLoader
{
class $WriterClassName(context.Asset)$
{
public:
// TODO
}
}
>>
IncludeHeaderOfOtherAsset(asset) ::= <<
#include "../$asset.Type.Name$/$asset.Type.Name; format="lower"$_write_db.h"
>>
// =======================
// Source file entry point
// =======================
source(context) ::= <<
#include "$context.Asset.Type.Name; format="lower"$_write_db.h"
// Referenced Assets:
$context.ReferencedAssets:IncludeHeaderOfOtherAsset()$
// TODO
>>