Merge pull request #38131 from akien-mga/3.2-cherrypicks
Cherry-picks for the 3.2 branch (future 3.2.2) - 3rd batch
This commit is contained in:
commit
ed27b7e6b9
|
@ -828,12 +828,11 @@ public:
|
|||
static const int HIDDEN = 1;
|
||||
static const int ON_TOP = 2;
|
||||
|
||||
private:
|
||||
protected:
|
||||
int current_state;
|
||||
List<EditorSpatialGizmo *> current_gizmos;
|
||||
HashMap<String, Vector<Ref<SpatialMaterial> > > materials;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
virtual bool has_gizmo(Spatial *p_spatial);
|
||||
virtual Ref<EditorSpatialGizmo> create_gizmo(Spatial *p_spatial);
|
||||
|
|
|
@ -57,17 +57,18 @@ void TileMapEditor::_notification(int p_what) {
|
|||
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
get_tree()->connect("node_removed", this, "_node_removed");
|
||||
FALLTHROUGH;
|
||||
}
|
||||
|
||||
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
|
||||
|
||||
if (is_visible_in_tree()) {
|
||||
_update_palette();
|
||||
}
|
||||
FALLTHROUGH;
|
||||
}
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
|
||||
get_tree()->connect("node_removed", this, "_node_removed");
|
||||
paint_button->set_icon(get_icon("Edit", "EditorIcons"));
|
||||
bucket_fill_button->set_icon(get_icon("Bucket", "EditorIcons"));
|
||||
picker_button->set_icon(get_icon("ColorPick", "EditorIcons"));
|
||||
|
|
|
@ -4075,6 +4075,25 @@ JointSpatialGizmoPlugin::JointSpatialGizmoPlugin() {
|
|||
create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)));
|
||||
create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1)));
|
||||
create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1)));
|
||||
|
||||
update_timer = memnew(Timer);
|
||||
update_timer->set_name("JointGizmoUpdateTimer");
|
||||
update_timer->set_wait_time(1.0 / 120.0);
|
||||
update_timer->connect("timeout", this, "incremental_update_gizmos");
|
||||
update_timer->set_autostart(true);
|
||||
EditorNode::get_singleton()->call_deferred("add_child", update_timer);
|
||||
}
|
||||
|
||||
void JointSpatialGizmoPlugin::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("incremental_update_gizmos"), &JointSpatialGizmoPlugin::incremental_update_gizmos);
|
||||
}
|
||||
|
||||
void JointSpatialGizmoPlugin::incremental_update_gizmos() {
|
||||
if (!current_gizmos.empty()) {
|
||||
update_idx++;
|
||||
update_idx = update_idx % current_gizmos.size();
|
||||
redraw(current_gizmos[update_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
bool JointSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
|
||||
|
|
|
@ -390,6 +390,14 @@ class JointSpatialGizmoPlugin : public EditorSpatialGizmoPlugin {
|
|||
|
||||
GDCLASS(JointSpatialGizmoPlugin, EditorSpatialGizmoPlugin);
|
||||
|
||||
Timer *update_timer;
|
||||
uint64_t update_idx = 0;
|
||||
|
||||
void incremental_update_gizmos();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
bool has_gizmo(Spatial *p_spatial);
|
||||
String get_name() const;
|
||||
|
|
|
@ -2683,6 +2683,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
|
|||
LocalVarNode *local_var = branch->body->variables[e->key()];
|
||||
local_var->assign = e->value();
|
||||
local_var->set_datatype(local_var->assign->get_datatype());
|
||||
local_var->assignments++;
|
||||
|
||||
IdentifierNode *id2 = alloc_node<IdentifierNode>();
|
||||
id2->name = local_var->name;
|
||||
|
@ -3673,6 +3674,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
|
|||
_set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ").");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < outer_class->variables.size(); i++) {
|
||||
if (outer_class->variables[i].identifier == name) {
|
||||
_set_error("A variable named \"" + String(name) + "\" already exists in the outer class scope (at line " + itos(outer_class->variables[i].line) + ").");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
outer_class = outer_class->owner;
|
||||
}
|
||||
|
@ -6568,6 +6575,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
|
|||
node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true);
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (!node_type.has_type) {
|
||||
_mark_line_as_unsafe(op->line);
|
||||
_add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string());
|
||||
}
|
||||
#endif // DEBUG_ENABLED
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
using System.IO;
|
||||
|
||||
namespace GodotTools.Core
|
||||
{
|
||||
public static class FileUtils
|
||||
{
|
||||
public static void SaveBackupCopy(string filePath)
|
||||
{
|
||||
string backupPathBase = filePath + ".old";
|
||||
string backupPath = backupPathBase;
|
||||
|
||||
const int maxAttempts = 5;
|
||||
int attempt = 1;
|
||||
|
||||
while (File.Exists(backupPath) && attempt <= maxAttempts)
|
||||
{
|
||||
backupPath = backupPathBase + "." + (attempt);
|
||||
attempt++;
|
||||
}
|
||||
|
||||
if (attempt > maxAttempts + 1)
|
||||
return;
|
||||
|
||||
File.Copy(filePath, backupPath, overwrite: true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@
|
|||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FileUtils.cs" />
|
||||
<Compile Include="ProcessExtensions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="StringExtensions.cs" />
|
||||
|
|
|
@ -153,7 +153,12 @@ EndProject";
|
|||
var result = regex.Replace(input,m => dict[m.Value]);
|
||||
|
||||
if (result != input)
|
||||
{
|
||||
// Save a copy of the solution before replacing it
|
||||
FileUtils.SaveBackupCopy(slnPath);
|
||||
|
||||
File.WriteAllText(slnPath, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,28 @@ using Microsoft.Build.Construction;
|
|||
|
||||
namespace GodotTools.ProjectEditor
|
||||
{
|
||||
public sealed class MSBuildProject
|
||||
{
|
||||
public ProjectRootElement Root { get; }
|
||||
|
||||
public bool HasUnsavedChanges => Root.HasUnsavedChanges;
|
||||
|
||||
public void Save() => Root.Save();
|
||||
|
||||
public MSBuildProject(ProjectRootElement root)
|
||||
{
|
||||
Root = root;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProjectUtils
|
||||
{
|
||||
public static MSBuildProject Open(string path)
|
||||
{
|
||||
var root = ProjectRootElement.Open(path);
|
||||
return root != null ? new MSBuildProject(root) : null;
|
||||
}
|
||||
|
||||
public static void AddItemToProjectChecked(string projectPath, string itemType, string include)
|
||||
{
|
||||
var dir = Directory.GetParent(projectPath).FullName;
|
||||
|
@ -43,7 +63,6 @@ namespace GodotTools.ProjectEditor
|
|||
|
||||
public static void RemoveItemFromProjectChecked(string projectPath, string itemType, string include)
|
||||
{
|
||||
var dir = Directory.GetParent(projectPath).FullName;
|
||||
var root = ProjectRootElement.Open(projectPath);
|
||||
Debug.Assert(root != null);
|
||||
|
||||
|
@ -59,8 +78,6 @@ namespace GodotTools.ProjectEditor
|
|||
var root = ProjectRootElement.Open(projectPath);
|
||||
Debug.Assert(root != null);
|
||||
|
||||
bool dirty = false;
|
||||
|
||||
var oldFolderNormalized = oldFolder.NormalizePath();
|
||||
var newFolderNormalized = newFolder.NormalizePath();
|
||||
string absOldFolderNormalized = Path.GetFullPath(oldFolderNormalized).NormalizePath();
|
||||
|
@ -71,10 +88,9 @@ namespace GodotTools.ProjectEditor
|
|||
string absPathNormalized = Path.GetFullPath(item.Include).NormalizePath();
|
||||
string absNewIncludeNormalized = absNewFolderNormalized + absPathNormalized.Substring(absOldFolderNormalized.Length);
|
||||
item.Include = absNewIncludeNormalized.RelativeToPath(dir).Replace("/", "\\");
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (dirty)
|
||||
if (root.HasUnsavedChanges)
|
||||
root.Save();
|
||||
}
|
||||
|
||||
|
@ -150,12 +166,9 @@ namespace GodotTools.ProjectEditor
|
|||
}
|
||||
|
||||
/// Simple function to make sure the Api assembly references are configured correctly
|
||||
public static void FixApiHintPath(string projectPath)
|
||||
public static void FixApiHintPath(MSBuildProject project)
|
||||
{
|
||||
var root = ProjectRootElement.Open(projectPath);
|
||||
Debug.Assert(root != null);
|
||||
|
||||
bool dirty = false;
|
||||
var root = project.Root;
|
||||
|
||||
void AddPropertyIfNotPresent(string name, string condition, string value)
|
||||
{
|
||||
|
@ -170,7 +183,6 @@ namespace GodotTools.ProjectEditor
|
|||
}
|
||||
|
||||
root.AddProperty(name, value).Condition = " " + condition + " ";
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
AddPropertyIfNotPresent(name: "ApiConfiguration",
|
||||
|
@ -212,7 +224,6 @@ namespace GodotTools.ProjectEditor
|
|||
}
|
||||
|
||||
referenceWithHintPath.AddMetadata("HintPath", hintPath);
|
||||
dirty = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -221,14 +232,12 @@ namespace GodotTools.ProjectEditor
|
|||
{
|
||||
// Found a Reference item without a HintPath
|
||||
referenceWithoutHintPath.AddMetadata("HintPath", hintPath);
|
||||
dirty = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Found no Reference item at all. Add it.
|
||||
root.AddItem("Reference", referenceName).Condition = " " + condition + " ";
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
const string coreProjectName = "GodotSharp";
|
||||
|
@ -242,17 +251,11 @@ namespace GodotTools.ProjectEditor
|
|||
|
||||
SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath);
|
||||
SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath);
|
||||
|
||||
if (dirty)
|
||||
root.Save();
|
||||
}
|
||||
|
||||
public static void MigrateFromOldConfigNames(string projectPath)
|
||||
public static void MigrateFromOldConfigNames(MSBuildProject project)
|
||||
{
|
||||
var root = ProjectRootElement.Open(projectPath);
|
||||
Debug.Assert(root != null);
|
||||
|
||||
bool dirty = false;
|
||||
var root = project.Root;
|
||||
|
||||
bool hasGodotProjectGeneratorVersion = false;
|
||||
bool foundOldConfiguration = false;
|
||||
|
@ -267,7 +270,6 @@ namespace GodotTools.ProjectEditor
|
|||
{
|
||||
configItem.Value = "Debug";
|
||||
foundOldConfiguration = true;
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +277,6 @@ namespace GodotTools.ProjectEditor
|
|||
{
|
||||
root.PropertyGroups.First(g => g.Condition == string.Empty)?
|
||||
.AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (!foundOldConfiguration)
|
||||
|
@ -299,33 +300,21 @@ namespace GodotTools.ProjectEditor
|
|||
void MigrateConditions(string oldCondition, string newCondition)
|
||||
{
|
||||
foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition))
|
||||
{
|
||||
propertyGroup.Condition = " " + newCondition + " ";
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
foreach (var propertyGroup in root.PropertyGroups)
|
||||
{
|
||||
foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition))
|
||||
{
|
||||
prop.Condition = " " + newCondition + " ";
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition))
|
||||
{
|
||||
itemGroup.Condition = " " + newCondition + " ";
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
foreach (var itemGroup in root.ItemGroups)
|
||||
{
|
||||
foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition))
|
||||
{
|
||||
item.Condition = " " + newCondition + " ";
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,10 +329,6 @@ namespace GodotTools.ProjectEditor
|
|||
MigrateConfigurationConditions("Release", "ExportRelease");
|
||||
MigrateConfigurationConditions("Tools", "Debug"); // Must be last
|
||||
}
|
||||
|
||||
|
||||
if (dirty)
|
||||
root.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,13 +168,13 @@ namespace GodotTools.Export
|
|||
|
||||
// Add dependency assemblies
|
||||
|
||||
var dependencies = new Godot.Collections.Dictionary<string, string>();
|
||||
var assemblies = new Godot.Collections.Dictionary<string, string>();
|
||||
|
||||
string projectDllName = GodotSharpEditor.ProjectAssemblyName;
|
||||
string projectDllSrcDir = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig);
|
||||
string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll");
|
||||
|
||||
dependencies[projectDllName] = projectDllSrcPath;
|
||||
assemblies[projectDllName] = projectDllSrcPath;
|
||||
|
||||
if (platform == OS.Platforms.Android)
|
||||
{
|
||||
|
@ -184,15 +184,15 @@ namespace GodotTools.Export
|
|||
if (!File.Exists(monoAndroidAssemblyPath))
|
||||
throw new FileNotFoundException("Assembly not found: 'Mono.Android'", monoAndroidAssemblyPath);
|
||||
|
||||
dependencies["Mono.Android"] = monoAndroidAssemblyPath;
|
||||
assemblies["Mono.Android"] = monoAndroidAssemblyPath;
|
||||
}
|
||||
|
||||
string bclDir = DeterminePlatformBclDir(platform);
|
||||
|
||||
var initialDependencies = dependencies.Duplicate();
|
||||
internal_GetExportedAssemblyDependencies(initialDependencies, buildConfig, bclDir, dependencies);
|
||||
var initialAssemblies = assemblies.Duplicate();
|
||||
internal_GetExportedAssemblyDependencies(initialAssemblies, buildConfig, bclDir, assemblies);
|
||||
|
||||
AddI18NAssemblies(dependencies, bclDir);
|
||||
AddI18NAssemblies(assemblies, bclDir);
|
||||
|
||||
string outputDataDir = null;
|
||||
|
||||
|
@ -211,22 +211,34 @@ namespace GodotTools.Export
|
|||
Directory.CreateDirectory(outputDataGameAssembliesDir);
|
||||
}
|
||||
|
||||
foreach (var dependency in dependencies)
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
void AddToAssembliesDir(string fileSrcPath)
|
||||
{
|
||||
string dependSrcPath = dependency.Value;
|
||||
|
||||
if (assembliesInsidePck)
|
||||
{
|
||||
string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile());
|
||||
AddFile(dependSrcPath, dependDstPath);
|
||||
string fileDstPath = Path.Combine(resAssembliesDir, fileSrcPath.GetFile());
|
||||
AddFile(fileSrcPath, fileDstPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
string dependDstPath = Path.Combine(outputDataDir, "Assemblies", dependSrcPath.GetFile());
|
||||
File.Copy(dependSrcPath, dependDstPath);
|
||||
Debug.Assert(outputDataDir != null);
|
||||
string fileDstPath = Path.Combine(outputDataDir, "Assemblies", fileSrcPath.GetFile());
|
||||
File.Copy(fileSrcPath, fileDstPath);
|
||||
}
|
||||
}
|
||||
|
||||
string assemblySrcPath = assembly.Value;
|
||||
|
||||
string assemblyPathWithoutExtension = Path.ChangeExtension(assemblySrcPath, null);
|
||||
string pdbSrcPath = assemblyPathWithoutExtension + ".pdb";
|
||||
|
||||
AddToAssembliesDir(assemblySrcPath);
|
||||
|
||||
if (File.Exists(pdbSrcPath))
|
||||
AddToAssembliesDir(pdbSrcPath);
|
||||
}
|
||||
|
||||
// AOT compilation
|
||||
bool aotEnabled = platform == OS.Platforms.iOS || (bool)ProjectSettings.GetSetting("mono/export/aot/enabled");
|
||||
|
||||
|
@ -254,7 +266,7 @@ namespace GodotTools.Export
|
|||
ToolchainPath = aotToolchainPath
|
||||
};
|
||||
|
||||
AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, dependencies);
|
||||
AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, assemblies);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,7 +378,7 @@ namespace GodotTools.Export
|
|||
if (PlatformRequiresCustomBcl(platform))
|
||||
throw new FileNotFoundException($"Missing BCL (Base Class Library) for platform: {platform}");
|
||||
|
||||
platformBclDir = typeof(object).Assembly.Location; // Use the one we're running on
|
||||
platformBclDir = typeof(object).Assembly.Location.GetBaseDir(); // Use the one we're running on
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,7 +437,7 @@ namespace GodotTools.Export
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialDependencies,
|
||||
string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencies);
|
||||
private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialAssemblies,
|
||||
string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencyAssemblies);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Godot;
|
||||
using GodotTools.Core;
|
||||
using GodotTools.Export;
|
||||
using GodotTools.Utils;
|
||||
using System;
|
||||
|
@ -450,13 +451,27 @@ namespace GodotTools
|
|||
{
|
||||
// Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease
|
||||
DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath);
|
||||
// Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease
|
||||
ProjectUtils.MigrateFromOldConfigNames(GodotSharpDirs.ProjectCsProjPath);
|
||||
|
||||
// Apply the other fixes after configurations are migrated
|
||||
var msbuildProject = ProjectUtils.Open(GodotSharpDirs.ProjectCsProjPath)
|
||||
?? throw new Exception("Cannot open C# project");
|
||||
|
||||
// NOTE: The order in which changes are made to the project is important
|
||||
|
||||
// Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease
|
||||
ProjectUtils.MigrateFromOldConfigNames(msbuildProject);
|
||||
|
||||
// Apply the other fixes only after configurations have been migrated
|
||||
|
||||
// Make sure the existing project has Api assembly references configured correctly
|
||||
ProjectUtils.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
|
||||
ProjectUtils.FixApiHintPath(msbuildProject);
|
||||
|
||||
if (msbuildProject.HasUnsavedChanges)
|
||||
{
|
||||
// Save a copy of the project before replacing it
|
||||
FileUtils.SaveBackupCopy(GodotSharpDirs.ProjectCsProjPath);
|
||||
|
||||
msbuildProject.Save();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -231,14 +231,14 @@ int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObje
|
|||
return err;
|
||||
}
|
||||
|
||||
uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_dependencies,
|
||||
MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_dependencies) {
|
||||
Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_dependencies);
|
||||
uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies,
|
||||
MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) {
|
||||
Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies);
|
||||
String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config);
|
||||
String custom_bcl_dir = GDMonoMarshal::mono_string_to_godot(p_custom_bcl_dir);
|
||||
Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies);
|
||||
Dictionary assembly_dependencies = GDMonoMarshal::mono_object_to_variant(r_assembly_dependencies);
|
||||
|
||||
return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, dependencies);
|
||||
return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, assembly_dependencies);
|
||||
}
|
||||
|
||||
MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) {
|
||||
|
|
|
@ -50,13 +50,13 @@ String get_assemblyref_name(MonoImage *p_image, int index) {
|
|||
return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME]));
|
||||
}
|
||||
|
||||
Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) {
|
||||
Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) {
|
||||
MonoImage *image = p_assembly->get_image();
|
||||
|
||||
for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) {
|
||||
String ref_name = get_assemblyref_name(image, i);
|
||||
|
||||
if (r_dependencies.has(ref_name))
|
||||
if (r_assembly_dependencies.has(ref_name))
|
||||
continue;
|
||||
|
||||
GDMonoAssembly *ref_assembly = NULL;
|
||||
|
@ -93,17 +93,17 @@ Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String>
|
|||
ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
|
||||
|
||||
// Use the path we got from the search. Don't try to get the path from the loaded assembly as we can't trust it will be from the selected BCL dir.
|
||||
r_dependencies[ref_name] = path;
|
||||
r_assembly_dependencies[ref_name] = path;
|
||||
|
||||
Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
|
||||
Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_assembly_dependencies);
|
||||
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
|
||||
const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) {
|
||||
Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
|
||||
const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_assembly_dependencies) {
|
||||
MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport");
|
||||
ERR_FAIL_NULL_V(export_domain, FAILED);
|
||||
_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);
|
||||
|
@ -113,16 +113,16 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencie
|
|||
Vector<String> search_dirs;
|
||||
GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir);
|
||||
|
||||
for (const Variant *key = p_initial_dependencies.next(); key; key = p_initial_dependencies.next(key)) {
|
||||
for (const Variant *key = p_initial_assemblies.next(); key; key = p_initial_assemblies.next(key)) {
|
||||
String assembly_name = *key;
|
||||
String assembly_path = p_initial_dependencies[*key];
|
||||
String assembly_path = p_initial_assemblies[*key];
|
||||
|
||||
GDMonoAssembly *assembly = NULL;
|
||||
bool load_success = GDMono::get_singleton()->load_assembly_from(assembly_name, assembly_path, &assembly, /* refonly: */ true);
|
||||
|
||||
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
|
||||
|
||||
Error err = get_assembly_dependencies(assembly, search_dirs, r_dependencies);
|
||||
Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies);
|
||||
if (err != OK)
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -41,8 +41,8 @@ namespace GodotSharpExport {
|
|||
|
||||
Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies);
|
||||
|
||||
Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
|
||||
const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies);
|
||||
Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
|
||||
const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_assembly_dependencies);
|
||||
|
||||
} // namespace GodotSharpExport
|
||||
|
||||
|
|
|
@ -128,12 +128,8 @@ void gd_mono_profiler_init() {
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_ENABLED)
|
||||
|
||||
void gd_mono_debug_init() {
|
||||
|
||||
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
|
||||
|
||||
CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8();
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
@ -158,6 +154,10 @@ void gd_mono_debug_init() {
|
|||
return; // Exported games don't use the project settings to setup the debugger agent
|
||||
#endif
|
||||
|
||||
// Debugging enabled
|
||||
|
||||
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
|
||||
|
||||
// --debugger-agent=help
|
||||
const char *options[] = {
|
||||
"--soft-breakpoints",
|
||||
|
@ -166,7 +166,6 @@ void gd_mono_debug_init() {
|
|||
mono_jit_parse_options(2, (char **)options);
|
||||
}
|
||||
|
||||
#endif // defined(DEBUG_ENABLED)
|
||||
#endif // !defined(JAVASCRIPT_ENABLED)
|
||||
|
||||
#if defined(JAVASCRIPT_ENABLED)
|
||||
|
@ -174,6 +173,7 @@ MonoDomain *gd_initialize_mono_runtime() {
|
|||
const char *vfs_prefix = "managed";
|
||||
int enable_debugging = 0;
|
||||
|
||||
// TODO: Provide a way to enable debugging on WASM release builds.
|
||||
#ifdef DEBUG_ENABLED
|
||||
enable_debugging = 1;
|
||||
#endif
|
||||
|
@ -184,9 +184,7 @@ MonoDomain *gd_initialize_mono_runtime() {
|
|||
}
|
||||
#else
|
||||
MonoDomain *gd_initialize_mono_runtime() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
gd_mono_debug_init();
|
||||
#endif
|
||||
|
||||
#if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED)
|
||||
// I don't know whether this actually matters or not
|
||||
|
@ -1388,6 +1386,9 @@ bool _GodotSharp::is_runtime_initialized() {
|
|||
|
||||
void _GodotSharp::_reload_assemblies(bool p_soft_reload) {
|
||||
#ifdef GD_MONO_HOT_RELOAD
|
||||
// This method may be called more than once with `call_deferred`, so we need to check
|
||||
// again if reloading is needed to avoid reloading multiple times unnecessarily.
|
||||
if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed())
|
||||
CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -281,6 +281,13 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
|
|||
break;
|
||||
}
|
||||
|
||||
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
|
||||
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
|
||||
MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class);
|
||||
mono_field_set_value(p_object, mono_field, managed);
|
||||
break;
|
||||
}
|
||||
|
||||
ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
|
||||
} break;
|
||||
|
||||
|
|
|
@ -132,6 +132,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
|
|||
|
||||
if (array_type->eklass == CACHED_CLASS_RAW(Color))
|
||||
return Variant::POOL_COLOR_ARRAY;
|
||||
|
||||
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
|
||||
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
|
||||
return Variant::ARRAY;
|
||||
} break;
|
||||
|
||||
case MONO_TYPE_CLASS: {
|
||||
|
@ -217,6 +221,13 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
|
|||
|
||||
bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) {
|
||||
switch (p_array_type.type_encoding) {
|
||||
case MONO_TYPE_ARRAY:
|
||||
case MONO_TYPE_SZARRAY: {
|
||||
MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type());
|
||||
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
|
||||
r_elem_type = ManagedType::from_class(array_type_class);
|
||||
return true;
|
||||
} break;
|
||||
case MONO_TYPE_GENERICINST: {
|
||||
MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type());
|
||||
|
||||
|
@ -511,6 +522,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
|
|||
if (array_type->eklass == CACHED_CLASS_RAW(Color))
|
||||
return (MonoObject *)PoolColorArray_to_mono_array(p_var->operator PoolColorArray());
|
||||
|
||||
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
|
||||
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
|
||||
return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);
|
||||
|
||||
ERR_FAIL_V_MSG(NULL, "Attempted to convert Variant to a managed array of unmarshallable element type.");
|
||||
} break;
|
||||
|
||||
|
@ -805,6 +820,10 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
|
|||
if (array_type->eklass == CACHED_CLASS_RAW(Color))
|
||||
return mono_array_to_PoolColorArray((MonoArray *)p_obj);
|
||||
|
||||
GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
|
||||
if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
|
||||
return mono_array_to_Array((MonoArray *)p_obj);
|
||||
|
||||
if (p_fail_with_err) {
|
||||
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
|
||||
} else {
|
||||
|
@ -970,6 +989,18 @@ MonoArray *Array_to_mono_array(const Array &p_array) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) {
|
||||
int length = p_array.size();
|
||||
MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
MonoObject *boxed = variant_to_mono_object(p_array[i]);
|
||||
mono_array_setref(ret, i, boxed);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Array mono_array_to_Array(MonoArray *p_array) {
|
||||
Array ret;
|
||||
if (!p_array)
|
||||
|
|
|
@ -125,6 +125,7 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc);
|
|||
// Array
|
||||
|
||||
MonoArray *Array_to_mono_array(const Array &p_array);
|
||||
MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class);
|
||||
Array mono_array_to_Array(MonoArray *p_array);
|
||||
|
||||
// PoolIntArray
|
||||
|
|
|
@ -90,7 +90,9 @@ android {
|
|||
packagingOptions {
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/NOTICE'
|
||||
doNotStrip '**/*.so'
|
||||
|
||||
// Should be uncommented for development purpose within Android Studio
|
||||
// doNotStrip '**/*.so'
|
||||
}
|
||||
|
||||
// Both signing and zip-aligning will be done at export time
|
||||
|
|
|
@ -26,7 +26,9 @@ android {
|
|||
packagingOptions {
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/NOTICE'
|
||||
doNotStrip '**/*.so'
|
||||
|
||||
// Should be uncommented for development purpose within Android Studio
|
||||
// doNotStrip '**/*.so'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
|
|
@ -950,13 +950,13 @@ void AnimationPlayer::_animation_process(float p_delta) {
|
|||
play(queued.front()->get());
|
||||
String new_name = playback.assigned;
|
||||
queued.pop_front();
|
||||
if (end_notify)
|
||||
if (end_notify || playback.seeked)
|
||||
emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
|
||||
} else {
|
||||
//stop();
|
||||
playing = false;
|
||||
_set_process(false);
|
||||
if (end_notify)
|
||||
if (end_notify || playback.seeked)
|
||||
emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
|
||||
}
|
||||
end_reached = false;
|
||||
|
|
|
@ -151,6 +151,8 @@ Files extracted from upstream source:
|
|||
|
||||
- `jpgd*.{c,h}`
|
||||
|
||||
Patches in the `patches` directory should be re-applied after updates.
|
||||
|
||||
|
||||
## libogg
|
||||
|
||||
|
|
|
@ -2126,7 +2126,7 @@ namespace jpgd {
|
|||
|
||||
int jpeg_decoder::decode_next_mcu_row()
|
||||
{
|
||||
if (setjmp(m_jmp_state))
|
||||
if (::setjmp(m_jmp_state))
|
||||
return JPGD_FAILED;
|
||||
|
||||
const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));
|
||||
|
@ -3042,7 +3042,7 @@ namespace jpgd {
|
|||
|
||||
jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags)
|
||||
{
|
||||
if (setjmp(m_jmp_state))
|
||||
if (::setjmp(m_jmp_state))
|
||||
return;
|
||||
decode_init(pStream, flags);
|
||||
}
|
||||
|
@ -3055,7 +3055,7 @@ namespace jpgd {
|
|||
if (m_error_code)
|
||||
return JPGD_FAILED;
|
||||
|
||||
if (setjmp(m_jmp_state))
|
||||
if (::setjmp(m_jmp_state))
|
||||
return JPGD_FAILED;
|
||||
|
||||
decode_start();
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp
|
||||
index a0c494db61..257d0b7574 100644
|
||||
--- a/thirdparty/jpeg-compressor/jpgd.cpp
|
||||
+++ b/thirdparty/jpeg-compressor/jpgd.cpp
|
||||
@@ -2126,7 +2126,7 @@ namespace jpgd {
|
||||
|
||||
int jpeg_decoder::decode_next_mcu_row()
|
||||
{
|
||||
- if (setjmp(m_jmp_state))
|
||||
+ if (::setjmp(m_jmp_state))
|
||||
return JPGD_FAILED;
|
||||
|
||||
const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));
|
||||
@@ -3042,7 +3042,7 @@ namespace jpgd {
|
||||
|
||||
jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags)
|
||||
{
|
||||
- if (setjmp(m_jmp_state))
|
||||
+ if (::setjmp(m_jmp_state))
|
||||
return;
|
||||
decode_init(pStream, flags);
|
||||
}
|
||||
@@ -3055,7 +3055,7 @@ namespace jpgd {
|
||||
if (m_error_code)
|
||||
return JPGD_FAILED;
|
||||
|
||||
- if (setjmp(m_jmp_state))
|
||||
+ if (::setjmp(m_jmp_state))
|
||||
return JPGD_FAILED;
|
||||
|
||||
decode_start();
|
Loading…
Reference in New Issue