Support JavaScript modules

- With modules JavaScript code can be split up into multiple files. We
	already implemented such a mechanism (`Engine.LoadLibrary`) in
	multiple parts of the engine. The advantage of using modules is
	that it's standart (JS-devs are familiar with it) and it doesn't
	has to be implemented multiple times.
	Note that `Engine.LoadLibrary` loads all files in a directory
	while the new `import` only loads one file.

- With modules seemingly global variables are local to that
	script/module. We already implemented such a mechanism
	(`ScriptInterface::LoadScript`).
This commit is contained in:
phosit
2025-01-15 20:38:37 +01:00
committed by phosit
parent 475053ea7c
commit c6d42ebbd5
13 changed files with 360 additions and 8 deletions
+8 -7
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 2024 Wildfire Games.
/* Copyright (C) 2025 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -47,19 +47,18 @@ ERROR_TYPE(Scripting_DefineType, CreationFailed);
// but as large as necessary for all wrapped functions)
#define SCRIPT_INTERFACE_MAX_ARGS 8
namespace boost { namespace random { class rand48; } }
class Path;
class ScriptContext;
class ScriptInterface;
struct ScriptInterface_impl;
namespace Script { class ModuleLoader; }
using VfsPath = Path;
class ScriptContext;
// Using a global object for the context is a workaround until Simulation, AI, etc,
// use their own threads and also their own contexts.
extern thread_local std::shared_ptr<ScriptContext> g_ScriptContext;
namespace boost { namespace random { class rand48; } }
class Path;
using VfsPath = Path;
/**
* Abstraction around a SpiderMonkey JS::Realm.
*
@@ -137,6 +136,8 @@ public:
return ObjectFromCBData<T>(rq);
}
Script::ModuleLoader& GetModuleLoader() const;
/**
* GetGeneralJSContext returns the context without starting a GC request and without
* entering the ScriptInterface compartment. It should only be used in specific situations,