Merge pull request #50882 from akien-mga/3.x-cherrypicks

This commit is contained in:
Rémi Verschelde 2021-07-26 14:31:17 +02:00 committed by GitHub
commit cc194f68e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 464 additions and 200 deletions

View file

@ -420,3 +420,8 @@ ResourceFormatImporter *ResourceFormatImporter::singleton = nullptr;
ResourceFormatImporter::ResourceFormatImporter() {
singleton = this;
}
void ResourceImporter::_bind_methods() {
BIND_ENUM_CONSTANT(IMPORT_ORDER_DEFAULT);
BIND_ENUM_CONSTANT(IMPORT_ORDER_SCENE);
}

View file

@ -95,6 +95,9 @@ public:
class ResourceImporter : public Reference {
GDCLASS(ResourceImporter, Reference);
protected:
static void _bind_methods();
public:
virtual String get_importer_name() const = 0;
virtual String get_visible_name() const = 0;
@ -102,7 +105,7 @@ public:
virtual String get_save_extension() const = 0;
virtual String get_resource_type() const = 0;
virtual float get_priority() const { return 1.0; }
virtual int get_import_order() const { return 0; }
virtual int get_import_order() const { return IMPORT_ORDER_DEFAULT; }
struct ImportOption {
PropertyInfo option;
@ -115,6 +118,11 @@ public:
ImportOption() {}
};
enum ImportOrder {
IMPORT_ORDER_DEFAULT = 0,
IMPORT_ORDER_SCENE = 100,
};
virtual int get_preset_count() const { return 0; }
virtual String get_preset_name(int p_idx) const { return String(); }
@ -129,4 +137,6 @@ public:
virtual String get_import_settings_string() const { return String(); }
};
VARIANT_ENUM_CAST(ResourceImporter::ImportOrder);
#endif // RESOURCE_IMPORTER_H

View file

@ -93,8 +93,8 @@
<argument index="1" name="value" type="bool">
</argument>
<description>
If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer].
If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer].
If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer].
If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer].
</description>
</method>
<method name="set_collision_mask_bit">
@ -105,8 +105,8 @@
<argument index="1" name="value" type="bool">
</argument>
<description>
If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask].
If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask].
If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask].
If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask].
</description>
</method>
<method name="shape_find_owner" qualifiers="const">

View file

@ -107,8 +107,8 @@
<argument index="1" name="value" type="bool">
</argument>
<description>
If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer].
If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer].
If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_layer].
If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_layer].
</description>
</method>
<method name="set_collision_mask_bit">
@ -119,8 +119,8 @@
<argument index="1" name="value" type="bool">
</argument>
<description>
If [code]value[/value] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask].
If [code]value[/value] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask].
If [code]value[/code] is [code]true[/code], sets the specified [code]bit[/code] in the the [member collision_mask].
If [code]value[/code] is [code]false[/code], clears the specified [code]bit[/code] in the the [member collision_mask].
</description>
</method>
<method name="shape_find_owner" qualifiers="const">

View file

@ -969,11 +969,13 @@
<signal name="mouse_entered">
<description>
Emitted when the mouse enters the control's [code]Rect[/code] area, provided its [member mouse_filter] lets the event reach it.
[b]Note:[/b] [signal mouse_entered] will not be emitted if the mouse enters a child [Control] node before entering the parent's [code]Rect[/code] area, at least until the mouse is moved to reach the parent's [code]Rect[/code] area.
</description>
</signal>
<signal name="mouse_exited">
<description>
Emitted when the mouse leaves the control's [code]Rect[/code] area, provided its [member mouse_filter] lets the event reach it.
[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a child [Control] node, even if the mouse cursor is still inside the parent's [code]Rect[/code] area.
</description>
</signal>
<signal name="resized">

View file

@ -64,7 +64,7 @@
<return type="int">
</return>
<description>
Gets the order of this importer to be run when importing resources. Higher values will be called later. Use this to ensure the importer runs after the dependencies are already imported.
Gets the order of this importer to be run when importing resources. Importers with [i]lower[/i] import orders will be called first, and higher values will be called later. Use this to ensure the importer runs after the dependencies are already imported. The default import order is [code]0[/code] unless overridden by a specific importer. See [enum ResourceImporter.ImportOrder] for some predefined values.
</description>
</method>
<method name="get_importer_name" qualifiers="virtual">

View file

@ -1,13 +1,22 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ResourceImporter" inherits="Reference" version="3.4">
<brief_description>
Base class for the implementation of core resource importers.
</brief_description>
<description>
This is the base class for the resource importers implemented in core. To implement your own resource importers using editor plugins, see [EditorImportPlugin].
</description>
<tutorials>
<link title="Import plugins">https://docs.godotengine.org/en/stable/tutorials/plugins/editor/import_plugins.html</link>
</tutorials>
<methods>
</methods>
<constants>
<constant name="IMPORT_ORDER_DEFAULT" value="0" enum="ImportOrder">
The default import order.
</constant>
<constant name="IMPORT_ORDER_SCENE" value="100" enum="ImportOrder">
The import order for scenes, which ensures scenes are imported [i]after[/i] all other core resources such as textures. Custom importers should generally have an import order lower than [code]100[/code] to avoid issues when importing scenes that rely on custom resources.
</constant>
</constants>
</class>

View file

@ -692,8 +692,8 @@ EditorProfiler::EditorProfiler() {
hb->add_child(memnew(Label(TTR("Measure:"))));
display_mode = memnew(OptionButton);
display_mode->add_item(TTR("Frame Time (sec)"));
display_mode->add_item(TTR("Average Time (sec)"));
display_mode->add_item(TTR("Frame Time (ms)"));
display_mode->add_item(TTR("Average Time (ms)"));
display_mode->add_item(TTR("Frame %"));
display_mode->add_item(TTR("Physics Frame %"));
display_mode->connect("item_selected", this, "_combo_changed");
@ -705,6 +705,7 @@ EditorProfiler::EditorProfiler() {
display_time = memnew(OptionButton);
display_time->add_item(TTR("Inclusive"));
display_time->add_item(TTR("Self"));
display_time->set_tooltip(TTR("Inclusive: Includes time from other functions called by this function.\nUse this to spot bottlenecks.\n\nSelf: Only count the time spent in the function itself, not in other functions called by that function.\nUse this to find individual functions to optimize."));
display_time->connect("item_selected", this, "_combo_changed");
hb->add_child(display_time);

View file

@ -140,7 +140,8 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
virtual int get_import_order() const { return 100; } //after everything
// Import scenes *after* everything else (such as textures).
virtual int get_import_order() const { return ResourceImporter::IMPORT_ORDER_SCENE; }
void _find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes);

View file

@ -5818,7 +5818,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
select_button->connect("pressed", this, "_button_tool_select", make_binds(TOOL_SELECT));
select_button->set_pressed(true);
select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), KEY_Q));
select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate") + "\n" + TTR("Alt+Drag: Move") + "\n" + TTR("Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving).") + "\n" + TTR("Alt+RMB: Depth list selection"));
select_button->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("RMB: Add node at position clicked."));
hb->add_child(memnew(VSeparator));

View file

@ -6220,8 +6220,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
button_binds.write[0] = MENU_TOOL_SELECT;
tool_button[TOOL_MODE_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SELECT]->set_shortcut(ED_SHORTCUT("spatial_editor/tool_select", TTR("Select Mode"), KEY_Q));
tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate\nAlt+Drag: Move\nAlt+RMB: Depth list selection"));
tool_button[TOOL_MODE_SELECT]->set_tooltip(keycode_get_string(KEY_MASK_CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked."));
hbc_menu->add_child(memnew(VSeparator));
tool_button[TOOL_MODE_MOVE] = memnew(ToolButton);

View file

@ -25,16 +25,30 @@ namespace Godot.Collections
}
}
/// <summary>
/// Wrapper around Godot's Array class, an array of Variant
/// typed elements allocated in the engine in C++. Useful when
/// interfacing with the engine. Otherwise prefer .NET collections
/// such as <see cref="System.Array"/> or <see cref="List{T}"/>.
/// </summary>
public class Array : IList, IDisposable
{
ArraySafeHandle safeHandle;
bool disposed = false;
/// <summary>
/// Constructs a new empty <see cref="Array"/>.
/// </summary>
public Array()
{
safeHandle = new ArraySafeHandle(godot_icall_Array_Ctor());
}
/// <summary>
/// Constructs a new <see cref="Array"/> from the given collection's elements.
/// </summary>
/// <param name="collection">The collection of elements to construct from.</param>
/// <returns>A new Godot Array.</returns>
public Array(IEnumerable collection) : this()
{
if (collection == null)
@ -44,6 +58,11 @@ namespace Godot.Collections
Add(element);
}
/// <summary>
/// Constructs a new <see cref="Array"/> from the given objects.
/// </summary>
/// <param name="array">The objects to put in the new array.</param>
/// <returns>A new Godot Array.</returns>
public Array(params object[] array) : this()
{
if (array == null)
@ -71,21 +90,40 @@ namespace Godot.Collections
return safeHandle.DangerousGetHandle();
}
/// <summary>
/// Duplicates this <see cref="Array"/>.
/// </summary>
/// <param name="deep">If true, performs a deep copy.</param>
/// <returns>A new Godot Array.</returns>
public Array Duplicate(bool deep = false)
{
return new Array(godot_icall_Array_Duplicate(GetPtr(), deep));
}
/// <summary>
/// Resizes this <see cref="Array"/> to the given size.
/// </summary>
/// <param name="newSize">The new size of the array.</param>
/// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns>
public Error Resize(int newSize)
{
return godot_icall_Array_Resize(GetPtr(), newSize);
}
/// <summary>
/// Shuffles the contents of this <see cref="Array"/> into a random order.
/// </summary>
public void Shuffle()
{
godot_icall_Array_Shuffle(GetPtr());
}
/// <summary>
/// Concatenates these two <see cref="Array"/>s.
/// </summary>
/// <param name="left">The first array.</param>
/// <param name="right">The second array.</param>
/// <returns>A new Godot Array with the contents of both arrays.</returns>
public static Array operator +(Array left, Array right)
{
return new Array(godot_icall_Array_Concatenate(left.GetPtr(), right.GetPtr()));
@ -93,6 +131,9 @@ namespace Godot.Collections
// IDisposable
/// <summary>
/// Disposes of this <see cref="Array"/>.
/// </summary>
public void Dispose()
{
if (disposed)
@ -109,38 +150,90 @@ namespace Godot.Collections
// IList
public bool IsReadOnly => false;
bool IList.IsReadOnly => false;
public bool IsFixedSize => false;
bool IList.IsFixedSize => false;
/// <summary>
/// Returns the object at the given index.
/// </summary>
/// <value>The object at the given index.</value>
public object this[int index]
{
get => godot_icall_Array_At(GetPtr(), index);
set => godot_icall_Array_SetAt(GetPtr(), index, value);
}
/// <summary>
/// Adds an object to the end of this <see cref="Array"/>.
/// This is the same as `append` or `push_back` in GDScript.
/// </summary>
/// <param name="value">The object to add.</param>
/// <returns>The new size after adding the object.</returns>
public int Add(object value) => godot_icall_Array_Add(GetPtr(), value);
/// <summary>
/// Checks if this <see cref="Array"/> contains the given object.
/// </summary>
/// <param name="value">The item to look for.</param>
/// <returns>Whether or not this array contains the given object.</returns>
public bool Contains(object value) => godot_icall_Array_Contains(GetPtr(), value);
/// <summary>
/// Erases all items from this <see cref="Array"/>.
/// </summary>
public void Clear() => godot_icall_Array_Clear(GetPtr());
/// <summary>
/// Searches this <see cref="Array"/> for an object
/// and returns its index or -1 if not found.
/// </summary>
/// <param name="value">The object to search for.</param>
/// <returns>The index of the object, or -1 if not found.</returns>
public int IndexOf(object value) => godot_icall_Array_IndexOf(GetPtr(), value);
/// <summary>
/// Inserts a new object at a given position in the array.
/// The position must be a valid position of an existing item,
/// or the position at the end of the array.
/// Existing items will be moved to the right.
/// </summary>
/// <param name="index">The index to insert at.</param>
/// <param name="value">The object to insert.</param>
public void Insert(int index, object value) => godot_icall_Array_Insert(GetPtr(), index, value);
/// <summary>
/// Removes the first occurrence of the specified value
/// from this <see cref="Array"/>.
/// </summary>
/// <param name="value">The value to remove.</param>
public void Remove(object value) => godot_icall_Array_Remove(GetPtr(), value);
/// <summary>
/// Removes an element from this <see cref="Array"/> by index.
/// </summary>
/// <param name="index">The index of the element to remove.</param>
public void RemoveAt(int index) => godot_icall_Array_RemoveAt(GetPtr(), index);
// ICollection
/// <summary>
/// Returns the number of elements in this <see cref="Array"/>.
/// This is also known as the size or length of the array.
/// </summary>
/// <returns>The number of elements.</returns>
public int Count => godot_icall_Array_Count(GetPtr());
public object SyncRoot => this;
object ICollection.SyncRoot => this;
public bool IsSynchronized => false;
bool ICollection.IsSynchronized => false;
/// <summary>
/// Copies the elements of this <see cref="Array"/> to the given
/// untyped C# array, starting at the given index.
/// </summary>
/// <param name="array">The array to copy to.</param>
/// <param name="index">The index to start at.</param>
public void CopyTo(System.Array array, int index)
{
if (array == null)
@ -155,6 +248,10 @@ namespace Godot.Collections
// IEnumerable
/// <summary>
/// Gets an enumerator for this <see cref="Array"/>.
/// </summary>
/// <returns>An enumerator.</returns>
public IEnumerator GetEnumerator()
{
int count = Count;
@ -165,6 +262,10 @@ namespace Godot.Collections
}
}
/// <summary>
/// Converts this <see cref="Array"/> to a string.
/// </summary>
/// <returns>A string representation of this array.</returns>
public override string ToString()
{
return godot_icall_Array_ToString(GetPtr());
@ -234,6 +335,13 @@ namespace Godot.Collections
internal extern static string godot_icall_Array_ToString(IntPtr ptr);
}
/// <summary>
/// Typed wrapper around Godot's Array class, an array of Variant
/// typed elements allocated in the engine in C++. Useful when
/// interfacing with the engine. Otherwise prefer .NET collections
/// such as arrays or <see cref="List{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
public class Array<T> : IList<T>, ICollection<T>, IEnumerable<T>
{
Array objectArray;
@ -246,11 +354,19 @@ namespace Godot.Collections
Array.godot_icall_Array_Generic_GetElementTypeInfo(typeof(T), out elemTypeEncoding, out elemTypeClass);
}
/// <summary>
/// Constructs a new empty <see cref="Array{T}"/>.
/// </summary>
public Array()
{
objectArray = new Array();
}
/// <summary>
/// Constructs a new <see cref="Array{T}"/> from the given collection's elements.
/// </summary>
/// <param name="collection">The collection of elements to construct from.</param>
/// <returns>A new Godot Array.</returns>
public Array(IEnumerable<T> collection)
{
if (collection == null)
@ -259,6 +375,11 @@ namespace Godot.Collections
objectArray = new Array(collection);
}
/// <summary>
/// Constructs a new <see cref="Array{T}"/> from the given items.
/// </summary>
/// <param name="array">The items to put in the new array.</param>
/// <returns>A new Godot Array.</returns>
public Array(params T[] array) : this()
{
if (array == null)
@ -268,6 +389,10 @@ namespace Godot.Collections
objectArray = new Array(array);
}
/// <summary>
/// Constructs a typed <see cref="Array{T}"/> from an untyped <see cref="Array"/>.
/// </summary>
/// <param name="array">The untyped array to construct from.</param>
public Array(Array array)
{
objectArray = array;
@ -288,26 +413,49 @@ namespace Godot.Collections
return objectArray.GetPtr();
}
/// <summary>
/// Converts this typed <see cref="Array{T}"/> to an untyped <see cref="Array"/>.
/// </summary>
/// <param name="from">The typed array to convert.</param>
public static explicit operator Array(Array<T> from)
{
return from.objectArray;
}
/// <summary>
/// Duplicates this <see cref="Array{T}"/>.
/// </summary>
/// <param name="deep">If true, performs a deep copy.</param>
/// <returns>A new Godot Array.</returns>
public Array<T> Duplicate(bool deep = false)
{
return new Array<T>(objectArray.Duplicate(deep));
}
/// <summary>
/// Resizes this <see cref="Array{T}"/> to the given size.
/// </summary>
/// <param name="newSize">The new size of the array.</param>
/// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns>
public Error Resize(int newSize)
{
return objectArray.Resize(newSize);
}
/// <summary>
/// Shuffles the contents of this <see cref="Array{T}"/> into a random order.
/// </summary>
public void Shuffle()
{
objectArray.Shuffle();
}
/// <summary>
/// Concatenates these two <see cref="Array{T}"/>s.
/// </summary>
/// <param name="left">The first array.</param>
/// <param name="right">The second array.</param>
/// <returns>A new Godot Array with the contents of both arrays.</returns>
public static Array<T> operator +(Array<T> left, Array<T> right)
{
return new Array<T>(left.objectArray + right.objectArray);
@ -315,22 +463,44 @@ namespace Godot.Collections
// IList<T>
/// <summary>
/// Returns the value at the given index.
/// </summary>
/// <value>The value at the given index.</value>
public T this[int index]
{
get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); }
set { objectArray[index] = value; }
}
/// <summary>
/// Searches this <see cref="Array{T}"/> for an item
/// and returns its index or -1 if not found.
/// </summary>
/// <param name="item">The item to search for.</param>
/// <returns>The index of the item, or -1 if not found.</returns>
public int IndexOf(T item)
{
return objectArray.IndexOf(item);
}
/// <summary>
/// Inserts a new item at a given position in the <see cref="Array{T}"/>.
/// The position must be a valid position of an existing item,
/// or the position at the end of the array.
/// Existing items will be moved to the right.
/// </summary>
/// <param name="index">The index to insert at.</param>
/// <param name="item">The item to insert.</param>
public void Insert(int index, T item)
{
objectArray.Insert(index, item);
}
/// <summary>
/// Removes an element from this <see cref="Array{T}"/> by index.
/// </summary>
/// <param name="index">The index of the element to remove.</param>
public void RemoveAt(int index)
{
objectArray.RemoveAt(index);
@ -338,31 +508,53 @@ namespace Godot.Collections
// ICollection<T>
/// <summary>
/// Returns the number of elements in this <see cref="Array{T}"/>.
/// This is also known as the size or length of the array.
/// </summary>
/// <returns>The number of elements.</returns>
public int Count
{
get { return objectArray.Count; }
}
public bool IsReadOnly
{
get { return objectArray.IsReadOnly; }
}
bool ICollection<T>.IsReadOnly => false;
/// <summary>
/// Adds an item to the end of this <see cref="Array{T}"/>.
/// This is the same as `append` or `push_back` in GDScript.
/// </summary>
/// <param name="item">The item to add.</param>
/// <returns>The new size after adding the item.</returns>
public void Add(T item)
{
objectArray.Add(item);
}
/// <summary>
/// Erases all items from this <see cref="Array{T}"/>.
/// </summary>
public void Clear()
{
objectArray.Clear();
}
/// <summary>
/// Checks if this <see cref="Array{T}"/> contains the given item.
/// </summary>
/// <param name="item">The item to look for.</param>
/// <returns>Whether or not this array contains the given item.</returns>
public bool Contains(T item)
{
return objectArray.Contains(item);
}
/// <summary>
/// Copies the elements of this <see cref="Array{T}"/> to the given
/// C# array, starting at the given index.
/// </summary>
/// <param name="array">The C# array to copy to.</param>
/// <param name="arrayIndex">The index to start at.</param>
public void CopyTo(T[] array, int arrayIndex)
{
if (array == null)
@ -386,6 +578,12 @@ namespace Godot.Collections
}
}
/// <summary>
/// Removes the first occurrence of the specified value
/// from this <see cref="Array{T}"/>.
/// </summary>
/// <param name="item">The value to remove.</param>
/// <returns>A bool indicating success or failure.</returns>
public bool Remove(T item)
{
return Array.godot_icall_Array_Remove(GetPtr(), item);
@ -393,6 +591,10 @@ namespace Godot.Collections
// IEnumerable<T>
/// <summary>
/// Gets an enumerator for this <see cref="Array{T}"/>.
/// </summary>
/// <returns>An enumerator.</returns>
public IEnumerator<T> GetEnumerator()
{
int count = objectArray.Count;
@ -408,6 +610,10 @@ namespace Godot.Collections
return GetEnumerator();
}
/// <summary>
/// Converts this <see cref="Array{T}"/> to a string.
/// </summary>
/// <returns>A string representation of this array.</returns>
public override string ToString() => objectArray.ToString();
}
}

View file

@ -61,9 +61,9 @@ namespace Godot
return string.Empty;
}
// <summary>
// If the string is a path to a file, return the path to the file without the extension.
// </summary>
/// <summary>
/// If the string is a path to a file, return the path to the file without the extension.
/// </summary>
public static string BaseName(this string instance)
{
int index = instance.LastIndexOf('.');
@ -74,17 +74,17 @@ namespace Godot
return instance;
}
// <summary>
// Return true if the strings begins with the given string.
// </summary>
/// <summary>
/// Return <see langword="true"/> if the strings begins with the given string.
/// </summary>
public static bool BeginsWith(this string instance, string text)
{
return instance.StartsWith(text);
}
// <summary>
// Return the bigrams (pairs of consecutive letters) of this string.
// </summary>
/// <summary>
/// Return the bigrams (pairs of consecutive letters) of this string.
/// </summary>
public static string[] Bigrams(this string instance)
{
var b = new string[instance.Length - 1];
@ -127,9 +127,9 @@ namespace Godot
return sign * Convert.ToInt32(instance, 2);
}
// <summary>
// Return the amount of substrings in string.
// </summary>
/// <summary>
/// Return the amount of substrings in string.
/// </summary>
public static int Count(this string instance, string what, bool caseSensitive = true, int from = 0, int to = 0)
{
if (what.Length == 0)
@ -187,9 +187,9 @@ namespace Godot
return c;
}
// <summary>
// Return a copy of the string with special characters escaped using the C language standard.
// </summary>
/// <summary>
/// Return a copy of the string with special characters escaped using the C language standard.
/// </summary>
public static string CEscape(this string instance)
{
var sb = new StringBuilder(string.Copy(instance));
@ -209,9 +209,10 @@ namespace Godot
return sb.ToString();
}
// <summary>
// Return a copy of the string with escaped characters replaced by their meanings according to the C language standard.
// </summary>
/// <summary>
/// Return a copy of the string with escaped characters replaced by their meanings
/// according to the C language standard.
/// </summary>
public static string CUnescape(this string instance)
{
var sb = new StringBuilder(string.Copy(instance));
@ -231,9 +232,12 @@ namespace Godot
return sb.ToString();
}
// <summary>
// Change the case of some letters. Replace underscores with spaces, convert all letters to lowercase then capitalize first and every letter following the space character. For [code]capitalize camelCase mixed_with_underscores[/code] it will return [code]Capitalize Camelcase Mixed With Underscores[/code].
// </summary>
/// <summary>
/// Change the case of some letters. Replace underscores with spaces, convert all letters
/// to lowercase then capitalize first and every letter following the space character.
/// For <c>capitalize camelCase mixed_with_underscores</c> it will return
/// <c>Capitalize Camelcase Mixed With Underscores</c>.
/// </summary>
public static string Capitalize(this string instance)
{
string aux = instance.Replace("_", " ").ToLower();
@ -254,17 +258,17 @@ namespace Godot
return cap;
}
// <summary>
// Perform a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
// </summary>
/// <summary>
/// Perform a case-sensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
/// </summary>
public static int CasecmpTo(this string instance, string to)
{
return instance.CompareTo(to, caseSensitive: true);
}
// <summary>
// Perform a comparison to another string, return -1 if less, 0 if equal and +1 if greater.
// </summary>
/// <summary>
/// Perform a comparison to another string, return -1 if less, 0 if equal and +1 if greater.
/// </summary>
public static int CompareTo(this string instance, string to, bool caseSensitive = true)
{
if (instance.Empty())
@ -316,33 +320,33 @@ namespace Godot
}
}
// <summary>
// Return true if the string is empty.
// </summary>
/// <summary>
/// Return <see langword="true"/> if the string is empty.
/// </summary>
public static bool Empty(this string instance)
{
return string.IsNullOrEmpty(instance);
}
// <summary>
// Return true if the strings ends with the given string.
// </summary>
/// <summary>
/// Return <see langword="true"/> if the strings ends with the given string.
/// </summary>
public static bool EndsWith(this string instance, string text)
{
return instance.EndsWith(text);
}
// <summary>
// Erase [code]chars[/code] characters from the string starting from [code]pos[/code].
// </summary>
/// <summary>
/// Erase <paramref name="chars"/> characters from the string starting from <paramref name="pos"/>.
/// </summary>
public static void Erase(this StringBuilder instance, int pos, int chars)
{
instance.Remove(pos, chars);
}
// <summary>
// If the string is a path to a file, return the extension.
// </summary>
/// <summary>
/// If the string is a path to a file, return the extension.
/// </summary>
public static string Extension(this string instance)
{
int pos = instance.FindLast(".");
@ -353,14 +357,18 @@ namespace Godot
return instance.Substring(pos + 1);
}
/// <summary>Find the first occurrence of a substring. Optionally, the search starting position can be passed.</summary>
/// <summary>
/// Find the first occurrence of a substring. Optionally, the search starting position can be passed.
/// </summary>
/// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int Find(this string instance, string what, int from = 0, bool caseSensitive = true)
{
return instance.IndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
}
/// <summary>Find the first occurrence of a char. Optionally, the search starting position can be passed.</summary>
/// <summary>
/// Find the first occurrence of a char. Optionally, the search starting position can be passed.
/// </summary>
/// <returns>The first instance of the char, or -1 if not found.</returns>
public static int Find(this string instance, char what, int from = 0, bool caseSensitive = true)
{
@ -383,16 +391,19 @@ namespace Godot
return instance.LastIndexOf(what, from, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
}
/// <summary>Find the first occurrence of a substring but search as case-insensitive. Optionally, the search starting position can be passed.</summary>
/// <summary>
/// Find the first occurrence of a substring but search as case-insensitive.
/// Optionally, the search starting position can be passed.
/// </summary>
/// <returns>The starting position of the substring, or -1 if not found.</returns>
public static int FindN(this string instance, string what, int from = 0)
{
return instance.IndexOf(what, from, StringComparison.OrdinalIgnoreCase);
}
// <summary>
// If the string is a path to a file, return the base directory.
// </summary>
/// <summary>
/// If the string is a path to a file, return the base directory.
/// </summary>
public static string GetBaseDir(this string instance)
{
int basepos = instance.Find("://");
@ -427,9 +438,9 @@ namespace Godot
return @base + rs.Substr(0, sep);
}
// <summary>
// If the string is a path to a file, return the file and ignore the base directory.
// </summary>
/// <summary>
/// If the string is a path to a file, return the file and ignore the base directory.
/// </summary>
public static string GetFile(this string instance)
{
int sep = Mathf.Max(instance.FindLast("/"), instance.FindLast("\\"));
@ -469,9 +480,9 @@ namespace Godot
return Encoding.UTF8.GetString(bytes);
}
// <summary>
// Hash the string and return a 32 bits unsigned integer.
// </summary>
/// <summary>
/// Hash the string and return a 32 bits unsigned integer.
/// </summary>
public static uint Hash(this string instance)
{
uint hash = 5381;
@ -561,17 +572,17 @@ namespace Godot
return sign * int.Parse(instance, NumberStyles.HexNumber);
}
// <summary>
// Insert a substring at a given position.
// </summary>
/// <summary>
/// Insert a substring at a given position.
/// </summary>
public static string Insert(this string instance, int pos, string what)
{
return instance.Insert(pos, what);
}
// <summary>
// If the string is a path to a file or directory, return true if the path is absolute.
// </summary>
/// <summary>
/// If the string is a path to a file or directory, return <see langword="true"/> if the path is absolute.
/// </summary>
public static bool IsAbsPath(this string instance)
{
if (string.IsNullOrEmpty(instance))
@ -582,17 +593,17 @@ namespace Godot
return instance[0] == '/' || instance[0] == '\\';
}
// <summary>
// If the string is a path to a file or directory, return true if the path is relative.
// </summary>
/// <summary>
/// If the string is a path to a file or directory, return <see langword="true"/> if the path is relative.
/// </summary>
public static bool IsRelPath(this string instance)
{
return !IsAbsPath(instance);
}
// <summary>
// Check whether this string is a subsequence of the given string.
// </summary>
/// <summary>
/// Check whether this string is a subsequence of the given string.
/// </summary>
public static bool IsSubsequenceOf(this string instance, string text, bool caseSensitive = true)
{
int len = instance.Length;
@ -633,34 +644,36 @@ namespace Godot
return false;
}
// <summary>
// Check whether this string is a subsequence of the given string, ignoring case differences.
// </summary>
/// <summary>
/// Check whether this string is a subsequence of the given string, ignoring case differences.
/// </summary>
public static bool IsSubsequenceOfI(this string instance, string text)
{
return instance.IsSubsequenceOf(text, caseSensitive: false);
}
// <summary>
// Check whether the string contains a valid float.
// </summary>
/// <summary>
/// Check whether the string contains a valid <see langword="float"/>.
/// </summary>
public static bool IsValidFloat(this string instance)
{
float f;
return float.TryParse(instance, out f);
}
// <summary>
// Check whether the string contains a valid color in HTML notation.
// </summary>
/// <summary>
/// Check whether the string contains a valid color in HTML notation.
/// </summary>
public static bool IsValidHtmlColor(this string instance)
{
return Color.HtmlIsValid(instance);
}
// <summary>
// Check whether the string is a valid identifier. As is common in programming languages, a valid identifier may contain only letters, digits and underscores (_) and the first character may not be a digit.
// </summary>
/// <summary>
/// Check whether the string is a valid identifier. As is common in
/// programming languages, a valid identifier may contain only letters,
/// digits and underscores (_) and the first character may not be a digit.
/// </summary>
public static bool IsValidIdentifier(this string instance)
{
int len = instance.Length;
@ -688,18 +701,18 @@ namespace Godot
return true;
}
// <summary>
// Check whether the string contains a valid integer.
// </summary>
/// <summary>
/// Check whether the string contains a valid integer.
/// </summary>
public static bool IsValidInteger(this string instance)
{
int f;
return int.TryParse(instance, out f);
}
// <summary>
// Check whether the string contains a valid IP address.
// </summary>
/// <summary>
/// Check whether the string contains a valid IP address.
/// </summary>
public static bool IsValidIPAddress(this string instance)
{
// TODO: Support IPv6 addresses
@ -722,9 +735,9 @@ namespace Godot
return true;
}
// <summary>
// Return a copy of the string with special characters escaped using the JSON standard.
// </summary>
/// <summary>
/// Return a copy of the string with special characters escaped using the JSON standard.
/// </summary>
public static string JSONEscape(this string instance)
{
var sb = new StringBuilder(string.Copy(instance));
@ -741,9 +754,9 @@ namespace Godot
return sb.ToString();
}
// <summary>
// Return an amount of characters from the left of the string.
// </summary>
/// <summary>
/// Return an amount of characters from the left of the string.
/// </summary>
public static string Left(this string instance, int pos)
{
if (pos <= 0)
@ -791,7 +804,8 @@ namespace Godot
}
/// <summary>
/// Do a simple expression match, where '*' matches zero or more arbitrary characters and '?' matches any single character except '.'.
/// Do a simple expression match, where '*' matches zero or more
/// arbitrary characters and '?' matches any single character except '.'.
/// </summary>
private static bool ExprMatch(this string instance, string expr, bool caseSensitive)
{
@ -815,7 +829,8 @@ namespace Godot
}
/// <summary>
/// Do a simple case sensitive expression match, using ? and * wildcards (see [method expr_match]).
/// Do a simple case sensitive expression match, using ? and * wildcards
/// (see <see cref="ExprMatch(string, string, bool)"/>).
/// </summary>
public static bool Match(this string instance, string expr, bool caseSensitive = true)
{
@ -826,7 +841,8 @@ namespace Godot
}
/// <summary>
/// Do a simple case insensitive expression match, using ? and * wildcards (see [method expr_match]).
/// Do a simple case insensitive expression match, using ? and * wildcards
/// (see <see cref="ExprMatch(string, string, bool)"/>).
/// </summary>
public static bool MatchN(this string instance, string expr)
{
@ -836,9 +852,9 @@ namespace Godot
return instance.ExprMatch(expr, caseSensitive: false);
}
// <summary>
// Return the MD5 hash of the string as an array of bytes.
// </summary>
/// <summary>
/// Return the MD5 hash of the string as an array of bytes.
/// </summary>
public static byte[] MD5Buffer(this string instance)
{
return godot_icall_String_md5_buffer(instance);
@ -847,9 +863,9 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static byte[] godot_icall_String_md5_buffer(string str);
// <summary>
// Return the MD5 hash of the string as a string.
// </summary>
/// <summary>
/// Return the MD5 hash of the string as a string.
/// </summary>
public static string MD5Text(this string instance)
{
return godot_icall_String_md5_text(instance);
@ -858,25 +874,25 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static string godot_icall_String_md5_text(string str);
// <summary>
// Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
// </summary>
/// <summary>
/// Perform a case-insensitive comparison to another string, return -1 if less, 0 if equal and +1 if greater.
/// </summary>
public static int NocasecmpTo(this string instance, string to)
{
return instance.CompareTo(to, caseSensitive: false);
}
// <summary>
// Return the character code at position [code]at[/code].
// </summary>
/// <summary>
/// Return the character code at position <paramref name="at"/>.
/// </summary>
public static int OrdAt(this string instance, int at)
{
return instance[at];
}
// <summary>
// Format a number to have an exact number of [code]digits[/code] after the decimal point.
// </summary>
/// <summary>
/// Format a number to have an exact number of <paramref name="digits"/> after the decimal point.
/// </summary>
public static string PadDecimals(this string instance, int digits)
{
int c = instance.Find(".");
@ -910,9 +926,9 @@ namespace Godot
return instance;
}
// <summary>
// Format a number to have an exact number of [code]digits[/code] before the decimal point.
// </summary>
/// <summary>
/// Format a number to have an exact number of <paramref name="digits"/> before the decimal point.
/// </summary>
public static string PadZeros(this string instance, int digits)
{
string s = instance;
@ -943,25 +959,26 @@ namespace Godot
return s;
}
// <summary>
// Decode a percent-encoded string. See [method percent_encode].
// </summary>
/// <summary>
/// Decode a percent-encoded string. See <see cref="PercentEncode"/>.
/// </summary>
public static string PercentDecode(this string instance)
{
return Uri.UnescapeDataString(instance);
}
// <summary>
// Percent-encode a string. This is meant to encode parameters in a URL when sending a HTTP GET request and bodies of form-urlencoded POST request.
// </summary>
/// <summary>
/// Percent-encode a string. This is meant to encode parameters in a URL when sending a HTTP GET request and bodies of form-urlencoded POST request.
/// </summary>
public static string PercentEncode(this string instance)
{
return Uri.EscapeDataString(instance);
}
// <summary>
// If the string is a path, this concatenates [code]file[/code] at the end of the string as a subpath. E.g. [code]"this/is".plus_file("path") == "this/is/path"[/code].
// </summary>
/// <summary>
/// If the string is a path, this concatenates <paramref name="file"/> at the end of the string as a subpath.
/// E.g. <c>"this/is".PlusFile("path") == "this/is/path"</c>.
/// </summary>
public static string PlusFile(this string instance, string file)
{
if (instance.Length > 0 && instance[instance.Length - 1] == '/')
@ -969,25 +986,25 @@ namespace Godot
return instance + "/" + file;
}
// <summary>
// Replace occurrences of a substring for different ones inside the string.
// </summary>
/// <summary>
/// Replace occurrences of a substring for different ones inside the string.
/// </summary>
public static string Replace(this string instance, string what, string forwhat)
{
return instance.Replace(what, forwhat);
}
// <summary>
// Replace occurrences of a substring for different ones inside the string, but search case-insensitive.
// </summary>
/// <summary>
/// Replace occurrences of a substring for different ones inside the string, but search case-insensitive.
/// </summary>
public static string ReplaceN(this string instance, string what, string forwhat)
{
return Regex.Replace(instance, what, forwhat, RegexOptions.IgnoreCase);
}
// <summary>
// Perform a search for a substring, but start from the end of the string instead of the beginning.
// </summary>
/// <summary>
/// Perform a search for a substring, but start from the end of the string instead of the beginning.
/// </summary>
public static int RFind(this string instance, string what, int from = -1)
{
return godot_icall_String_rfind(instance, what, from);
@ -996,9 +1013,10 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static int godot_icall_String_rfind(string str, string what, int from);
// <summary>
// Perform a search for a substring, but start from the end of the string instead of the beginning. Also search case-insensitive.
// </summary>
/// <summary>
/// Perform a search for a substring, but start from the end of the string instead of the beginning.
/// Also search case-insensitive.
/// </summary>
public static int RFindN(this string instance, string what, int from = -1)
{
return godot_icall_String_rfindn(instance, what, from);
@ -1007,9 +1025,9 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static int godot_icall_String_rfindn(string str, string what, int from);
// <summary>
// Return the right side of the string from a given position.
// </summary>
/// <summary>
/// Return the right side of the string from a given position.
/// </summary>
public static string Right(this string instance, int pos)
{
if (pos >= instance.Length)
@ -1056,9 +1074,9 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static byte[] godot_icall_String_sha256_buffer(string str);
// <summary>
// Return the SHA-256 hash of the string as a string.
// </summary>
/// <summary>
/// Return the SHA-256 hash of the string as a string.
/// </summary>
public static string SHA256Text(this string instance)
{
return godot_icall_String_sha256_text(instance);
@ -1067,9 +1085,10 @@ namespace Godot
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static string godot_icall_String_sha256_text(string str);
// <summary>
// Return the similarity index of the text compared to this string. 1 means totally similar and 0 means totally dissimilar.
// </summary>
/// <summary>
/// Return the similarity index of the text compared to this string.
/// 1 means totally similar and 0 means totally dissimilar.
/// </summary>
public static float Similarity(this string instance, string text)
{
if (instance == text)
@ -1107,17 +1126,19 @@ namespace Godot
return 2.0f * inter / sum;
}
// <summary>
// Split the string by a divisor string, return an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
// </summary>
/// <summary>
/// Split the string by a divisor string, return an array of the substrings.
/// Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
/// </summary>
public static string[] Split(this string instance, string divisor, bool allowEmpty = true)
{
return instance.Split(new[] { divisor }, StringSplitOptions.RemoveEmptyEntries);
}
// <summary>
// Split the string in floats by using a divisor string, return an array of the substrings. Example "1,2.5,3" will return [1,2.5,3] if split by ",".
// </summary>
/// <summary>
/// Split the string in floats by using a divisor string, return an array of the substrings.
/// Example "1,2.5,3" will return [1,2.5,3] if split by ",".
/// </summary>
public static float[] SplitFloats(this string instance, string divisor, bool allowEmpty = true)
{
var ret = new List<float>();
@ -1149,9 +1170,10 @@ namespace Godot
(char)30, (char)31, (char)32
};
// <summary>
// Return a copy of the string stripped of any non-printable character at the beginning and the end. The optional arguments are used to toggle stripping on the left and right edges respectively.
// </summary>
/// <summary>
/// Return a copy of the string stripped of any non-printable character at the beginning and the end.
/// The optional arguments are used to toggle stripping on the left and right edges respectively.
/// </summary>
public static string StripEdges(this string instance, bool left = true, bool right = true)
{
if (left)
@ -1164,74 +1186,79 @@ namespace Godot
return instance.TrimEnd(_nonPrintable);
}
// <summary>
// Return part of the string from the position [code]from[/code], with length [code]len[/code].
// </summary>
/// <summary>
/// Return part of the string from the position <paramref name="from"/>, with length <paramref name="len"/>.
/// </summary>
public static string Substr(this string instance, int from, int len)
{
int max = instance.Length - from;
return instance.Substring(from, len > max ? max : len);
}
// <summary>
// Convert the String (which is a character array) to PoolByteArray (which is an array of bytes). The conversion is speeded up in comparison to to_utf8() with the assumption that all the characters the String contains are only ASCII characters.
// </summary>
/// <summary>
/// Convert the String (which is a character array) to PoolByteArray (which is an array of bytes).
/// The conversion is speeded up in comparison to <see cref="ToUTF8(string)"/> with the assumption
/// that all the characters the String contains are only ASCII characters.
/// </summary>
public static byte[] ToAscii(this string instance)
{
return Encoding.ASCII.GetBytes(instance);
}
// <summary>
// Convert a string, containing a decimal number, into a [code]float[/code].
// </summary>
/// <summary>
/// Convert a string, containing a decimal number, into a <see langword="float" />.
/// </summary>
public static float ToFloat(this string instance)
{
return float.Parse(instance);
}
// <summary>
// Convert a string, containing an integer number, into an [code]int[/code].
// </summary>
/// <summary>
/// Convert a string, containing an integer number, into an <see langword="int" />.
/// </summary>
public static int ToInt(this string instance)
{
return int.Parse(instance);
}
// <summary>
// Return the string converted to lowercase.
// </summary>
/// <summary>
/// Return the string converted to lowercase.
/// </summary>
public static string ToLower(this string instance)
{
return instance.ToLower();
}
// <summary>
// Return the string converted to uppercase.
// </summary>
/// <summary>
/// Return the string converted to uppercase.
/// </summary>
public static string ToUpper(this string instance)
{
return instance.ToUpper();
}
// <summary>
// Convert the String (which is an array of characters) to PoolByteArray (which is an array of bytes). The conversion is a bit slower than to_ascii(), but supports all UTF-8 characters. Therefore, you should prefer this function over to_ascii().
// </summary>
/// <summary>
/// Convert the String (which is an array of characters) to PoolByteArray (which is an array of bytes).
/// The conversion is a bit slower than <see cref="ToAscii(string)"/>, but supports all UTF-8 characters.
/// Therefore, you should prefer this function over <see cref="ToAscii(string)"/>.
/// </summary>
public static byte[] ToUTF8(this string instance)
{
return Encoding.UTF8.GetBytes(instance);
}
// <summary>
// Return a copy of the string with special characters escaped using the XML standard.
// </summary>
/// <summary>
/// Return a copy of the string with special characters escaped using the XML standard.
/// </summary>
public static string XMLEscape(this string instance)
{
return SecurityElement.Escape(instance);
}
// <summary>
// Return a copy of the string with escaped characters replaced by their meanings according to the XML standard.
// </summary>
/// <summary>
/// Return a copy of the string with escaped characters replaced by their meanings
/// according to the XML standard.
/// </summary>
public static string XMLUnescape(this string instance)
{
return SecurityElement.FromString(instance).Text;

View file

@ -2193,7 +2193,7 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
int new_id = script->get_available_id();
if (files.size()) {
undo_redo->create_action(TTR("Add Preload Node"));
undo_redo->create_action(TTR("Add Node(s)"));
for (int i = 0; i < files.size(); i++) {
Ref<Resource> res = ResourceLoader::load(files[i]);

View file

@ -178,6 +178,7 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/calendars"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/photos_library"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/apple_events"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/debugging"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/enabled"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/entitlements/app_sandbox/network_server"), false));
@ -845,6 +846,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ent_f->store_line("<key>com.apple.security.automation.apple-events</key>");
ent_f->store_line("<true/>");
}
if ((bool)p_preset->get("codesign/entitlements/debugging")) {
ent_f->store_line("<key>com.apple.security.get-task-allow</key>");
ent_f->store_line("<true/>");
}
if ((bool)p_preset->get("codesign/entitlements/app_sandbox/enabled")) {
ent_f->store_line("<key>com.apple.security.app-sandbox</key>");

View file

@ -168,7 +168,6 @@ def setup_mingw(env):
"""Set up env for use with mingw"""
# Nothing to do here
print("Using MinGW")
pass
def configure_msvc(env, manual_msvc_config):