NETCore.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include <Atomic/Core/CoreEvents.h>
  2. #include <Atomic/IO/FileSystem.h>
  3. #include <Atomic/IO/Log.h>
  4. #include <Atomic/Core/StringUtils.h>
  5. #include "CSEventHelper.h"
  6. #include "CSComponent.h"
  7. #include "NETCore.h"
  8. #include "NETManaged.h"
  9. #include "NETAssemblyFile.h"
  10. #ifdef ATOMIC_PLATFORM_WINDOWS
  11. #include "Platforms/Windows/NETHostWindows.h"
  12. #else
  13. #include "Platforms/Unix/NETHostUnix.h"
  14. #endif
  15. namespace Atomic
  16. {
  17. /// Register NETCore library objects.
  18. void ATOMIC_API RegisterNETCoreLibrary(Context* context);
  19. WeakPtr<Context> NETCore::csContext_;
  20. WeakPtr<NETCore> NETCore::instance_;
  21. NETCore::NETCore(Context* context) :
  22. Object(context)
  23. {
  24. RegisterNETCoreLibrary(context_);
  25. assert(!instance_);
  26. instance_ = this;
  27. csContext_ = context;
  28. }
  29. NETCore::~NETCore()
  30. {
  31. Shutdown();
  32. context_->RemoveGlobalEventListener(context_->GetSubsystem<CSEventDispatcher>());
  33. context_->RemoveSubsystem(CSEventDispatcher::GetTypeStatic());
  34. context_->RemoveSubsystem(NETManaged::GetTypeStatic());
  35. instance_ = NULL;
  36. }
  37. void NETCore::Shutdown()
  38. {
  39. RefCounted::SetRefCountedDeletedFunction(0);
  40. if (netHost_.NotNull())
  41. {
  42. netHost_->Shutdown();
  43. netHost_ = 0;
  44. }
  45. }
  46. extern "C"
  47. {
  48. // http://ybeernet.blogspot.com/2011/03/techniques-of-calling-unmanaged-code.html
  49. // pinvoke is faster than [UnmanagedFunctionPointer] :/
  50. // [SuppressUnmanagedCodeSecurity] <--- add this attribute, in any event
  51. #ifdef ATOMIC_PLATFORM_WINDOWS
  52. #pragma warning(disable: 4244) // possible loss of data
  53. #define ATOMIC_EXPORT_API __declspec(dllexport)
  54. #else
  55. #define ATOMIC_EXPORT_API
  56. #endif
  57. ATOMIC_EXPORT_API ClassID csb_Atomic_RefCounted_GetClassID(RefCounted* refCounted)
  58. {
  59. if (!refCounted)
  60. return 0;
  61. return refCounted->GetClassID();
  62. }
  63. ATOMIC_EXPORT_API RefCounted* csb_AtomicEngine_GetSubsystem(const char* name)
  64. {
  65. return NETCore::GetContext()->GetSubsystem(name);
  66. }
  67. ATOMIC_EXPORT_API void csb_AtomicEngine_ReleaseRef(RefCounted* ref)
  68. {
  69. if (!ref)
  70. return;
  71. ref->ReleaseRef();
  72. }
  73. }
  74. void NETCore::WaitForDebuggerConnect()
  75. {
  76. netHost_->WaitForDebuggerConnect();
  77. }
  78. void NETCore::AddAssemblyLoadPath(const String& assemblyPath)
  79. {
  80. typedef void (*AddAssemblyLoadPathFunction)(const char* assemblyPath);
  81. AddAssemblyLoadPathFunction addAssemblyLoadPath;
  82. bool result = CreateDelegate(
  83. "AtomicNETBootstrap",
  84. "Atomic.Bootstrap.AtomicLoadContext",
  85. "AddAssemblyLoadPath",
  86. (void**) &addAssemblyLoadPath);
  87. if (result)
  88. {
  89. addAssemblyLoadPath(assemblyPath.CString());
  90. }
  91. }
  92. bool NETCore::CreateDelegate(const String& assemblyName, const String& qualifiedClassName, const String& methodName, void** funcOut)
  93. {
  94. return netHost_->CreateDelegate(assemblyName, qualifiedClassName, methodName, funcOut);
  95. }
  96. bool NETCore::Initialize(String& errorMsg)
  97. {
  98. #ifdef ATOMIC_PLATFORM_WINDOWS
  99. netHost_ = new NETHostWindows(context_);
  100. #else
  101. netHost_ = new NETHostUnix(context_);
  102. #endif
  103. if (!netHost_->Initialize())
  104. {
  105. errorMsg = "NETHost Failed to Initialize";
  106. return false;
  107. }
  108. // MOVE THIS!
  109. typedef void (*StartupFunction)(const char* assemblyLoadPaths);
  110. StartupFunction startup;
  111. // The coreclr binding model will become locked upon loading the first assembly that is not on the TPA list, or
  112. // upon initializing the default context for the first time. For this test, test assemblies are located alongside
  113. // corerun, and hence will be on the TPA list. So, we should be able to set the default context once successfully,
  114. // and fail on the second try.
  115. // AssemblyLoadContext
  116. // https://github.com/dotnet/corefx/issues/3054
  117. // dnx loader
  118. // https://github.com/aspnet/dnx/tree/dev/src/Microsoft.Dnx.Loader
  119. bool result = netHost_->CreateDelegate(
  120. "AtomicNETBootstrap",
  121. "Atomic.Bootstrap.AtomicLoadContext",
  122. "Startup",
  123. (void**) &startup);
  124. if (result)
  125. {
  126. startup(netHost_->GetCoreCLRAssemblyLoadPaths().CString());
  127. }
  128. // MOVE THIS!
  129. typedef void (*InitializeFunction)();
  130. InitializeFunction init;
  131. result = netHost_->CreateDelegate(
  132. "AtomicNETEngine",
  133. "AtomicEngine.Atomic",
  134. "Initialize",
  135. (void**) &init);
  136. if (result)
  137. {
  138. init();
  139. }
  140. SharedPtr<NETManaged> managed(new NETManaged(context_));
  141. context_->RegisterSubsystem(managed);
  142. SharedPtr<CSEventDispatcher> dispatcher(new CSEventDispatcher(context_));
  143. context_->RegisterSubsystem(dispatcher);
  144. context_->AddGlobalEventListener(dispatcher);
  145. if (!context_->GetEditorContext())
  146. {
  147. SubscribeToEvent(E_UPDATE, HANDLER(NETCore, HandleUpdate));
  148. }
  149. return managed->Initialize();
  150. }
  151. void NETCore::HandleUpdate(StringHash eventType, VariantMap& eventData)
  152. {
  153. using namespace Update;
  154. GetSubsystem<NETManaged>()->NETUpdate(eventData[P_TIMESTEP].GetFloat());
  155. }
  156. void RegisterNETCoreLibrary(Context* context)
  157. {
  158. NETAssemblyFile::RegisterObject(context);
  159. CSComponent::RegisterObject(context);
  160. }
  161. }