Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2015/9/16 Roslyn Paradox LiveScripting

Akiko Kawai
September 16, 2015
330

2015/9/16 Roslyn Paradox LiveScripting

Metro.cs #1 2015/9/16 ParadoxのLiveScripting事情 遥佐保
PPTX→ http://jyurimaru.info/data/20150916ParadoxLiveScripting/20150916_RoslynParadoxLiveScripting.pptx

Akiko Kawai

September 16, 2015
Tweet

Transcript

  1. View Slide

  2. View Slide

  3. http://paradox3d.net
    https://github.com/SiliconStudio/paradox

    View Slide

  4. View Slide

  5. View Slide

  6. Paradox Game Studio
    Visual Studio
    Running EXE
    Roslyn利用

    View Slide

  7. View Slide

  8. View Slide

  9. Roslyn/MSBuild Project
    Part0-csproj
    Player.cs
    Part1-csproj
    Enemy.cs
    Player.dll
    Player.pdb
    Enemy.dll
    Enemy.pdb
    ↑こんなsln構成
    だと思いますが
    WCF pipe

    View Slide

  10. View Slide

  11. Game用のプロジェクトを新規作成
    using Microsoft.CodeAnalysis
    private async Task OpenProject(string projectPath)
    {
    var csharpWorkspaceAssemblies = new[]{
    System.Reflection.Assembly.Load("Microsoft.CodeAnalysis.Workspaces"),
    System.Reflection.Assembly.Load("Microsoft.CodeAnalysis.CSharp.Workspaces"),
    System.Reflection.Assembly.Load("Microsoft.CodeAnalysis.Workspaces.Desktop")
    };
    var msWorkspace = MSBuildWorkspace.Create(
    ImmutableDictionary.Empty,
    MefHostServices.Create(csharpWorkspaceAssemblies));
    return await msWorkspace.OpenProjectAsync(projectPath);
    }

    View Slide

  12. Game用プロジェクトを新規に作成する
    元Projectと”同じ様な”構造、だが1ファイルづつ
    var newproject = solution.AddProject(assemblyName, assemblyName, LanguageNames.CSharp)
    .WithMetadataReferences(motoProject.MetadataReferences)
    .WithProjectReferences(motoProject.AllProjectReferences)
    .WithCompilationOptions(
    new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
    // ソースコードの追加
    Newproject = newproject.AddDocument(syntaxTree.FilePath, syntaxTree.GetText()).Project;
    // 他のソースコードの参照があれば追加(※しれっと……???)
    project = newproject.AddProjectReference(
    new ProjectReference(dependencySourceGroup.Target.Project.Id));

    View Slide

  13. http://quickgraph.codeplex.com/
    QuickGraph.AdjacencyGraph>
    QuickGraph.AdjacencyGraph

    View Slide

  14. Roslynでコンパイル、1ファイルづつ
    var compilation = await newproject.GetCompilationAsync();

    View Slide

  15. View Slide

  16. MSBuildで改めて実際にコンパイル
    Task BuildTask { get; private set; }
    Microsoft.Build.Evaluation.Project project;
    var projectInstance = new ProjectInstance(
    project.Xml,
    project.ProjectCollection.GlobalProperties,
    null,
    project.ProjectCollection);
    BuildTask = Task.Run(() =>{ … new BuildParameters BuildParameters(project.ProjectCollection) … }

    View Slide

  17. できたDLLをメモリに保存
    // sourceGroupとは独自で作ったクラス
    // - PE(dllファイル)
    // - PDB
    // - Microsoft.CodeAnalysis.Project
    // - Mono.Cecil.AssemblyDefinition (ParadoxではScriptのシリアライズに利用している)
    sourceGroup.PE = File.ReadAllBytes(peFileName);
    sourceGroup.PDB = File.ReadAllBytes(pdbFileName);

    View Slide

  18. View Slide

  19. WCF pipe通信
    // gameDebuggerHostとは独自で作ったクラス
    // 今から起動させるアプリケーションのこと
    ServiceHost = new System.ServiceModel.ServiceHost(gameDebuggerHost);
    ServiceHost.AddServiceEndpoint(
    typeof(IGameDebuggerHost),
    new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) {
    MaxReceivedMessageSize = int.MaxValue
    }, address);
    ServiceHost.Open();
    var startInfo = new ProcessStartInfo{
    FileName = gameHostAssembly,
    Arguments = "—-host=net.pipe://localhost/xxx",
    WorkingDirectory = workingDirectory,
    CreateNoWindow = true,
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    };
    var process = new System.Diabnostics.Process { StartInfo = startInfo };
    process.Start();

    View Slide

  20. View Slide

  21. Paradox Game Studio
    FileSystemWatcher

    View Slide

  22. FileSystemWatcher
    public Watcher(string path)
    {
    watcher = new FileSystemWatcher(){
    Path = path,
    NotifyFilter = (
    NotifyFilters.LastWrite
    | NotifyFilters.FileName
    | NotifyFilters.DirectoryName),
    IncludeSubdirectories = true,
    Filter = ""
    };
    watcher.BeginInit();
    watcher.Changed += OnModified;
    watcher.Created += OnModified;
    watcher.Deleted += OnModified;
    watcher.Renamed += OnModified;
    watcher.EndInit();
    }

    View Slide

  23. View Slide

  24. Roslyn/MSBuild Project
    Part0-csproj
    Player.cs
    Part1-csproj
    Enemy.cs
    Player.dll
    Player.pdb
    Enemy.dll
    Enemy.pdb

    View Slide

  25. View Slide

  26. Running EXE
    Paradox Game Studio
    // Target(Running EXE)に送って実行させる(DLLのSwap)
    // Game Studioは何もしていない
    debugTarget.AssemblyLoadRaw(
    loadedProject.PE, loadedProject.PDB);
    // 実際にSwapを実行しているのは、Running EXE側
    public Assembly AssemblyLoadRaw(byte[] peData, byte[] pdbData)
    {
    return Assembly.Load(peData, pdbData);
    }
    https://github.com/SiliconStudio/paradox/blob/master/sources/engine/Silicon
    Studio.Paradox.Debugger/Debugger/GameDebuggerTarget.cs
    DLL Hot Swap
    .NETだから可能な技術

    View Slide

  27. View Slide

  28. Running
    EXE
    https://github.com/SiliconStudio/paradox/blob/master/sources/engine/SiliconStudio.Paradox.Debugger/De
    bugger/LiveAssemblyReloader.cs

    View Slide

  29. Paradox Game Studio
    Visual Studio
    Running EXE
    Roslyn利用

    View Slide

  30. View Slide

  31. View Slide

  32. https://www.surveymonkey.com/r/YGD8VYH

    View Slide

  33. 33
    Windowsアプリ操作系最強!
    Is a magical library!
    It break through
    the walls of processes.
    NuGetで「めとべや」で検索!
    ひらがなで引っかかるのはこれだけ!?
    9/19 Friendlyハンズオン at SHIFT様
    3名様に9/20発売のSeleniumデザパタ本をプレゼント!
    めとべや公式ライブラリもあり!
    友達だから何でもできる!

    View Slide

  34. View Slide