243 lines
6.3 KiB
C++
243 lines
6.3 KiB
C++
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "MTypes.h"
|
|
#include "MAssemblyOptions.h"
|
|
#include "Engine/Core/Delegate.h"
|
|
#include "Engine/Core/Types/String.h"
|
|
#include "Engine/Core/Collections/Array.h"
|
|
#include "Engine/Core/Collections/Dictionary.h"
|
|
#include "Engine/Platform/CriticalSection.h"
|
|
|
|
/// <summary>
|
|
/// Represents a managed assembly, which is a reusable, versionable, and self-describing building block of a common language runtime application.
|
|
/// </summary>
|
|
class FLAXENGINE_API MAssembly
|
|
{
|
|
friend MDomain;
|
|
public:
|
|
|
|
typedef Dictionary<MString, MClass*> ClassesDictionary;
|
|
|
|
private:
|
|
|
|
#if USE_MONO
|
|
MonoAssembly* _monoAssembly = nullptr;
|
|
MonoImage* _monoImage = nullptr;
|
|
#endif
|
|
MDomain* _domain;
|
|
|
|
int32 _isLoaded : 1;
|
|
int32 _isLoading : 1;
|
|
int32 _isDependency : 1;
|
|
int32 _isFileLocked : 1;
|
|
mutable int32 _hasCachedClasses : 1;
|
|
|
|
mutable ClassesDictionary _classes;
|
|
CriticalSection _locker;
|
|
|
|
int32 _reloadCount;
|
|
MString _name;
|
|
String _assemblyPath;
|
|
|
|
Array<byte> _debugData;
|
|
|
|
const MAssemblyOptions _options;
|
|
|
|
public:
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="MAssembly"/> class.
|
|
/// </summary>
|
|
/// <param name="domain">The assembly domain.</param>
|
|
/// <param name="name">The assembly name.</param>
|
|
/// <param name="options">The assembly options.</param>
|
|
MAssembly(MDomain* domain, const StringAnsiView& name, const MAssemblyOptions& options);
|
|
|
|
/// <summary>
|
|
/// Finalizes an instance of the <see cref="MAssembly"/> class.
|
|
/// </summary>
|
|
~MAssembly();
|
|
|
|
public:
|
|
|
|
/// <summary>
|
|
/// Managed assembly actions delegate type.
|
|
/// </summary>
|
|
typedef Delegate<MAssembly*> AssemblyDelegate;
|
|
|
|
/// <summary>
|
|
/// Action fired when assembly starts loading.
|
|
/// </summary>
|
|
AssemblyDelegate Loading;
|
|
|
|
/// <summary>
|
|
/// Action fired when assembly gets loaded.
|
|
/// </summary>
|
|
AssemblyDelegate Loaded;
|
|
|
|
/// <summary>
|
|
/// Action fired when assembly loading fails.
|
|
/// </summary>
|
|
AssemblyDelegate LoadFailed;
|
|
|
|
/// <summary>
|
|
/// Action fired when assembly start unloading.
|
|
/// </summary>
|
|
AssemblyDelegate Unloading;
|
|
|
|
/// <summary>
|
|
/// Action fired when assembly gets unloaded.
|
|
/// </summary>
|
|
AssemblyDelegate Unloaded;
|
|
|
|
public:
|
|
|
|
/// <summary>
|
|
/// Returns true if assembly is during loading state.
|
|
/// </summary>
|
|
FORCE_INLINE bool IsLoading() const
|
|
{
|
|
return _isLoading != 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if assembly has been loaded.
|
|
/// </summary>
|
|
FORCE_INLINE bool IsLoaded() const
|
|
{
|
|
return _isLoaded != 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the assembly name.
|
|
/// </summary>
|
|
FORCE_INLINE const MString& GetName() const
|
|
{
|
|
return _name;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the assembly name as string.
|
|
/// </summary>
|
|
String ToString() const;
|
|
|
|
/// <summary>
|
|
/// Gets the assembly path.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// If assembly was made from scratch (empty), path will return null.
|
|
/// </remarks>
|
|
FORCE_INLINE const String& GetAssemblyPath() const
|
|
{
|
|
return _assemblyPath;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the parent domain.
|
|
/// </summary>
|
|
FORCE_INLINE MDomain* GetDomain() const
|
|
{
|
|
return _domain;
|
|
}
|
|
|
|
#if USE_MONO
|
|
/// <summary>
|
|
/// Gets the Mono assembly.
|
|
/// </summary>
|
|
FORCE_INLINE MonoAssembly* GetMonoAssembly() const
|
|
{
|
|
return _monoAssembly;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the Mono image.
|
|
/// </summary>
|
|
FORCE_INLINE MonoImage* GetMonoImage() const
|
|
{
|
|
return _monoImage;
|
|
}
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Gets the options that assembly was created with.
|
|
/// </summary>
|
|
FORCE_INLINE const MAssemblyOptions& GetOptions() const
|
|
{
|
|
return _options;
|
|
}
|
|
|
|
public:
|
|
|
|
/// <summary>
|
|
/// Loads assembly for domain.
|
|
/// </summary>
|
|
/// <param name="assemblyPath">The assembly path.</param>
|
|
/// <returns>True if cannot load, otherwise false</returns>
|
|
bool Load(const String& assemblyPath);
|
|
|
|
#if USE_MONO
|
|
/// <summary>
|
|
/// Loads assembly for domain.
|
|
/// </summary>
|
|
/// <param name="monoImage">The assembly image.</param>
|
|
/// <returns>True if cannot load, otherwise false.</returns>
|
|
bool Load(MonoImage* monoImage);
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Cleanup data. Caller must ensure not to use any types from this assembly after it has been unloaded.
|
|
/// </summary>
|
|
/// <param name="isReloading">If true assembly is during reloading and should force release the runtime data.</param>
|
|
void Unload(bool isReloading = false);
|
|
|
|
public:
|
|
|
|
/// <summary>
|
|
/// Attempts to find a managed class with the specified namespace and name in this assembly. Returns null if one cannot be found.
|
|
/// </summary>
|
|
/// <param name="typeName">The type name.</param>
|
|
/// <returns>The class object or null if failed to find it.</returns>
|
|
MClass* GetClass(const StringAnsiView& typeName) const;
|
|
|
|
#if USE_MONO
|
|
/// <summary>
|
|
/// Converts an internal mono representation of a class into engine class.
|
|
/// </summary>
|
|
/// <param name="monoClass">The Mono class.</param>
|
|
/// <returns>The class object.</returns>
|
|
MClass* GetClass(MonoClass* monoClass) const;
|
|
|
|
/// <summary>
|
|
/// Gets the native of the assembly (for the current domain). Can be used to pass to the scripting backend as a parameter.
|
|
/// </summary>
|
|
/// <returns>The native assembly object.</returns>
|
|
MonoReflectionAssembly* GetNative() const;
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Gets the classes lookup cache. Performs full initialization if not cached. The result cache contains all classes from the assembly.
|
|
/// </summary>
|
|
/// <returns>The cache.</returns>
|
|
const ClassesDictionary& GetClasses() const;
|
|
|
|
private:
|
|
|
|
/// <summary>
|
|
/// Loads the assembly for domain.
|
|
/// </summary>
|
|
/// <returns>True if failed, otherwise false.</returns>
|
|
bool LoadDefault(const String& assemblyPath);
|
|
|
|
/// <summary>
|
|
/// Loads the assembly for domain from non-blocking image.
|
|
/// </summary>
|
|
/// <returns>True if failed, otherwise false.</returns>
|
|
bool LoadWithImage(const String& assemblyPath);
|
|
|
|
void OnLoading();
|
|
void OnLoaded(const struct DateTime& startTime);
|
|
void OnLoadFailed();
|
|
};
|