Skip to content

Commit

Permalink
Preliminary deserialization implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Aurumaker72 committed Nov 11, 2023
1 parent fde0884 commit a841666
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 45 deletions.
99 changes: 99 additions & 0 deletions RsrcArchitect.ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using RsrcArchitect.ViewModels.Messages;
using RsrcCore;
using RsrcCore.Controls;
using RsrcCore.Serializers.Implementations;

namespace RsrcArchitect.ViewModels;

Expand Down Expand Up @@ -36,6 +37,104 @@ private void CreateProject()
}, "New Dialog Project", DialogEditorSettingsViewModel, _filePickerService));
}

[RelayCommand]
private void Open()
{
var dialog = new RcDialogSerializer().Deserialize("""
IDD_MOVIE_PLAYBACK_DIALOG DIALOGEX 0, 0, 342, 342
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Play Movie"
FONT 8, "MS Shell Dlg", 400, 0, 0x0
BEGIN
EDITTEXT IDC_INI_MOVIEFILE,59,20,212,12,ES_AUTOHSCROLL
PUSHBUTTON "Browse...",IDC_MOVIE_BROWSE,281,19,50,14
PUSHBUTTON "Refresh",IDC_MOVIE_REFRESH,281,3,50,14
CONTROL "Open Read-Only",IDC_MOVIE_READONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,203,6,69,10
EDITTEXT IDC_PAUSEAT_FIELD,80,320,44,13,ES_AUTOHSCROLL | ES_NUMBER
DEFPUSHBUTTON "OK",IDC_OK,225,320,50,14
PUSHBUTTON "Cancel",IDC_CANCEL,281,320,50,14
GROUPBOX "Movie Settings",IDC_ROM_HEADER_INFO_TEXT,9,118,153,195
LTEXT "Name:",IDC_ROM_INTERNAL_NAME_TEXT,23,139,31,8
LTEXT "Country:",IDC_ROM_COUNTRY_TEXT,23,151,32,8
EDITTEXT IDC_ROM_INTERNAL_NAME,56,139,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_ROM_COUNTRY,56,151,88,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "Plugins",IDC_ROM_PLUGINS,15,179,140,62
LTEXT "Video:",IDC_GFXPLUGIN,23,191,32,10
LTEXT "Sound:",IDC_SOUNDPLUGIN,23,203,31,8
LTEXT "Input:",IDC_INPUTPLUGIN,23,215,31,8
LTEXT "RSP:",IDC_RSPPLUGIN,23,227,32,8
LTEXT "Pause at frame:",IDC_PAUSEAT_LABEL,23,323,52,10
LTEXT "Movie File:",IDC_INI_MOVIEFILE_TEXT,16,22,40,8
EDITTEXT IDC_INI_AUTHOR,59,42,272,12,ES_AUTOHSCROLL
EDITTEXT IDC_INI_DESCRIPTION,59,60,272,24,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
LTEXT "CRC:",IDC_ROM_CRC_TEXT,23,163,31,8
EDITTEXT IDC_ROM_CRC,56,163,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "ROM",IDC_ROM_INFO_TEXT,16,127,139,50
LTEXT "Author:",IDC_MOVIE_AUTHOR_TEXT,25,44,29,8
LTEXT "Description:",IDC_MOVIE_DESCRIPTION_TEXT,12,68,42,8
EDITTEXT IDC_MOVIE_VIDEO_TEXT,56,191,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_SOUND_TEXT,56,203,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_INPUT_TEXT,56,215,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_RSP_TEXT,56,227,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "Controllers",IDC_MOVIE_CONTROLLERS,15,245,140,62
LTEXT "1:",IDC_CONTROLLER1,23,257,32,10
LTEXT "2:",IDC_CONTROLLER2,23,269,31,8
LTEXT "3:",IDC_CONTROLLER3,23,281,31,8
LTEXT "4:",IDC_CONTROLLER4,23,293,32,8
EDITTEXT IDC_MOVIE_CONTROLLER1_TEXT,55,257,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_CONTROLLER2_TEXT,55,269,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_CONTROLLER3_TEXT,55,281,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_CONTROLLER4_TEXT,55,293,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
LTEXT "1:",IDC_CONTROLLER5,193,257,32,10
LTEXT "2:",IDC_CONTROLLER6,193,269,31,8
LTEXT "3:",IDC_CONTROLLER7,193,281,31,8
LTEXT "4:",IDC_CONTROLLER8,193,293,32,8
EDITTEXT IDC_MOVIE_CONTROLLER1_TEXT2,225,257,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_CONTROLLER2_TEXT2,225,269,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_CONTROLLER3_TEXT2,225,281,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_CONTROLLER4_TEXT2,225,293,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
LTEXT "Length:",IDC_MOVIE_LENGTH_TEXT,25,91,32,8
LTEXT "Frames:",IDC_MOVIE_FRAMES_TEXT,24,105,32,8
LTEXT "Re-records:",IDC_MOVIE_RERECORDS_TEXT,186,91,43,8
EDITTEXT IDC_MOVIE_LENGTH,58,91,104,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_FRAMES,58,105,104,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_RERECORDS,232,91,93,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
LTEXT "Starts From:",IDC_STARTSFROM_LABEL,184,105,45,8
EDITTEXT IDC_FROMSNAPSHOT_TEXT,232,105,56,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "Your Settings",IDC_ROM_HEADER_INFO_TEXT2,179,118,153,195
LTEXT "Country:",IDC_ROM_COUNTRY_TEXT2,193,151,32,8
EDITTEXT IDC_ROM_INTERNAL_NAME2,226,139,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_ROM_COUNTRY2,226,151,88,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "Plugins",IDC_ROM_PLUGINS2,185,179,140,62
LTEXT "Video:",IDC_GFXPLUGIN2,193,191,32,10
LTEXT "Sound:",IDC_SOUNDPLUGIN2,193,203,31,8
LTEXT "Input:",IDC_INPUTPLUGIN2,193,215,31,8
LTEXT "RSP:",IDC_RSPPLUGIN2,193,227,32,8
LTEXT "CRC:",IDC_ROM_CRC_TEXT2,193,163,31,8
EDITTEXT IDC_ROM_CRC3,226,163,91,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "ROM",IDC_ROM_INFO_TEXT2,186,127,139,50
EDITTEXT IDC_MOVIE_VIDEO_TEXT2,226,191,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_SOUND_TEXT2,226,203,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_INPUT_TEXT2,226,215,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
EDITTEXT IDC_MOVIE_RSP_TEXT2,226,227,98,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER
GROUPBOX "Controllers",IDC_MOVIE_CONTROLLERS2,185,245,140,62
LTEXT "Name:",IDC_ROM_INTERNAL_NAME_TEXT2,193,139,31,8
END
""");
DialogEditorViewModels.Add(new DialogEditorViewModel(dialog, "New Dialog Project", DialogEditorSettingsViewModel, _filePickerService));
// var result = await _filePickerService.TryPickOpenFileAsync(new[] { ".rc" });
//
// if (result == null)
// {
// return;
// }
//
// var text = File.ReadAllText(result);
// var dialog = new RcDialogSerializer().Deserialize(text);
// DialogEditorViewModels.Add(new DialogEditorViewModel(dialog, "New Dialog Project", DialogEditorSettingsViewModel, _filePickerService));
}

void IRecipient<DialogEditorViewModelClosingMessage>.Receive(DialogEditorViewModelClosingMessage message)
{
DialogEditorViewModels.Remove(message.Value);
Expand Down
1 change: 1 addition & 0 deletions RsrcArchitect.Views.WPF/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<Menu>
<MenuItem Header="_File">
<MenuItem Header="_New Project" Command="{Binding MainViewModel.CreateProjectCommand}" />
<MenuItem Header="_Open" Command="{Binding MainViewModel.OpenCommand}" />
<Separator />
<MenuItem Header="_Save As">
<MenuItem Header="_Resource File"
Expand Down
96 changes: 51 additions & 45 deletions RsrcCore/Serializers/Implementations/RcDialogSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Diagnostics.Contracts;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using RsrcCore.Controls;
using RsrcCore.Extensions;
Expand Down Expand Up @@ -43,63 +46,61 @@ public string Serialize(Dictionary<Control, Rectangle> flattenedControls, Dialog
[Pure]
public Dialog Deserialize(string serialized)
{
var dialog = new Dialog();
var dialog = new Dialog()
{
Root = new TreeNode<Control>(new Panel())
};

var lines = serialized.Split(Environment.NewLine);
var tokens = Tokenize(lines);

throw new NotImplementedException();
}

private IEnumerable<Token> Tokenize(IEnumerable<string> lines)
{
List<Token> tokens = new();

var enumerable = lines as string[] ?? lines.ToArray();

var preludes = Regex.Replace(enumerable.ElementAt(0).Replace(',', ' '), @"\s+", " ").Split(' ');

tokens.Add(new Token(Token.Types.Identifier, preludes[0]));
tokens.Add(new Token(Token.Types.Keyword, preludes[1]));
tokens.Add(new Token(Token.Types.LiteralNumber, preludes[2]));
tokens.Add(new Token(Token.Types.LiteralNumber, preludes[3]));
tokens.Add(new Token(Token.Types.LiteralNumber, preludes[4]));
tokens.Add(new Token(Token.Types.LiteralNumber, preludes[5]));

var styles = enumerable.ElementAt(1).Replace("| ", "").Split(' ');

tokens.Add(new Token(Token.Types.Keyword, styles[0]));
tokens.AddRange(styles[1..].Select(style => new Token(Token.Types.BuiltinType, style)));
// IDD_DIALOG DIALOGEX 0, 0, 342, 342
var prelude = lines[0].Replace(",", "").Split(" ");
dialog.Identifier = prelude[0];
dialog.Width = int.Parse(prelude[4]);
dialog.Height = int.Parse(prelude[5]);

var captions = enumerable.ElementAt(2).Replace("\"", "").Split(' ');
tokens.Add(new Token(Token.Types.Keyword, captions[0]));
tokens.Add(new Token(Token.Types.LiteralString, captions[1]));
// CAPTION "Play Movie"
const string captionHint = "CAPTION ";
// we chop off one additional character on each side to remove the quotes
dialog.Caption = lines[2].Substring(captionHint.Length + 1, lines[2].Length - captionHint.Length - 2);

var fonts = enumerable.ElementAt(3).Replace("\"", "").Split(' ');
tokens.Add(new Token(Token.Types.Keyword, captions[0]));
tokens.Add(new Token(Token.Types.LiteralNumber, captions[1]));
tokens.Add(new Token(Token.Types.LiteralString, captions[2]));
tokens.Add(new Token(Token.Types.LiteralNumber, captions[3]));
tokens.Add(new Token(Token.Types.LiteralNumber, captions[4]));
tokens.Add(new Token(Token.Types.LiteralNumber, captions[5]));

var begin = enumerable.ElementAt(4);
tokens.Add(new Token(Token.Types.Keyword, begin));
var controlLines = lines[new Range(new Index(5), new Index(1, true))].Select(x => x.Trim());

var controls = enumerable[new Range(4, enumerable.Length - 1)];
foreach (var control in controls)
foreach (var controlLine in controlLines)
{
var parameters = enumerable.ElementAt(3).Replace("\"", "").Split(' ');
tokens.Add(new Token(Token.Types.Keyword, captions[0]));
}
// different control classes have different order of properties, so we need to work conditionally
var controlClass = controlLine.Split(" ")[0];

if (controlClass == "PUSHBUTTON")
{
var propertiesStartIndex = controlLine.IndexOf("\"", StringComparison.Ordinal);
var controlProperties = controlLine[propertiesStartIndex..];
var captionEndIndex = controlProperties.IndexOf('"', 1);
var caption = controlProperties[1..captionEndIndex];

var rest = controlProperties[captionEndIndex..];
var restProperties = rest.Split(",");

var end = enumerable.ElementAt(enumerable.Length - 1);
tokens.Add(new Token(Token.Types.Keyword, end));
var identifier = restProperties[1];
var x = int.Parse(restProperties[2]);
var y = int.Parse(restProperties[3]);
var width = int.Parse(restProperties[4]);
var height = int.Parse(restProperties[5]);

return tokens;
dialog.Root.AddChild(new Button()
{
Identifier = identifier,
Rectangle = new Rectangle(x, y, width, height),
Caption = caption
});
}
}

return dialog;
}


private static string DoSerialize(Dictionary<Control, Rectangle> flattenedControls, Dialog dialog)
{
StringBuilder stringBuilder = new();
Expand Down Expand Up @@ -242,5 +243,10 @@ public Token(Types type, string text)
Type = type;
Text = text;
}

public override string ToString()
{
return $"{Type}: {Text}";
}
}
}

0 comments on commit a841666

Please sign in to comment.