Skip to content

Commit

Permalink
Merge pull request #9 from Dangl-IT/feature/ipc
Browse files Browse the repository at this point in the history
Feature/ipc
  • Loading branch information
GeorgDangl authored Apr 9, 2024
2 parents dca7913 + c4ebc60 commit 5e1090e
Show file tree
Hide file tree
Showing 29 changed files with 569 additions and 75 deletions.
7 changes: 6 additions & 1 deletion build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,12 @@ public static class FileVersionProvider
Target BuildRevitPlugin => _ => _
.DependsOn(BuildFrontend)
.DependsOn(Compile)
.DependsOn(BuildElectronApp)
.Executes(() =>
{
CopyDirectoryRecursively(SourceDirectory / "ipa-bcfier-ui" / "dist" / "ipa-bcfier-ui" / "browser", SourceDirectory / "IPA.Bcfier.Revit" / "Resources" / "Browser", DirectoryExistsPolicy.Merge, FileExistsPolicy.Overwrite);

var pluginOutputDirectory = OutputDirectory / "RevitPlugin";

DotNetBuild(c => c.SetProjectFile(SourceDirectory / "IPA.Bcfier.Revit" / "IPA.Bcfier.Revit.csproj")
.SetConfiguration("Release")
.SetOutputDirectory(pluginOutputDirectory)
Expand All @@ -264,6 +265,10 @@ public static class FileVersionProvider

var installerDirectory = pluginOutputDirectory / "Installer";
installerDirectory.CreateOrCleanDirectory();

using var zipStream = File.OpenRead(OutputDirectory / "electron" / "IPA.Bcfier_Unzipped_Windows_X64.zip");
ZipFile.ExtractToDirectory(zipStream, installerDirectory / "bcfier-app");

CopyDirectoryRecursively(SourceDirectory / "IPA.Bcfier.Revit" / "InstallerAssets", installerDirectory / "InstallerAssets", DirectoryExistsPolicy.Merge, FileExistsPolicy.Overwrite);
File.Copy(pluginOutputDirectory / "Dangl.BCF.dll", installerDirectory / "Dangl.BCF.dll");
File.Copy(pluginOutputDirectory / "IPA.Bcfier.dll", installerDirectory/ "IPA.Bcfier.dll");
Expand Down
7 changes: 7 additions & 0 deletions src/IPA.Bcfier.App/Configuration/RevitParameters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace IPA.Bcfier.App.Configuration
{
public class RevitParameters
{
public bool IsConnectedToRevit { get; set; } = false;
}
}
10 changes: 9 additions & 1 deletion src/IPA.Bcfier.App/Controllers/FrontendConfigController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using IPA.Bcfier.App.Configuration;

namespace IPA.Bcfier.App.Controllers
{
Expand All @@ -10,6 +11,12 @@ namespace IPA.Bcfier.App.Controllers
public class FrontendConfigController : ControllerBase
{
private static string? _frontendConfig;
private readonly RevitParameters _revitParameters;

public FrontendConfigController(RevitParameters revitParameters)
{
_revitParameters = revitParameters;
}

[HttpGet("config.js")]
public IActionResult GetFrontendConfigAsJavaScript([FromQuery] string? timestamp)
Expand Down Expand Up @@ -57,7 +64,8 @@ private FrontendConfig GetFrontendConfigModel()
{
return new FrontendConfig
{
IsInElectronMode = true
IsInElectronMode = true,
IsConnectedToRevit = _revitParameters.IsConnectedToRevit
};
}
}
Expand Down
85 changes: 85 additions & 0 deletions src/IPA.Bcfier.App/Controllers/ViewpointsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using IPA.Bcfier.Ipc;
using IPA.Bcfier.Models.Bcf;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace IPA.Bcfier.App.Controllers
{
[ApiController]
[Route("api/viewpoints")]
public class ViewpointsController : ControllerBase
{
[HttpPost("visualization")]
public async Task<IActionResult> ShowViewpointAsync([FromBody] BcfViewpoint viewpoint)
{
using var ipcHandler = new IpcHandler(thisAppName: "BcfierApp", otherAppName: "Revit");
await ipcHandler.InitializeAsync();

var correlationId = Guid.NewGuid();
await ipcHandler.SendMessageAsync(JsonConvert.SerializeObject(new IpcMessage
{
CorrelationId = correlationId,
Command = IpcMessageCommand.ShowViewpoint,
Data = JsonConvert.SerializeObject(viewpoint)
}));

var hasReceived = false;
var start = DateTime.Now;
while (DateTime.UtcNow - start < TimeSpan.FromSeconds(120))
{
if (IpcHandler.ReceivedMessages.TryDequeue(out var message))
{
var ipcMessage = JsonConvert.DeserializeObject<IpcMessage>(message)!;
if (ipcMessage.CorrelationId == correlationId)
{
hasReceived = true;
return NoContent();
}
else
{
IpcHandler.ReceivedMessages.Enqueue(message);
}
}
}

return BadRequest();
}

[HttpPost("")]
public async Task<IActionResult> CreateViewpointAsync()
{
using var ipcHandler = new IpcHandler(thisAppName: "BcfierApp", otherAppName: "Revit");
await ipcHandler.InitializeAsync();

var correlationId = Guid.NewGuid();
await ipcHandler.SendMessageAsync(JsonConvert.SerializeObject(new IpcMessage
{
CorrelationId = correlationId,
Command = IpcMessageCommand.CreateViewpoint,
Data = null
}));

var hasReceived = false;
var start = DateTime.Now;
while (DateTime.UtcNow - start < TimeSpan.FromSeconds(120))
{
if (IpcHandler.ReceivedMessages.TryDequeue(out var message))
{
var ipcMessage = JsonConvert.DeserializeObject<IpcMessage>(message)!;
if (ipcMessage.CorrelationId == correlationId)
{
hasReceived = true;
var bcfViewpoint = JsonConvert.DeserializeObject<BcfViewpoint>(ipcMessage.Data!.ToString())!;
return Ok(bcfViewpoint);
}
else
{
IpcHandler.ReceivedMessages.Enqueue(message);
}
}
}

return BadRequest();
}
}
}
3 changes: 3 additions & 0 deletions src/IPA.Bcfier.App/IPA.Bcfier.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@
<None Update="bcfier.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="icon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
33 changes: 31 additions & 2 deletions src/IPA.Bcfier.App/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using ElectronNET.API;
using ElectronNET.API.Entities;
using IPA.Bcfier.App.Configuration;
using IPA.Bcfier.App.Services;
using IPA.Bcfier.Ipc;
using Newtonsoft.Json;

namespace IPA.Bcfier.App
{
Expand All @@ -20,16 +23,42 @@ public static async Task Main(string[] args)
Icon = Path.Combine(Directory.GetCurrentDirectory(), "bcfier.png"),
Height = 800,
Width = 1200,
AutoHideMenuBar = true,
AutoHideMenuBar = true
};

var window = await Electron.WindowManager.CreateWindowAsync(browserWindowOptions);

var hasRevitIntegration = false;
using (var scope = host.Services.CreateScope())
{
scope.ServiceProvider.GetRequiredService<ElectronWindowProvider>().SetBrowserWindow(window);
hasRevitIntegration = await Electron.App.CommandLine.HasSwitchAsync("revit-integration");
scope.ServiceProvider.GetRequiredService<RevitParameters>().IsConnectedToRevit = hasRevitIntegration;
}

await Electron.IpcMain.On("closeApp", async (e) =>
{
if (hasRevitIntegration)
{
try
{
using var ipcHandler = new IpcHandler(thisAppName: "BcfierApp", otherAppName: "Revit");
await ipcHandler.SendMessageAsync(JsonConvert.SerializeObject(new IpcMessage
{
CorrelationId = Guid.NewGuid(),
Command = IpcMessageCommand.AppClosed,
Data = null
}), timeout: 500);
}
catch (Exception ex)
{
// We're not really handling failures here, just write them to
// the console and then continue with closing the window
Console.WriteLine(ex);
}
}
window.Close();
});

await host.WaitForShutdownAsync();
}
catch (Exception e)
Expand Down
2 changes: 2 additions & 0 deletions src/IPA.Bcfier.App/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Dangl.Data.Shared.AspNetCore.SpaUtilities;
using ElectronNET.API;
using IPA.Bcfier.App.Configuration;
using IPA.Bcfier.App.Services;
using IPA.Bcfier.Services;
using Microsoft.AspNetCore.Mvc;
Expand All @@ -16,6 +17,7 @@ public void ConfigureServices(IServiceCollection services)
services.AddSingleton<ElectronWindowProvider>();
services.AddTransient<SettingsService>();
services.AddHttpContextAccessor();
services.AddSingleton(new RevitParameters());

services.Configure<ApiBehaviorOptions>(options =>
{
Expand Down
5 changes: 3 additions & 2 deletions src/IPA.Bcfier.App/electron.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
"productName": "IPA.Bcfier",
"copyright": "Copyright © 2024 Dangl IT GmbH",
"afterSign": "../../../electronAfterPackHook.js",
"buildVersion": "3.0.0-initial-frontend.15",
"buildVersion": "3.0.0-ipc.67",
"compression": "maximum",
"directories": {
"output": "../../../bin/Desktop"
},
"win": {
"target": "nsis"
"target": "nsis",
"icon": "icon.ico"
},
"nsis": {
"uninstallDisplayName": "${productName}",
Expand Down
Binary file added src/IPA.Bcfier.App/icon.ico
Binary file not shown.
10 changes: 4 additions & 6 deletions src/IPA.Bcfier.Revit/BcfierJavascriptBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using IPA.Bcfier.Models.Settings;
using IPA.Bcfier.Services;
using Autodesk.Revit.UI;
using Microsoft.Win32;
using IPA.Bcfier.Revit.Models;
using IPA.Bcfier.Models.Bcf;

Expand All @@ -25,6 +22,7 @@ private class DataClass

public string Data { get; set; }
}

public async Task SendDataToRevit(string data, IJavascriptCallback javascriptCallback)
{
var classData = JsonConvert.DeserializeObject<DataClass>(data)!;
Expand Down Expand Up @@ -59,7 +57,7 @@ public async Task SendDataToRevit(string data, IJavascriptCallback javascriptCal
{
// Since we need a Revit context (more specifically access to the UI thread),
// we're enqueuing that task to be executed in the Revit context
_revitTaskQueueHandler.OpenBcfFileCallbacks.Enqueue(javascriptCallback);
_revitTaskQueueHandler.OpenBcfFileCallbacks.Enqueue(message => javascriptCallback.ExecuteAsync(message));
}
else if (classData.Command == "exportBcfFile")
{
Expand All @@ -71,14 +69,14 @@ public async Task SendDataToRevit(string data, IJavascriptCallback javascriptCal
}
else if (classData.Command == "createViewpoint")
{
_revitTaskQueueHandler.CreateRevitViewpointCallbacks.Enqueue(javascriptCallback);
_revitTaskQueueHandler.CreateRevitViewpointCallbacks.Enqueue(message => javascriptCallback.ExecuteAsync(message));
}
else if (classData.Command == "showViewpoint")
{
var viewpoint = JsonConvert.DeserializeObject<BcfViewpoint>(classData.Data);
_revitTaskQueueHandler.ShowViewpointQueueItems.Enqueue(new ShowViewpointQueueItem
{
Callback = javascriptCallback,
Callback = () => javascriptCallback.ExecuteAsync(),
Viewpoint = viewpoint
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/IPA.Bcfier.Revit/IPA.Bcfier.Revit.addin
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<AddIn Type="Application">
<Name>IPA.BCFier</Name>
<FullClassName>IPA.Bcfier.Revit.IpaBcfierRevitPlugin</FullClassName>
<Assembly>IPA.Bcfier.Revit.dll</Assembly>
<Assembly>Ipa.BCFier/IPA.Bcfier.Revit.dll</Assembly>
<AddInId>cfd740a5-8089-4323-a6e5-c86cfee9cca2</AddInId>
<VendorId>Dangl IT GmbH</VendorId>
<VendorDescription>www.dangl-it.com</VendorDescription>
Expand Down
9 changes: 5 additions & 4 deletions src/IPA.Bcfier.Revit/Installer.iss
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ Name: revit24; Description: Addin for Autodesk Revit 2024; Types: full
[Files]

;REVIT 2024
Source: "{#Repository}\DecimalEx.dll"; DestDir: "{#RevitAddin24}"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\Dangl.BCF.dll"; DestDir: "{#RevitAddin24}"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\IPA.Bcfier.dll"; DestDir: "{#RevitAddin24}"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\IPA.Bcfier.Revit.dll"; DestDir: "{#RevitAddin24}"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\IPA.Bcfier.Revit.addin"; DestDir: "{#RevitAddin24}"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\DecimalEx.dll"; DestDir: "{#RevitAddin24}\Ipa.BCFier"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\Dangl.BCF.dll"; DestDir: "{#RevitAddin24}\Ipa.BCFier"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\IPA.Bcfier.dll"; DestDir: "{#RevitAddin24}\Ipa.BCFier"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\IPA.Bcfier.Revit.dll"; DestDir: "{#RevitAddin24}\Ipa.BCFier"; Flags: ignoreversion; Components: revit24
Source: "{#Repository}\bcfier-app\*"; DestDir: "{#RevitAddin24}\Ipa.BCFier\ipa-bcfier-app"; Flags: ignoreversion recursesubdirs; Components: revit24
2 changes: 1 addition & 1 deletion src/IPA.Bcfier.Revit/IpaBcfierRevitPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class IpaBcfierRevitPlugin : IExternalApplication
{
public Result OnStartup(UIControlledApplication application)
{
var buttonData = new PushButtonData("openPluginButton", "Open Plugin", Assembly.GetExecutingAssembly().Location, "IPA.Bcfier.Revit.OpenIpaBcfierWindowCommand");
var buttonData = new PushButtonData("openPluginButton", "Open Plugin", Assembly.GetExecutingAssembly().Location, "IPA.Bcfier.Revit.ListenToIpaBcfierAppPipeCommand");
var pushButton = application.CreateRibbonPanel("IPA").AddItem(buttonData) as PushButton;
pushButton.ToolTip = "Launch IPA.Bcfier Revit Plugin";
pushButton.Image = GetBitmapImage("button16.png");
Expand Down
Loading

0 comments on commit 5e1090e

Please sign in to comment.