rj-action-library/Runtime/Godot/Scenes/Exporters/HTML/SceneFileHTMLExporter.cs

243 lines
7.5 KiB
C#

using Godot;
using System;
using System.Collections.Generic;
namespace Rokojori
{
public class SceneFileHTMLExporter
{
public static readonly XMLElementNodeName GD_ExternalResource = XMLElementNodeName.Create( "gd-external-resource" );
public static readonly XMLElementNodeName GD_SubResource = XMLElementNodeName.Create( "gd-sub-resource" );
public static readonly XMLElementNodeName GD_Node = XMLElementNodeName.Create( "gd-node" );
public static readonly XMLElementNodeName GD_Name = XMLElementNodeName.Create( "gd-name" );
public static readonly XMLElementNodeName GD_Type = XMLElementNodeName.Create( "gd-type" );
public static readonly XMLElementNodeName GD_Script = XMLElementNodeName.Create( "gd-script" );
public static readonly XMLElementNodeName GD_Members = XMLElementNodeName.Create( "gd-members" );
public static readonly XMLElementNodeName GD_Member = XMLElementNodeName.Create( "gd-member" );
public static readonly XMLElementNodeName GD_Children = XMLElementNodeName.Create( "gd-children" );
public static readonly XMLElementNodeName GD_Reference = XMLElementNodeName.Create( "gd-reference" );
SceneFileParser _parser;
XMLDocument _htmlDoc;
XMLElementNode body;
XMLElementNode head;
public static void Convert( string inputPath, string outputPath )
{
var text = FilesSync.LoadUTF8( inputPath );
var parser = new SceneFileParser();
parser.Parse( text );
Export( parser, outputPath );
}
public static void Export( SceneFileParser parser, string path )
{
new SceneFileHTMLExporter().ParseAndExport( parser, path );
}
public void ParseAndExport( SceneFileParser parser, string path )
{
_parser = parser;
CreateHTMLDocument();
AddExternalResources();
AddNodes();
var exportPath = path.EndsWith( ".html" ) ? path : ( path + ".html" );
FilesSync.SaveUTF8( exportPath, new XMLSerializer().SerializeHtml( _htmlDoc.documentElement ) );
}
void CreateHTMLDocument()
{
var doc = XMLDocument.HTML();
var html = doc.documentElement;
body = html.querySelector( HTMLElementName.body );
head = html.querySelector( HTMLElementName.head );
head.AddHTMLScript( SceneFileHTMLScriptJS.script );
head.AddHTMLStyle( SceneFileHTMLStyle.style );
_htmlDoc = doc;
}
void AddExternalResources()
{
var extResources = _parser.sceneFile.extResources;
RJLog.Log( "External Resources:", extResources.Count );
for ( int i = 0; i < extResources.Count; i++ )
{
var resource = extResources[ i ];
var attachmentElement = body;
var resourceElement = _htmlDoc.Create( GD_ExternalResource );
resourceElement.SetAttribute( "class", "resource" );
attachmentElement.AppendChild( resourceElement );
var nameElement = resourceElement.AddElement( GD_Name, resource.path.value );
resourceElement.AddElement( GD_Type, resource.id.value + " " + resource.uid.value + " " + resource.type.value );
resourceElement.SetAttribute( "id", resource.id.value );
attachmentElement.AddElement( HTMLElementName.br );
}
var subResources = _parser.sceneFile.subResources;
RJLog.Log( "Sub Resources:", subResources.Count );
for ( int i = 0; i < subResources.Count; i++ )
{
var resource = subResources[ i ];
var attachmentElement = body;
var resourceElement = _htmlDoc.Create( GD_SubResource );
resourceElement.SetAttribute( "class", "resource" );
attachmentElement.AppendChild( resourceElement );
var nameElement = resourceElement.AddElement( GD_Name, resource.id.value + " " + resource.type.value );
var scriptOrShaderMember = resource.GetMember( "script" );
if ( scriptOrShaderMember == null )
{
scriptOrShaderMember = resource.GetMember( "shader" );
}
if ( scriptOrShaderMember != null )
{
var scriptEntry = _parser.sceneFile.extResources.Find( e => e.id.value == scriptOrShaderMember.valueData.reference );
var scriptType = scriptEntry == null ? "Null" : scriptEntry.path.value;
resourceElement.AddElement( GD_Type, scriptType + "@" + scriptOrShaderMember.valueData.reference );
}
resourceElement.SetAttribute( "id", resource.id.value );
attachmentElement.AddElement( HTMLElementName.br );
}
}
void AddNodes()
{
var nodes = _parser.sceneFile.nodes;
RJLog.Log( "Nodes:", nodes.Count );
var elementMap = new Dictionary<string,XMLElementNode>();
for ( int i = 0; i < nodes.Count; i++ )
{
var node = nodes[ i ];
//RJLog.Log( i, node.name.value );
var attachmentElement = body;
var elementPath = node.elementPath;
var parent = node.parent.value;
if ( parent != null && elementMap.ContainsKey( parent ) )
{
attachmentElement = elementMap[ parent ].querySelector( GD_Children );
}
var nodeElement = _htmlDoc.Create( GD_Node );
nodeElement.SetAttribute( "class", "node" );
var nameElement = nodeElement.AddElement( GD_Name, node.name.value );
nameElement.SetAttribute( "class", "closeable" );
nameElement.SetAttribute( "data-close-target", ".. " + GD_Children.selector );
var scriptMember = node.GetMember( "script" );
if ( scriptMember != null )
{
var scriptEntry = _parser.sceneFile.extResources.Find( e => e.id.value == scriptMember.valueData.reference );
var scriptType = scriptEntry == null ? "Null" : scriptEntry.path.value;
nodeElement.AddElement( GD_Type, scriptType + "@" + scriptMember.valueData.reference + "(" + node.type.value + ")" );
}
else
{
nodeElement.AddElement( GD_Type, node.type.value );
}
string scriptValue = null ;
if ( scriptValue != null )
{
nodeElement.AddElement( GD_Script, scriptValue );
}
var membersElement = nodeElement.AddElement( GD_Members, "" );
var memberData = node.data;
memberData.ForEach(
m =>
{
if ( m.member != null )
{
var mem = m.member;
if ( mem.valuesData != null )
{
}
else if ( mem.valueData != null )
{
if ( SceneFileValueType.Variant == mem.valueData.type )
{
membersElement.AddElement( GD_Member, mem.name + ": " + mem.valueData );
}
else
{
var member = membersElement.AddElement( GD_Member, mem.name );
var reference = member.AddElement( GD_Reference, mem.valueData.reference );
reference.SetAttribute( "reference", mem.valueData.reference );
}
}
}
else
{
// membersElement.AddElement( GD_Member, "Type: " + m.type + " {" + m.line + "}");
}
}
);
nodeElement.AddElement( GD_Children );
elementMap[ elementPath ] = nodeElement;
// RJLog.Log( "'" + elementPath + "'", node.name.value );
attachmentElement.AppendChild( nodeElement );
}
}
}
}