diff --git a/AGXUnity/IO/Environment.cs b/AGXUnity/IO/Environment.cs
index 5afe08a2..e7aaf128 100644
--- a/AGXUnity/IO/Environment.cs
+++ b/AGXUnity/IO/Environment.cs
@@ -334,6 +334,9 @@ private static void OnPlayerCli()
private static void OnCLI()
{
+ if ( LicenseManager.IsAssetImportWorkerProcess )
+ return;
+
if ( CommandLine.HasArg( CommandLine.Arg.GenerateOfflineActivation ) ) {
try {
var offlineLicenseIdCode = CommandLine.GetValues( CommandLine.Arg.GenerateOfflineActivation );
diff --git a/AGXUnity/LicenseInfo.cs b/AGXUnity/LicenseInfo.cs
index e9fdf7c3..8b9bcbb0 100644
--- a/AGXUnity/LicenseInfo.cs
+++ b/AGXUnity/LicenseInfo.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
+using UnityEditor;
using Math = System.Math;
namespace AGXUnity
@@ -88,6 +89,11 @@ public static LicenseInfo Create()
{
var info = new LicenseInfo();
+#if UNITY_EDITOR
+ if ( AssetDatabase.IsAssetImportWorkerProcess() )
+ return info;
+#endif
+
try {
info.Version = agx.agxSWIG.agxGetVersion( false );
if ( info.Version.ToLower().StartsWith( "agx-" ) )
diff --git a/AGXUnity/LicenseManager.cs b/AGXUnity/LicenseManager.cs
index cde8ee82..979adb9b 100644
--- a/AGXUnity/LicenseManager.cs
+++ b/AGXUnity/LicenseManager.cs
@@ -11,6 +11,74 @@ namespace AGXUnity
[HelpURL( "https://us.download.algoryx.se/AGXUnity/documentation/current/editor_interface.html#license-manager" )]
public static class LicenseManager
{
+#if UNITY_EDITOR
+ [UnityEditor.InitializeOnLoadMethod]
+ private static void CacheEditorProcessState()
+ {
+ try {
+ s_isAssetImportWorkerProcess = UnityEditor.AssetDatabase.IsAssetImportWorkerProcess();
+ }
+ catch ( UnityEngine.UnityException ) {
+ s_isAssetImportWorkerProcess = LooksLikeAssetImportWorkerProcess();
+ }
+ }
+#endif
+
+ public static bool CanAccessRuntime => !IsAssetImportWorkerProcess;
+
+ internal static agx.Runtime Runtime
+ {
+ get
+ {
+ if ( !CanAccessRuntime )
+ throw new AGXUnity.Exception( "Runtime may not be accessed from a Unity asset import worker process." );
+
+ return agx.Runtime.instance();
+ }
+ }
+
+ public static bool IsAssetImportWorkerProcess
+ {
+ get
+ {
+#if UNITY_EDITOR
+ if ( s_isAssetImportWorkerProcess.HasValue )
+ return s_isAssetImportWorkerProcess.Value;
+
+ try {
+ s_isAssetImportWorkerProcess = UnityEditor.AssetDatabase.IsAssetImportWorkerProcess();
+ return s_isAssetImportWorkerProcess.Value;
+ }
+ catch ( UnityEngine.UnityException ) {
+ return LooksLikeAssetImportWorkerProcess();
+ }
+#else
+ return false;
+#endif
+ }
+ }
+
+#if UNITY_EDITOR
+ private static bool LooksLikeAssetImportWorkerProcess()
+ {
+ try {
+ var processName = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
+ if ( processName.IndexOf( "AssetImportWorker", StringComparison.OrdinalIgnoreCase ) >= 0 )
+ return true;
+
+ foreach ( var arg in System.Environment.GetCommandLineArgs() )
+ if ( arg.IndexOf( "AssetImportWorker", StringComparison.OrdinalIgnoreCase ) >= 0 )
+ return true;
+ }
+ catch {
+ }
+
+ return false;
+ }
+
+ private static bool? s_isAssetImportWorkerProcess = null;
+#endif
+
///
/// Current license information loaded in AGX Dynamics.
///
@@ -76,6 +144,9 @@ public static IEnumerable LicenseTypes
///
public static bool LoadFile()
{
+ if ( !CanAccessRuntime )
+ return false;
+
// This is potentially a license unlock by a script. It's not
// possible to know if it exists scripts that manually unlocks AGX.
var potentialScriptLoaded = LicenseInfo.Create();
@@ -110,6 +181,9 @@ public static LicenseInfo QueryInfo( string filename )
TypeDescription = "Unknown",
};
+ if ( !CanAccessRuntime )
+ return info;
+
if ( !File.Exists( filename ) ) {
Debug.LogWarning( $"AGXUnity.LicenseManager: Unable to query license info for license {filename} - file doesn't exist." );
return info;
@@ -125,7 +199,7 @@ public static LicenseInfo QueryInfo( string filename )
if ( licenseType == LicenseInfo.LicenseType.Legacy )
return LicenseInfo.FromLegacy( licenseContent );
- return LicenseInfo.FromNative( agx.Runtime.instance().queryLicenseInformation( licenseContent ) );
+ return LicenseInfo.FromNative( Runtime.queryLicenseInformation( licenseContent ) );
}
///
@@ -146,6 +220,9 @@ public static bool LoadFile( string filename )
/// True if successfully loaded and is a valid license, otherwise false.
public static bool Load( string licenseContent )
{
+ if ( !CanAccessRuntime )
+ return false;
+
var context = "Explicit license content.";
// Loading encrypted runtime from script. AGX is writing the generated
// file as given in 'context' here, see ActivateEncryptedRuntime.
@@ -184,6 +261,9 @@ public static bool GenerateEncryptedRuntime( int runtimeLicenseId,
string referenceApplicationFile,
Action onSuccess = null )
{
+ if ( !CanAccessRuntime )
+ return false;
+
if ( !Directory.Exists( applicationRootDirectory ) ) {
Debug.LogError( "AGXUnity.LicenseManager: Unable to generate encrypted runtime license - " +
$"application root directory \"{applicationRootDirectory}\" doesn't exist." );
@@ -205,7 +285,7 @@ public static bool GenerateEncryptedRuntime( int runtimeLicenseId,
try {
agxIO.Environment.instance().getFilePath( agxIO.Environment.Type.RESOURCE_PATH ).pushbackPath( applicationRootDirectory );
- var encrypted = agx.Runtime.instance().encryptRuntimeActivation( runtimeLicenseId,
+ var encrypted = Runtime.encryptRuntimeActivation( runtimeLicenseId,
runtimeLicensePassword,
referenceApplicationFile );
agxIO.Environment.instance().getFilePath( agxIO.Environment.Type.RESOURCE_PATH ).removeFilePath( applicationRootDirectory );
@@ -229,7 +309,7 @@ public static bool GenerateEncryptedRuntime( int runtimeLicenseId,
}
Debug.LogError( "AGXUnity.LicenseManager: Unable to generate encrypted runtime license - " +
- $"encryption failed with status: {agx.Runtime.instance().getStatus()}" );
+ $"encryption failed with status: {Runtime.getStatus()}" );
}
catch ( System.Exception e ) {
Debug.LogError( "AGXUnity.LicenseManager: Exception occurred during generate of encrypted runtime " +
@@ -309,12 +389,15 @@ public static bool GenerateOfflineActivation( int licenseId,
string outputFilename,
bool throwOnError = true )
{
+ if ( !CanAccessRuntime )
+ return false;
+
var success = false;
try {
- var activationText = agx.Runtime.instance().generateOfflineActivationRequest( licenseId, licensePassword );
- if ( !string.IsNullOrEmpty( agx.Runtime.instance().getStatus() ) )
- throw new AGXUnity.Exception( agx.Runtime.instance().getStatus() );
+ var activationText = Runtime.generateOfflineActivationRequest( licenseId, licensePassword );
+ if ( !string.IsNullOrEmpty( Runtime.getStatus() ) )
+ throw new AGXUnity.Exception( Runtime.getStatus() );
File.WriteAllText( outputFilename, activationText );
@@ -348,6 +431,9 @@ public static bool CreateOfflineLicense( string webResponseFilenameOrContent,
string licenseFilename,
bool throwOnerror = true )
{
+ if ( !CanAccessRuntime )
+ return false;
+
var success = false;
try {
@@ -357,10 +443,10 @@ public static bool CreateOfflineLicense( string webResponseFilenameOrContent,
if ( File.Exists( webResponseFilenameOrContent ) )
webResponseFilenameOrContent = File.ReadAllText( webResponseFilenameOrContent );
- if ( !agx.Runtime.instance().processOfflineActivationRequest( webResponseFilenameOrContent ) )
- throw new AGXUnity.Exception( agx.Runtime.instance().getStatus() );
+ if ( !Runtime.processOfflineActivationRequest( webResponseFilenameOrContent ) )
+ throw new AGXUnity.Exception( Runtime.getStatus() );
- File.WriteAllText( licenseFilename, agx.Runtime.instance().readEncryptedLicense() );
+ File.WriteAllText( licenseFilename, Runtime.readEncryptedLicense() );
success = File.Exists( licenseFilename );
}
@@ -382,6 +468,9 @@ public static bool CreateOfflineLicense( string webResponseFilenameOrContent,
///
public static LicenseInfo UpdateLicenseInformation()
{
+ if ( !CanAccessRuntime )
+ return ( LicenseInfo = new LicenseInfo() );
+
return ( LicenseInfo = LicenseInfo.Create() );
}
@@ -397,6 +486,11 @@ public static void ActivateAsync( int licenseId,
string targetDirectory,
Action onDone )
{
+ if ( !CanAccessRuntime ) {
+ onDone?.Invoke( false );
+ return;
+ }
+
if ( IsBusy ) {
Debug.LogWarning( $"AGXUnity.LicenseManager: Unable to activate license with id {licenseId} - activation is still in progress." );
onDone?.Invoke( false );
@@ -407,7 +501,7 @@ public static void ActivateAsync( int licenseId,
s_activationTask = Task.Run( () => {
var success = false;
try {
- success = agx.Runtime.instance().activateAgxLicense( licenseId,
+ success = Runtime.activateAgxLicense( licenseId,
licensePassword,
licenseFilename );
UpdateLicenseInformation();
@@ -447,6 +541,11 @@ public static bool Activate( int licenseId,
public static void RefreshAsync( string filename,
Action onDone )
{
+ if ( !CanAccessRuntime ) {
+ onDone?.Invoke( false );
+ return;
+ }
+
var isBusy = IsBusy;
var seemsValid = !string.IsNullOrEmpty( filename ) &&
!isBusy &&
@@ -472,7 +571,7 @@ public static void RefreshAsync( string filename,
s_refreshTask = Task.Run( () => {
var success = false;
try {
- success = agx.Runtime.instance().loadLicenseFile( filename, true );
+ success = Runtime.loadLicenseFile( filename, true );
UpdateLicenseInformation();
}
catch ( Exception e ) {
@@ -539,14 +638,17 @@ public static bool DeactivateAndDelete( string filename )
/// True if successfully deactivated, otherwise false.
public static bool DeactivateLoaded()
{
+ if ( !CanAccessRuntime )
+ return false;
+
var success = false;
try {
- success = agx.Runtime.instance().deactivateAgxLicense();
+ success = Runtime.deactivateAgxLicense();
if ( success )
Reset();
else
- Debug.LogWarning( $"AGXUnity.LicenseManager: Unable to deactivate loaded license - {agx.Runtime.instance().getStatus()}" );
+ Debug.LogWarning( $"AGXUnity.LicenseManager: Unable to deactivate loaded license - {Runtime.getStatus()}" );
}
catch ( Exception e ) {
Debug.LogException( e );
@@ -559,8 +661,11 @@ public static bool DeactivateLoaded()
///
public static void Reset()
{
+ if ( !CanAccessRuntime )
+ return;
+
try {
- agx.Runtime.instance().clear();
+ Runtime.clear();
}
catch ( Exception ) {
}
@@ -712,6 +817,9 @@ public static bool DeleteFile( string filename )
/// True if successfully loaded, otherwise false.
private static bool LoadFile( string filename, string context )
{
+ if ( !CanAccessRuntime )
+ return false;
+
if ( string.IsNullOrEmpty( filename ) ) {
IssueLoadWarning( "Filename is null or empty.", context );
return false;
@@ -737,14 +845,14 @@ private static bool LoadFile( string filename, string context )
// If the license has been refreshed we have to write the
// new license content to 'filename' independent of 'loadSuccess'.
try {
- var isRefreshed = agx.Runtime.instance().isLicenseRefreshed();
+ var isRefreshed = Runtime.isLicenseRefreshed();
var isRefreshedAndCanWrite = isRefreshed &&
IO.Environment.CanWriteToExisting( filename );
if ( isRefreshedAndCanWrite ) {
LoadInfo( $"The license has been refreshed - rewriting license file {filename}.", context );
using ( var str = new StreamWriter( filename, false ) )
- str.WriteLine( agx.Runtime.instance().readEncryptedLicense() );
+ str.WriteLine( Runtime.readEncryptedLicense() );
LoadInfo( $"Successfully updated license file {filename}.", context );
}
@@ -773,6 +881,9 @@ private static bool LoadFile( string filename, string context )
/// True if successful, otherwise false.
private static bool Load( string licenseContent, string context )
{
+ if ( !CanAccessRuntime )
+ return false;
+
if ( string.IsNullOrEmpty( licenseContent ) ) {
IssueLoadWarning( "License content is null or empty.", context );
return false;
@@ -789,8 +900,8 @@ private static bool Load( string licenseContent, string context )
try {
// Service type.
if ( licenseContentType == LicenseContentType.Service ) {
- agx.Runtime.instance().loadLicenseString( licenseContent );
- LoadInfo( $"Loading service license successful: {agx.Runtime.instance().isValid()}.",
+ Runtime.loadLicenseString( licenseContent );
+ LoadInfo( $"Loading service license successful: {Runtime.isValid()}.",
context );
}
// Runtime license activation.
@@ -799,22 +910,22 @@ private static bool Load( string licenseContent, string context )
// to support non-ASCII input paths.
var cwd = Directory.GetCurrentDirectory();
agxIO.Environment.instance().getFilePath( agxIO.Environment.Type.RESOURCE_PATH ).pushbackPath( cwd );
- agx.Runtime.instance().activateEncryptedRuntime( licenseContent, context );
+ Runtime.activateEncryptedRuntime( licenseContent, context );
agxIO.Environment.instance().getFilePath( agxIO.Environment.Type.RESOURCE_PATH ).removeFilePath( cwd );
- LoadInfo( $"Activating encrypted runtime license \"{context}\" successful: {agx.Runtime.instance().isValid()}.",
+ LoadInfo( $"Activating encrypted runtime license \"{context}\" successful: {Runtime.isValid()}.",
context );
}
// Legacy type.
else if ( licenseContentType == LicenseContentType.Legacy ) {
- agx.Runtime.instance().unlock( licenseContent );
- LoadInfo( $"Loading legacy license successful: {agx.Runtime.instance().isValid()}.",
+ Runtime.unlock( licenseContent );
+ LoadInfo( $"Loading legacy license successful: {Runtime.isValid()}.",
context );
}
// Assume obfuscated legacy.
else {
- agx.Runtime.instance().verifyAndUnlock( licenseContent );
- LoadInfo( $"Loading obfuscated legacy license successful: {agx.Runtime.instance().isValid()}.",
+ Runtime.verifyAndUnlock( licenseContent );
+ LoadInfo( $"Loading obfuscated legacy license successful: {Runtime.isValid()}.",
context );
}
}
@@ -831,9 +942,12 @@ private static bool Load( string licenseContent, string context )
private static bool LoadFloating( string file, string context )
{
+ if ( !CanAccessRuntime )
+ return false;
+
try {
- agx.Runtime.instance().openNetworkSession( file );
- LoadInfo( $"Loading floating license successful: {agx.Runtime.instance().isValid()}.", context );
+ Runtime.openNetworkSession( file );
+ LoadInfo( $"Loading floating license successful: {Runtime.isValid()}.", context );
}
catch ( Exception e ) {
IssueLoadWarning( "Caught exception calling AGX Dynamics.", context );
@@ -848,9 +962,12 @@ private static bool LoadFloating( string file, string context )
public static bool ReturnFloating( string context )
{
+ if ( !CanAccessRuntime )
+ return false;
+
bool success;
try {
- success = agx.Runtime.instance().closeNetworkSession();
+ success = Runtime.closeNetworkSession();
LoadInfo( $"Returning floating license successful: {success}.", context );
}
catch ( Exception e ) {
diff --git a/AGXUnity/NativeHandler.cs b/AGXUnity/NativeHandler.cs
index 2d8df39a..5f0130df 100644
--- a/AGXUnity/NativeHandler.cs
+++ b/AGXUnity/NativeHandler.cs
@@ -149,7 +149,7 @@ public void Unregister( ScriptComponent component )
public void ValidateLicense()
{
- HasValidLicense = m_isAgx.Initialized && agx.Runtime.instance().isValid();
+ HasValidLicense = m_isAgx.Initialized && LicenseManager.Runtime.isValid();
}
public void MakeMainThread()
@@ -219,6 +219,9 @@ public static NativeHandler Instance
{
get
{
+ if ( !LicenseManager.CanAccessRuntime )
+ throw new AGXUnity.Exception( "NativeHandler.Instance may not be initialized from a Unity asset import worker process." );
+
if ( s_instance == null )
s_instance = new NativeHandler();
return s_instance;
diff --git a/AGXUnity/Simulation.cs b/AGXUnity/Simulation.cs
index 2494715d..c3375acb 100644
--- a/AGXUnity/Simulation.cs
+++ b/AGXUnity/Simulation.cs
@@ -980,7 +980,7 @@ protected void OnGUI()
id => {
// Invalid license if initialized.
if ( NativeHandler.Instance.Initialized ) {
- var status = agx.Runtime.instance().getStatus();
+ var status = LicenseManager.Runtime.getStatus();
// Assume no license file was found if status == "" when the
// license manager resets any state in agx.Runtime.
if ( string.IsNullOrEmpty( status ) )
diff --git a/Editor/AGXUnityEditor/ExternalAGXInitializer.cs b/Editor/AGXUnityEditor/ExternalAGXInitializer.cs
index c323b584..b00b315c 100644
--- a/Editor/AGXUnityEditor/ExternalAGXInitializer.cs
+++ b/Editor/AGXUnityEditor/ExternalAGXInitializer.cs
@@ -35,6 +35,9 @@ public bool HasData
public bool ApplyData()
{
+ if ( AGXUnity.LicenseManager.IsAssetImportWorkerProcess )
+ return false;
+
IsApplied = true;
Environment.Set( Environment.Variable.AGX_DIR, AGX_DIR );
@@ -139,6 +142,9 @@ public static string IgnoreIncompatibleVersion
public static bool Initialize()
{
+ if ( AGXUnity.LicenseManager.IsAssetImportWorkerProcess )
+ return false;
+
#if UNITY_EDITOR_WIN
// Dependencies dir set and we're certain setup_env has been executed.
if ( Environment.IsSet( Environment.Variable.AGX_DEPENDENCIES_DIR ) )
diff --git a/Editor/AGXUnityEditor/Manager.cs b/Editor/AGXUnityEditor/Manager.cs
index a8e3d7c0..16d37599 100644
--- a/Editor/AGXUnityEditor/Manager.cs
+++ b/Editor/AGXUnityEditor/Manager.cs
@@ -69,6 +69,9 @@ public static class Manager
///
static Manager()
{
+ if ( AGXUnity.LicenseManager.IsAssetImportWorkerProcess )
+ return;
+
IO.Utils.VerifyDirectories();
GetRequestScriptReloadData().Float = -1;