diff options
-rw-r--r-- | doc/classes/AnimatedSprite.xml | 10 | ||||
-rw-r--r-- | doc/classes/AnimatedSprite3D.xml | 8 | ||||
-rw-r--r-- | doc/classes/BackBufferCopy.xml | 10 | ||||
-rw-r--r-- | doc/classes/Camera.xml | 31 | ||||
-rw-r--r-- | doc/classes/Camera2D.xml | 12 | ||||
-rw-r--r-- | doc/classes/KinematicBody.xml | 18 | ||||
-rw-r--r-- | doc/classes/KinematicBody2D.xml | 22 | ||||
-rw-r--r-- | doc/classes/Sprite.xml | 18 | ||||
-rw-r--r-- | doc/classes/Sprite3D.xml | 9 | ||||
-rw-r--r-- | doc/classes/SpriteBase3D.xml | 17 | ||||
-rw-r--r-- | doc/classes/TextureButton.xml | 21 | ||||
-rw-r--r-- | doc/classes/TextureProgress.xml | 34 | ||||
-rw-r--r-- | modules/mono/editor/godotsharp_builds.cpp | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 34 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.h | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.cpp | 97 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_assembly.h | 8 |
17 files changed, 253 insertions, 100 deletions
diff --git a/doc/classes/AnimatedSprite.xml b/doc/classes/AnimatedSprite.xml index 809890bea1..dce7bf283a 100644 --- a/doc/classes/AnimatedSprite.xml +++ b/doc/classes/AnimatedSprite.xml @@ -4,7 +4,7 @@ Sprite node that can use multiple textures for animation. </brief_description> <description> - Sprite node that can use multiple textures for animation. Animations are created using a [SpriteFrames] resource, which can be configured in the editor via the SpriteFrames panel. + Animations are created using a [SpriteFrames] resource, which can be configured in the editor via the SpriteFrames panel. </description> <tutorials> </tutorials> @@ -149,7 +149,7 @@ </methods> <members> <member name="animation" type="String" setter="set_animation" getter="get_animation"> - The current animation from the [code]frames[/code] resource. If this value is changed, the [code]frame[/code] counter is reset. + The current animation from the [code]frames[/code] resource. If this value changes, the [code]frame[/code] counter is reset. </member> <member name="centered" type="bool" setter="set_centered" getter="is_centered"> If [code]true[/code] texture will be centered. Default value: [code]true[/code]. @@ -161,7 +161,7 @@ If [code]true[/code] texture is flipped vertically. Default value: [code]false[/code]. </member> <member name="frame" type="int" setter="set_frame" getter="get_frame"> - The current frame index. + The displayed animation frame's index. </member> <member name="frames" type="SpriteFrames" setter="set_sprite_frames" getter="get_sprite_frames"> The [SpriteFrames] resource containing the animation(s). @@ -170,7 +170,7 @@ The texture's drawing offset. </member> <member name="playing" type="bool" setter="_set_playing" getter="_is_playing"> - If [code]true[/code] the [code]animation[/code] is currently playing. + If [code]true[/code] the [member animation] is currently playing. </member> </members> <signals> @@ -181,7 +181,7 @@ </signal> <signal name="frame_changed"> <description> - Emitted when [code]frame[/code] changes. + Emitted when [member frame] changed. </description> </signal> </signals> diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml index 4e28f7de8d..b0bb7bb6ab 100644 --- a/doc/classes/AnimatedSprite3D.xml +++ b/doc/classes/AnimatedSprite3D.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AnimatedSprite3D" inherits="SpriteBase3D" category="Core" version="3.0.alpha.custom_build"> <brief_description> + 2D sprite node in 3D world, that can use multiple 2D textures for animation. </brief_description> <description> + Animations are created using a [SpriteFrames] resource, which can be configured in the editor via the SpriteFrames panel. </description> <tutorials> </tutorials> @@ -83,18 +85,22 @@ </methods> <members> <member name="animation" type="String" setter="set_animation" getter="get_animation"> + The current animation from the [code]frames[/code] resource. If this value changes, the [code]frame[/code] counter is reset. </member> <member name="frame" type="int" setter="set_frame" getter="get_frame"> + The displayed animation frame's index. </member> <member name="frames" type="SpriteFrames" setter="set_sprite_frames" getter="get_sprite_frames"> + The [SpriteFrames] resource containing the animation(s). </member> <member name="playing" type="bool" setter="_set_playing" getter="_is_playing"> + If [code]true[/code] the [member animation] is currently playing. </member> </members> <signals> <signal name="frame_changed"> <description> - Emitted when frame is changed. + Emitted when [member frame] changed. </description> </signal> </signals> diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml index 091bd3fa73..6c44430949 100644 --- a/doc/classes/BackBufferCopy.xml +++ b/doc/classes/BackBufferCopy.xml @@ -15,7 +15,7 @@ <return type="int" enum="BackBufferCopy.CopyMode"> </return> <description> - Return the copy mode currently applied to the BackBufferCopy (refer to constants section). + Return the copy mode currently applied to the BackBufferCopy. See [code]COPY_MODE_*[/code] constants. </description> </method> <method name="get_rect" qualifiers="const"> @@ -31,7 +31,7 @@ <argument index="0" name="copy_mode" type="int" enum="BackBufferCopy.CopyMode"> </argument> <description> - Set the copy mode of the BackBufferCopy (refer to constants section). + Set the copy mode of the BackBufferCopy. See [code]COPY_MODE_*[/code] constants. </description> </method> <method name="set_rect"> @@ -46,8 +46,10 @@ </methods> <members> <member name="copy_mode" type="int" setter="set_copy_mode" getter="get_copy_mode" enum="BackBufferCopy.CopyMode"> + Buffer mode. See [code]COPY_MODE_*[/code] constants. </member> <member name="rect" type="Rect2" setter="set_rect" getter="get_rect"> + The area covered by the BackBufferCopy. Only used if [code]copy_mode[/code] is [code]COPY_MODE_RECT[/code]. </member> </members> <constants> @@ -55,10 +57,10 @@ Disables the buffering mode. This means the BackBufferCopy node will directly use the portion of screen it covers. </constant> <constant name="COPY_MODE_RECT" value="1"> - Sets the copy mode to a region. + BackBufferCopy buffers a rectangular region. </constant> <constant name="COPY_MODE_VIEWPORT" value="2"> - Sets the copy mode to the entire screen. + BackBufferCopy buffers the entire screen. </constant> </constants> </class> diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml index 2302c39e35..068b91204c 100644 --- a/doc/classes/Camera.xml +++ b/doc/classes/Camera.xml @@ -15,6 +15,7 @@ <return type="void"> </return> <description> + If this is the current Camera, remove it from being current. If it is inside the node tree, request to make the next Camera current, if any. </description> </method> <method name="get_camera_transform" qualifiers="const"> @@ -28,6 +29,7 @@ <return type="int"> </return> <description> + Returns the culling mask, describing which 3D render layers are rendered by this Camera. </description> </method> <method name="get_doppler_tracking" qualifiers="const"> @@ -40,30 +42,35 @@ <return type="Environment"> </return> <description> + Returns the [Environment] used by this Camera. </description> </method> <method name="get_fov" qualifiers="const"> <return type="float"> </return> <description> + Returns the [i]FOV[/i] Y angle in degrees (FOV means Field of View). </description> </method> <method name="get_h_offset" qualifiers="const"> <return type="float"> </return> <description> + Returns the horizontal (X) offset of the Camera viewport. </description> </method> <method name="get_keep_aspect_mode" qualifiers="const"> <return type="int" enum="Camera.KeepAspect"> </return> <description> + Returns the current mode for keeping the aspect ratio. See [code]KEEP_*[/code] constants. </description> </method> <method name="get_projection" qualifiers="const"> <return type="int" enum="Camera.Projection"> </return> <description> + Returns the Camera's projection. See PROJECTION_* constants. </description> </method> <method name="get_size" qualifiers="const"> @@ -76,25 +83,28 @@ <return type="float"> </return> <description> + Returns the vertical (Y) offset of the Camera viewport. </description> </method> <method name="get_zfar" qualifiers="const"> <return type="float"> </return> <description> + Returns the far clip plane in world space units. </description> </method> <method name="get_znear" qualifiers="const"> <return type="float"> </return> <description> + Returns the near clip plane in world space units. </description> </method> <method name="is_current" qualifiers="const"> <return type="bool"> </return> <description> - Return whether the Camera is the current one in the [Viewport], or plans to become current (if outside the scene tree). + Returns [code]true[/code] if the Camera is the current one in the [Viewport], or plans to become current (if outside the scene tree). </description> </method> <method name="is_position_behind" qualifiers="const"> @@ -103,6 +113,7 @@ <argument index="0" name="world_point" type="Vector3"> </argument> <description> + Returns [code]true[/code] if the given position is behind the Camera. </description> </method> <method name="make_current"> @@ -126,6 +137,7 @@ <argument index="0" name="screen_point" type="Vector2"> </argument> <description> + Returns how a 2D coordinate in the Viewport rectangle maps to a 3D point in worldspace. </description> </method> <method name="project_ray_normal" qualifiers="const"> @@ -134,7 +146,7 @@ <argument index="0" name="screen_point" type="Vector2"> </argument> <description> - Return a normal vector in worldspace, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin,normal) for object intersection or picking. + Returns a normal vector in worldspace, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. </description> </method> <method name="project_ray_origin" qualifiers="const"> @@ -143,7 +155,7 @@ <argument index="0" name="screen_point" type="Vector2"> </argument> <description> - Return a 3D position in worldspace, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin,normal) for object intersection or picking. + Returns a 3D position in worldspace, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. </description> </method> <method name="set_cull_mask"> @@ -152,6 +164,7 @@ <argument index="0" name="mask" type="int"> </argument> <description> + Sets the cull mask, describing which 3D render layers are rendered by this Camera. </description> </method> <method name="set_doppler_tracking"> @@ -160,6 +173,7 @@ <argument index="0" name="mode" type="int" enum="Camera.DopplerTracking"> </argument> <description> + Changes Doppler effect tracking. See [code]DOPPLER_*[/code] constants. </description> </method> <method name="set_environment"> @@ -168,6 +182,7 @@ <argument index="0" name="env" type="Environment"> </argument> <description> + Sets the [Environment] to use for this Camera. </description> </method> <method name="set_h_offset"> @@ -176,6 +191,7 @@ <argument index="0" name="ofs" type="float"> </argument> <description> + Sets the horizontal (X) offset of the Camera viewport. </description> </method> <method name="set_keep_aspect_mode"> @@ -184,6 +200,7 @@ <argument index="0" name="mode" type="int" enum="Camera.KeepAspect"> </argument> <description> + Sets the mode for keeping the aspect ratio. See [code]KEEP_*[/code] constants. </description> </method> <method name="set_orthogonal"> @@ -218,6 +235,7 @@ <argument index="0" name="ofs" type="float"> </argument> <description> + Sets the vertical (Y) offset of the Camera viewport. </description> </method> <method name="unproject_position" qualifiers="const"> @@ -226,7 +244,7 @@ <argument index="0" name="world_point" type="Vector3"> </argument> <description> - Return how a 3D point in worldspace maps to a 2D coordinate in the [Viewport] rectangle. + Returns how a 3D point in worldspace maps to a 2D coordinate in the [Viewport] rectangle. </description> </method> </methods> @@ -238,14 +256,19 @@ Orthogonal Projection (objects remain the same size on the screen no matter how far away they are). </constant> <constant name="KEEP_WIDTH" value="0"> + Try to keep the aspect ratio when scaling the Camera's viewport to the screen. If not possible, preserve the viewport's width by changing the height. Height is [code]sizey[/code] for orthographic projection, [code]fovy[/code] for perspective projection. </constant> <constant name="KEEP_HEIGHT" value="1"> + Try to keep the aspect ratio when scaling the Camera's viewport to the screen. If not possible, preserve the viewport's height by changing the width. Width is [code]sizex[/code] for orthographic projection, [code]fovx[/code] for perspective projection. </constant> <constant name="DOPPLER_TRACKING_DISABLED" value="0"> + Disable Doppler effect simulation (default). </constant> <constant name="DOPPLER_TRACKING_IDLE_STEP" value="1"> + Simulate Doppler effect by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this Camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]). </constant> <constant name="DOPPLER_TRACKING_FIXED_STEP" value="2"> + Simulate Doppler effect by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this Camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]). </constant> </constants> </class> diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index b6b699612e..228b6ebf91 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -324,18 +324,24 @@ </methods> <members> <member name="anchor_mode" type="int" setter="set_anchor_mode" getter="get_anchor_mode" enum="Camera2D.AnchorMode"> + The Camera2D's anchor point. See [code]ANCHOR_MODE_*[/code] constants. </member> <member name="current" type="bool" setter="_set_current" getter="is_current"> + If [code]true[/code] this camera is the active camera for the current scene. Only one camera can be current, so setting a different camera [code]current[/code] will disable this one. </member> <member name="drag_margin_bottom" type="float" setter="set_drag_margin" getter="get_drag_margin"> + Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen. </member> <member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled"> </member> <member name="drag_margin_left" type="float" setter="set_drag_margin" getter="get_drag_margin"> + Left margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen. </member> <member name="drag_margin_right" type="float" setter="set_drag_margin" getter="get_drag_margin"> + Right margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen. </member> <member name="drag_margin_top" type="float" setter="set_drag_margin" getter="get_drag_margin"> + Top margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen. </member> <member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled"> </member> @@ -346,16 +352,21 @@ <member name="editor_draw_screen" type="bool" setter="set_screen_drawing_enabled" getter="is_screen_drawing_enabled"> </member> <member name="limit_bottom" type="int" setter="set_limit" getter="get_limit"> + Bottom scroll limit in pixels. The camera stops moving when reaching this value. </member> <member name="limit_left" type="int" setter="set_limit" getter="get_limit"> + Left scroll limit in pixels. The camera stops moving when reaching this value. </member> <member name="limit_right" type="int" setter="set_limit" getter="get_limit"> + Right scroll limit in pixels. The camera stops moving when reaching this value. </member> <member name="limit_smoothed" type="bool" setter="set_limit_smoothing_enabled" getter="is_limit_smoothing_enabled"> </member> <member name="limit_top" type="int" setter="set_limit" getter="get_limit"> + Top scroll limit in pixels. The camera stops moving when reaching this value. </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset"> + The camera's offset, useful for looking around or camera shake animations. </member> <member name="rotating" type="bool" setter="set_rotating" getter="is_rotating"> </member> @@ -364,6 +375,7 @@ <member name="smoothing_speed" type="float" setter="set_follow_smoothing" getter="get_follow_smoothing"> </member> <member name="zoom" type="Vector2" setter="set_zoom" getter="get_zoom"> + The camera's zoom relative to the viewport. Values larger than [code]Vector2(1, 1)[/code] zoom out and smaller values zoom in. For an example, use [code]Vector2(0.5, 0.5)[/code] for a 2x zoom in, and [code]Vector2(4, 4)[/code] for a 4x zoom out. </member> </members> <constants> diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml index 8f242c5187..fb7edd65ad 100644 --- a/doc/classes/KinematicBody.xml +++ b/doc/classes/KinematicBody.xml @@ -6,7 +6,7 @@ <description> Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all (to other types of bodies, such a character or a rigid body, these are the same as a static body). They have however, two main uses: Simulated Motion: When these bodies are moved manually, either from code or from an AnimationPlayer (with process mode set to fixed), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc). - Kinematic Characters: KinematicBody also has an api for moving objects (the [method move] method) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics. + Kinematic Characters: KinematicBody also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics. </description> <tutorials> </tutorials> @@ -17,6 +17,7 @@ <return type="Vector3"> </return> <description> + Returns the velocity of the floor. Only updates when calling [method move_and_slide]. </description> </method> <method name="get_safe_margin" qualifiers="const"> @@ -31,30 +32,35 @@ <argument index="0" name="slide_idx" type="int"> </argument> <description> + Returns a [KinematicCollision], which contains information about a collision that occured during the last [method move_and_slide] call. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count]()-1). </description> </method> <method name="get_slide_count" qualifiers="const"> <return type="int"> </return> <description> + Returns the number of times the body collided and changed direction during the last call to [method move_and_slide]. </description> </method> <method name="is_on_ceiling" qualifiers="const"> <return type="bool"> </return> <description> + Returns [code]true[/code] if the body is on the ceiling. Only updates when calling [method move_and_slide]. </description> </method> <method name="is_on_floor" qualifiers="const"> <return type="bool"> </return> <description> + Returns [code]true[/code] if the body is on the floor. Only updates when calling [method move_and_slide]. </description> </method> <method name="is_on_wall" qualifiers="const"> <return type="bool"> </return> <description> + Returns [code]true[/code] if the body is on a wall. Only updates when calling [method move_and_slide]. </description> </method> <method name="move_and_collide"> @@ -63,6 +69,7 @@ <argument index="0" name="rel_vec" type="Vector3"> </argument> <description> + Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision], which contains information about the collision. </description> </method> <method name="move_and_slide"> @@ -79,6 +86,13 @@ <argument index="4" name="floor_max_angle" type="float" default="0.785398"> </argument> <description> + Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [KinematicBody] or [RigidBody], it will also be affected by the motion of the other body. You can use this to make moving or rotating platforms, or to make nodes push other nodes. + [code]linear_velocity[/code] is a value in pixels per second. Unlike in for example [method move_and_collide], you should [i]not[/i] multiply it with [code]delta[/delta] — this is done by the method. + [code]floor_normal[/code] is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of [code]Vector2(0, 0)[/code], everything is considered a wall. This is useful for topdown games. + If the body is standing on a slope and the horizontal speed (relative to the floor's speed) goes below [code]slope_stop_min_velocity[/code], the body will stop completely. This prevents the body from sliding down slopes when you include gravity in [code]linear_velocity[/code]. When set to lower values, the body will not be able to stand still on steep slopes. + If the body collides, it will change direction a maximum of [code]max_bounces[/code] times before it stops. + [code]floor_max_angle[/code] is the maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall. The default value equals 45 degrees. + Returns the movement that remained when the body stopped. To get more detailed information about collisions that occured, use [method get_slide_collision]. </description> </method> <method name="set_safe_margin"> @@ -97,11 +111,13 @@ <argument index="1" name="rel_vec" type="Vector3"> </argument> <description> + Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. </description> </method> </methods> <members> <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin"> + If the body is at least this close to another body, this body will consider them to be colliding. </member> </members> <constants> diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml index dddae2c0fc..d9e669f493 100644 --- a/doc/classes/KinematicBody2D.xml +++ b/doc/classes/KinematicBody2D.xml @@ -6,7 +6,7 @@ <description> Kinematic bodies are special types of bodies that are meant to be user-controlled. They are not affected by physics at all (to other types of bodies, such a character or a rigid body, these are the same as a static body). They have however, two main uses: Simulated Motion: When these bodies are moved manually, either from code or from an AnimationPlayer (with process mode set to fixed), the physics will automatically compute an estimate of their linear and angular velocity. This makes them very useful for moving platforms or other AnimationPlayer-controlled objects (like a door, a bridge that opens, etc). - Kinematic Characters: KinematicBody2D also has an api for moving objects (the [method move] method) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics. + Kinematic Characters: KinematicBody2D also has an API for moving objects (the [method move_and_collide] and [method move_and_slide] methods) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics. </description> <tutorials> </tutorials> @@ -17,6 +17,7 @@ <return type="Vector2"> </return> <description> + Returns the velocity of the floor. Only updates when calling [method move_and_slide]. </description> </method> <method name="get_safe_margin" qualifiers="const"> @@ -31,30 +32,35 @@ <argument index="0" name="slide_idx" type="int"> </argument> <description> + Returns a [KinematicCollision2D], which contains information about a collision that occured during the last [method move_and_slide] call. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count]()-1). </description> </method> <method name="get_slide_count" qualifiers="const"> <return type="int"> </return> <description> + Returns the number of times the body collided and changed direction during the last call to [method move_and_slide]. </description> </method> <method name="is_on_ceiling" qualifiers="const"> <return type="bool"> </return> <description> + Returns [code]true[/code] if the body is on the ceiling. Only updates when calling [method move_and_slide]. </description> </method> <method name="is_on_floor" qualifiers="const"> <return type="bool"> </return> <description> + Returns [code]true[/code] if the body is on the floor. Only updates when calling [method move_and_slide]. </description> </method> <method name="is_on_wall" qualifiers="const"> <return type="bool"> </return> <description> + Returns [code]true[/code] if the body is on a wall. Only updates when calling [method move_and_slide]. </description> </method> <method name="move_and_collide"> @@ -63,7 +69,7 @@ <argument index="0" name="rel_vec" type="Vector2"> </argument> <description> - Moves the body along the given vector. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the colliding body. + Moves the body along the vector [code]rel_vec[/code]. The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision. </description> </method> <method name="move_and_slide"> @@ -80,6 +86,13 @@ <argument index="4" name="floor_max_angle" type="float" default="0.785398"> </argument> <description> + Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [KinematicBody2D] or [RigidBody2D], it will also be affected by the motion of the other body. You can use this to make moving or rotating platforms, or to make nodes push other nodes. + [code]linear_velocity[/code] is a value in pixels per second. Unlike in for example [method move_and_collide], you should [i]not[/i] multiply it with [code]delta[/delta] — this is done by the method. + [code]floor_normal[/code] is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of [code]Vector2(0, 0)[/code], everything is considered a wall. This is useful for topdown games. + If the body is standing on a slope and the horizontal speed (relative to the floor's speed) goes below [code]slope_stop_min_velocity[/code], the body will stop completely. This prevents the body from sliding down slopes when you include gravity in [code]linear_velocity[/code]. When set to lower values, the body will not be able to stand still on steep slopes. + If the body collides, it will change direction a maximum of [code]max_bounces[/code] times before it stops. + [code]floor_max_angle[/code] is the maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall. The default value equals 45 degrees. + Returns the movement that remained when the body stopped. To get more detailed information about collisions that occured, use [method get_slide_collision]. </description> </method> <method name="set_safe_margin"> @@ -98,14 +111,15 @@ <argument index="1" name="rel_vec" type="Vector2"> </argument> <description> - Returns true if there would be a collision if the body moved from the given point in the given direction. + Checks for collisions without moving the body. Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]rel_vec[/code]. Returns [code]true[/code] if a collision would occur. </description> </method> </methods> <members> <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin"> + If the body is at least this close to another body, this body will consider them to be colliding. </member> </members> <constants> </constants> -</class> +</class>
\ No newline at end of file diff --git a/doc/classes/Sprite.xml b/doc/classes/Sprite.xml index c0c491140f..0cdc8f7099 100644 --- a/doc/classes/Sprite.xml +++ b/doc/classes/Sprite.xml @@ -202,7 +202,7 @@ </methods> <members> <member name="centered" type="bool" setter="set_centered" getter="is_centered"> - If [code]true[/code] texture will be centered. Default value: [code]true[/code]. + If [code]true[/code] texture is centered. Default value: [code]true[/code]. </member> <member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h"> If [code]true[/code] texture is flipped horizontally. Default value: [code]false[/code]. @@ -211,40 +211,42 @@ If [code]true[/code] texture is flipped vertically. Default value: [code]false[/code]. </member> <member name="frame" type="int" setter="set_frame" getter="get_frame"> - Current frame to display from sprite sheet. [code]vframes[/code] or [code]hframes[/code] must be greater than 1. + Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1. </member> <member name="hframes" type="int" setter="set_hframes" getter="get_hframes"> - The number of horizontal frames in the sprite sheet. + The number of collumns in the sprite sheet. </member> <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> + The normal map gives depth to the Sprite. </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset"> The texture's drawing offset. </member> <member name="region_enabled" type="bool" setter="set_region" getter="is_region"> - If [code]true[/code] texture will be cut from a larger atlas texture. See [code]region_rect[/code]. Default value: [code]false[/code]. + If [code]true[/code] texture is cut from a larger atlas texture. See [code]region_rect[/code]. Default value: [code]false[/code]. </member> <member name="region_filter_clip" type="bool" setter="set_region_filter_clip" getter="is_region_filter_clip_enabled"> + If [code]true[/code] the outermost pixels get blurred out. </member> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect"> - The region of the atlas texture to display. [code]region_enabled[/code] must be [code]true[/code]. + The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. </member> <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> [Texture] object to draw. </member> <member name="vframes" type="int" setter="set_vframes" getter="get_vframes"> - The number of vertical frames in the sprite sheet. + The number of rows in the sprite sheet. </member> </members> <signals> <signal name="frame_changed"> <description> - Emitted when the [code]frame[/code] changes. + Emitted when the [member frame] changes. </description> </signal> <signal name="texture_changed"> <description> - Emitted when the [code]texture[/code] changes. + Emitted when the [member texture] changes. </description> </signal> </signals> diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml index f6f2f8f00c..e51616a071 100644 --- a/doc/classes/Sprite3D.xml +++ b/doc/classes/Sprite3D.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Sprite3D" inherits="SpriteBase3D" category="Core" version="3.0.alpha.custom_build"> <brief_description> + 2D Sprite node in 3D world. </brief_description> <description> + A node that displays a 2D texture in a 3D environment. The texture displayed can be a region from a larger atlas texture, or a frame from a sprite sheet animation. </description> <tutorials> </tutorials> @@ -96,21 +98,28 @@ </methods> <members> <member name="frame" type="int" setter="set_frame" getter="get_frame"> + Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1. </member> <member name="hframes" type="int" setter="set_hframes" getter="get_hframes"> + The number of columns in the sprite sheet. </member> <member name="region_enabled" type="bool" setter="set_region" getter="is_region"> + If [code]true[/code] texture will be cut from a larger atlas texture. See [member region_rect]. Default value: [code]false[/code]. </member> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect"> + The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. </member> <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> + [Texture] object to draw. </member> <member name="vframes" type="int" setter="set_vframes" getter="get_vframes"> + The number of rows in the sprite sheet. </member> </members> <signals> <signal name="frame_changed"> <description> + Emitted when the [member frame] changes. </description> </signal> </signals> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 1640e5dc9f..7ed681ea12 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="SpriteBase3D" inherits="GeometryInstance" category="Core" version="3.0.alpha.custom_build"> <brief_description> + 2D Sprite node in 3D environment. </brief_description> <description> + A node that displays 2D texture information in a 3D environment. </description> <tutorials> </tutorials> @@ -164,36 +166,51 @@ <member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="SpriteBase3D.AlphaCutMode"> </member> <member name="axis" type="int" setter="set_axis" getter="get_axis" enum="Vector3.Axis"> + The direction in which the front of the texture faces. </member> <member name="centered" type="bool" setter="set_centered" getter="is_centered"> + If [code]true[/code] texture will be centered. Default value: [code]true[/code]. </member> <member name="double_sided" type="bool" setter="set_draw_flag" getter="get_draw_flag"> + If [code]true[/code] texture can be seen from the back as well, if [code]false[/code], it is invisible when looking at it from behind. Default value: [code]true[/code]. </member> <member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h"> + If [code]true[/code] texture is flipped horizontally. Default value: [code]false[/code]. </member> <member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v"> + If [code]true[/code] texture is flipped vertically. Default value: [code]false[/code]. </member> <member name="modulate" type="Color" setter="set_modulate" getter="get_modulate"> + A color value that gets multiplied on, could be used for mood-coloring or to simulate the color of light. </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset"> + The texture's drawing offset. </member> <member name="opacity" type="float" setter="set_opacity" getter="get_opacity"> + The objects visibility on a scale from [code]0[/code] fully invisible to [code]1[/code] fully visible. </member> <member name="pixel_size" type="float" setter="set_pixel_size" getter="get_pixel_size"> + The size of one pixel's width on the Sprite to scale it in 3D. </member> <member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag"> + If [code]true[/code] the [Light] in the [Environment] has effects on the Sprite. Default value: [code]false[/code]. </member> <member name="transparent" type="bool" setter="set_draw_flag" getter="get_draw_flag"> + If [code]true[/code] the texture's transparency and the opacity are used to make those parts of the Sprite invisible. Default value: [code]true[/code]. </member> </members> <constants> <constant name="FLAG_TRANSPARENT" value="0"> + If set, the texture's transparency and the opacity are used to make those parts of the Sprite invisible. </constant> <constant name="FLAG_SHADED" value="1"> + If set, the Light in the Environment has effects on the Sprite. </constant> <constant name="FLAG_DOUBLE_SIDED" value="2"> + If set, texture can be seen from the back as well, if not, it is invisible when looking at it from behind. </constant> <constant name="FLAG_MAX" value="3"> + Used internally to mark the end of the Flags section. </constant> <constant name="ALPHA_CUT_DISABLED" value="0"> </constant> diff --git a/doc/classes/TextureButton.xml b/doc/classes/TextureButton.xml index e4f00555b3..8e51548c10 100644 --- a/doc/classes/TextureButton.xml +++ b/doc/classes/TextureButton.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="TextureButton" inherits="BaseButton" category="Core" version="3.0.alpha.custom_build"> <brief_description> - Button that can be themed with textures. + Texture-based button. Supports Pressed, Hover, Disabled and Focused states. </brief_description> <description> - Button that can be themed with textures. This is like a regular [Button] but can be themed by assigning textures to it. This button is intended to be easy to theme, however a regular button can expand (that uses styleboxes) and still be better if the interface is expect to have internationalization of texts. - Only the normal texture is required, the others are optional. + [code]TextureButton[/code] has the same functionality as [Button], except it uses sprites instead of Godot's [Theme] resource. It is faster to create, but it doesn't support localization like more complex Controls. + The Normal state's texture is required. Others are optional. </description> <tutorials> </tutorials> @@ -127,36 +127,51 @@ </methods> <members> <member name="expand" type="bool" setter="set_expand" getter="get_expand"> + If [code]true[/code] the texture stretches to the edges of the node's bounding rectangle using the [member stretch_mode]. If [code]false[/code] the texture will not scale with the node. Default value: [code]false[/code]. </member> <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureButton.StretchMode"> + Controls the texture's behavior when you resize the node's bounding rectangle, [b]only if[/b] [member expand] is [code]true[/code]. Set it to one of the [code]STRETCH_*[/code] constants. See the constants to learn more. </member> <member name="texture_click_mask" type="BitMap" setter="set_click_mask" getter="get_click_mask"> + Pure black and white [Bitmap] image to use for click detection. On the mask, white pixels represent the button's clickable area. Use it to create buttons with curved shapes. </member> <member name="texture_disabled" type="Texture" setter="set_disabled_texture" getter="get_disabled_texture"> + Texture to display when the node is disabled. See [member BaseButton.disabled]. </member> <member name="texture_focused" type="Texture" setter="set_focused_texture" getter="get_focused_texture"> + Texture to display when the node has mouse or keyboard focus. </member> <member name="texture_hover" type="Texture" setter="set_hover_texture" getter="get_hover_texture"> + Texture to display when the mouse hovers the node. </member> <member name="texture_normal" type="Texture" setter="set_normal_texture" getter="get_normal_texture"> + Texture to display by default, when the node is [b]not[/b] in the disabled, focused, hover or pressed state. </member> <member name="texture_pressed" type="Texture" setter="set_pressed_texture" getter="get_pressed_texture"> + Texture to display on mouse down over the node, if the node has keyboard focus and the player presses the enter key or if the player presses the [member BaseButton.shortcut] key. </member> </members> <constants> <constant name="STRETCH_SCALE" value="0"> + Scale to fit the node's bounding rectangle. </constant> <constant name="STRETCH_TILE" value="1"> + Tile inside the node's bounding rectangle. </constant> <constant name="STRETCH_KEEP" value="2"> + The texture keeps its original size and stays in the bounding rectangle's top-left corner. </constant> <constant name="STRETCH_KEEP_CENTERED" value="3"> + The texture keeps its original size and stays centered in the node's bounding rectangle. </constant> <constant name="STRETCH_KEEP_ASPECT" value="4"> + Scale the texture to fit the node's bounding rectangle, but maintain the texture's aspect ratio. </constant> <constant name="STRETCH_KEEP_ASPECT_CENTERED" value="5"> + Scale the texture to fit the node's bounding rectangle, center it, and maintain its aspect ratio. </constant> <constant name="STRETCH_KEEP_ASPECT_COVERED" value="6"> + Scale the texture so that the shorter side fits the bounding rectangle. The other side clips to the node's limits. </constant> </constants> </class> diff --git a/doc/classes/TextureProgress.xml b/doc/classes/TextureProgress.xml index 0a6ffcdeb8..f8165753c6 100644 --- a/doc/classes/TextureProgress.xml +++ b/doc/classes/TextureProgress.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="TextureProgress" inherits="Range" category="Core" version="3.0.alpha.custom_build"> <brief_description> - Textured progress bar. + Texture-based progress bar. Useful for loading screens and life or stamina bars. </brief_description> <description> - A [ProgressBar] that uses textures to display fill percentage. Can be set to linear or radial mode. + TextureProgress works like [ProgressBar] but it uses up to 3 textures instead of Godot's [Theme] resource. Works horizontally, vertically, and radially. </description> <tutorials> </tutorials> @@ -151,51 +151,59 @@ The fill direction. Uses FILL_* constants. </member> <member name="nine_patch_stretch" type="bool" setter="set_nine_patch_stretch" getter="get_nine_patch_stretch"> - If [code]true[/code] textures will be stretched as [NinePatchRect]. Uses [code]stretch_margin[/code] properties (see below). Default value: [code]false[/code] + If [code]true[/code] Godot treats the bar's textures like [NinePatchRect]. Use [code]stretch_margin_*[/code], like [member stretch_margin_bottom], to set up the nine patch's 3x3 grid. Default value: [code]false[/code]. </member> <member name="radial_center_offset" type="Vector2" setter="set_radial_center_offset" getter="get_radial_center_offset"> - The offset amount for radial mode. + Offsets [member texture_progress] if [member fill_mode] is [code]FILL_CLOCKWISE[/code] or [code]FILL_COUNTER_CLOCKWISE[/code]. </member> <member name="radial_fill_degrees" type="float" setter="set_fill_degrees" getter="get_fill_degrees"> - The amount of the texture to use for radial mode. + Upper limit for the fill of [member texture_progress] if [member fill_mode] is [code]FILL_CLOCKWISE[/code] or [code]FILL_COUNTER_CLOCKWISE[/code]. When the node's [code]value[/code] is equal to its [code]max_value[/code], the texture fills up to this angle. + See [member Range.value], [member Range.max_value]. </member> <member name="radial_initial_angle" type="float" setter="set_radial_initial_angle" getter="get_radial_initial_angle"> - Start angle for radial mode. + Starting angle for the fill of [member texture_progress] if [member fill_mode] is [code]FILL_CLOCKWISE[/code] or [code]FILL_COUNTER_CLOCKWISE[/code]. When the node's [code]value[/code] is equal to its [code]min_value[/code], the texture doesn't show up at all. When the [code]value[/code] increases, the texture fills and tends towards [member radial_fill_degrees]. </member> <member name="stretch_margin_bottom" type="int" setter="set_stretch_margin" getter="get_stretch_margin"> - Nine-patch texture offset for bottom margin. + The height of the 9-patch's bottom row. A margin of 16 means the 9-slice's bottom corners and side will have a height of 16 pixels. You can set all 4 margin values individually to create panels with non-uniform borders. </member> <member name="stretch_margin_left" type="int" setter="set_stretch_margin" getter="get_stretch_margin"> - Nine-patch texture offset for left margin. + The width of the 9-patch's left column. </member> <member name="stretch_margin_right" type="int" setter="set_stretch_margin" getter="get_stretch_margin"> - Nine-patch texture offset for right margin. + The width of the 9-patch's right column. </member> <member name="stretch_margin_top" type="int" setter="set_stretch_margin" getter="get_stretch_margin"> - Nine-patch texture offset for top margin. + The height of the 9-patch's top row. </member> <member name="texture_over" type="Texture" setter="set_over_texture" getter="get_over_texture"> - The [Texture] that will be drawn over the progress bar. + [Texture] that draws over the progress bar. Use it to add highlights or an upper-frame that hides part of [member texture_progress]. </member> <member name="texture_progress" type="Texture" setter="set_progress_texture" getter="get_progress_texture"> - The [Texture] used to display [code]value[/code]. + [Texture] that clips based on the node's [code]value[/code] and [member fill_mode]. As [code]value[/code] increased, the texture fills up. It shows entirely when [code]value[/code] reaches [code]max_value[/code]. It doesn't show at all if [code]value[/code] is equal to [code]min_value[/code]. + The [code]value[/code] property comes from [Range]. See [member Range.value], [member Range.min_value], [member Range.max_value]. </member> <member name="texture_under" type="Texture" setter="set_under_texture" getter="get_under_texture"> - The [Texture] that will be drawn under the progress bar. + [Texture] that draws under the progress bar. The bar's background. </member> </members> <constants> <constant name="FILL_LEFT_TO_RIGHT" value="0"> + The [member texture_progress] fills from left to right. </constant> <constant name="FILL_RIGHT_TO_LEFT" value="1"> + The [member texture_progress] fills from right to left. </constant> <constant name="FILL_TOP_TO_BOTTOM" value="2"> + The [member texture_progress] fills from top to bototm. </constant> <constant name="FILL_BOTTOM_TO_TOP" value="3"> + The [member texture_progress] fills from bottom to top. </constant> <constant name="FILL_CLOCKWISE" value="4"> + Turns the node into a radial bar. The [member texture_progress] fills clockwise. See [member radial_center_offset], [member radial_initial_angle] and [member radial_fill_degrees] to refine its behavior. </constant> <constant name="FILL_COUNTER_CLOCKWISE" value="5"> + Turns the node into a radial bar. The [member texture_progress] fills counter-clockwise. See [member radial_center_offset], [member radial_initial_angle] and [member radial_fill_degrees] to refine its behavior. </constant> </constants> </class> diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp index 7b80e26645..1bad8a3f85 100644 --- a/modules/mono/editor/godotsharp_builds.cpp +++ b/modules/mono/editor/godotsharp_builds.cpp @@ -59,7 +59,7 @@ String _find_build_engine_on_unix(const String &p_name) { "/opt/novell/mono/bin/" }; - for (int i = 0; i < sizeof(locations) / sizeof(char); i++) { + for (int i = 0; i < sizeof(locations) / sizeof(const char *); i++) { String location = locations[i]; if (FileAccess::exists(location + p_name)) { diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index d0b5b12d4b..2c88832998 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -266,6 +266,13 @@ void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) { assemblies[p_domain_id][p_assembly->get_name()] = p_assembly; } +GDMonoAssembly **GDMono::get_loaded_assembly(const String &p_name) { + + MonoDomain *domain = mono_domain_get(); + uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0; + return assemblies[domain_id].getptr(p_name); +} + bool GDMono::_load_assembly(const String &p_name, GDMonoAssembly **r_assembly) { CRASH_COND(!r_assembly); @@ -278,34 +285,17 @@ bool GDMono::_load_assembly(const String &p_name, GDMonoAssembly **r_assembly) { MonoAssembly *assembly = mono_assembly_load_full(aname, NULL, &status, false); mono_assembly_name_free(aname); - if (!assembly) - return false; + ERR_FAIL_NULL_V(assembly, false); uint32_t domain_id = mono_domain_get_id(mono_domain_get()); GDMonoAssembly **stored_assembly = assemblies[domain_id].getptr(p_name); - if (stored_assembly) { - // Loaded by our preload hook (status is not initialized when returning from a preload hook) - ERR_FAIL_COND_V((*stored_assembly)->get_assembly() != assembly, false); - *r_assembly = *stored_assembly; - } else { - ERR_FAIL_COND_V(status != MONO_IMAGE_OK, false); - - MonoImage *assembly_image = mono_assembly_get_image(assembly); - ERR_FAIL_NULL_V(assembly_image, false); - - const char *path = mono_image_get_filename(assembly_image); - - *r_assembly = memnew(GDMonoAssembly(p_name, path)); - Error error = (*r_assembly)->wrapper_for_image(assembly_image); + ERR_FAIL_COND_V(status != MONO_IMAGE_OK, false); + ERR_FAIL_COND_V(stored_assembly == NULL, false); - if (error != OK) { - memdelete(*r_assembly); - *r_assembly = NULL; - ERR_FAIL_V(false); - } - } + ERR_FAIL_COND_V((*stored_assembly)->get_assembly() != assembly, false); + *r_assembly = *stored_assembly; if (OS::get_singleton()->is_stdout_verbose()) OS::get_singleton()->print(String("Mono: Assembly " + p_name + " loaded from path: " + (*r_assembly)->get_path() + "\n").utf8()); diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index ab96d575e6..b188c0730a 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -122,7 +122,9 @@ public: static GDMono *get_singleton() { return singleton; } + // Do not use these, unless you know what you're doing void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly); + GDMonoAssembly **get_loaded_assembly(const String &p_name); _FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized; } _FORCE_INLINE_ bool is_finalizing_scripts_domain() const { return finalizing_scripts_domain; } diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index a98537b9e1..a623b34b68 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -39,28 +39,60 @@ #include "../godotsharp_dirs.h" #include "gd_mono_class.h" -MonoAssembly *gdmono_load_assembly_from(const String &p_name, const String &p_path) { +bool GDMonoAssembly::no_search = false; +Vector<String> GDMonoAssembly::search_dirs; - MonoDomain *domain = mono_domain_get(); +MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_data) { - GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path)); - Error err = assembly->load(domain); - ERR_FAIL_COND_V(err != OK, NULL); + (void)user_data; // UNUSED - GDMono::get_singleton()->add_assembly(mono_domain_get_id(domain), assembly); + String name = mono_assembly_name_get_name(aname); + bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); - return assembly->get_assembly(); -} + if (no_search) + return NULL; -MonoAssembly *gdmono_MonoAssemblyPreLoad(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { + no_search = true; // Avoid the recursion madness - (void)user_data; // UNUSED + GDMonoAssembly **loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); + if (loaded_asm) + return (*loaded_asm)->get_assembly(); + + String path; + MonoAssembly *res = NULL; + + for (int i = 0; i < search_dirs.size(); i++) { + const String &search_dir = search_dirs[i]; - MonoAssembly *assembly_loaded = mono_assembly_loaded(aname); - if (assembly_loaded) // Already loaded - return assembly_loaded; + if (has_extension) { + path = search_dir.plus_file(name); + if (FileAccess::exists(path)) { + res = _load_assembly_from(name.get_basename(), path); + break; + } + } else { + path = search_dir.plus_file(name + ".dll"); + if (FileAccess::exists(path)) { + res = _load_assembly_from(name, path); + break; + } + + path = search_dir.plus_file(name + ".exe"); + if (FileAccess::exists(path)) { + res = _load_assembly_from(name, path); + break; + } + } + } - static Vector<String> search_dirs; + no_search = false; + + return res; +} + +MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data) { + + (void)user_data; // UNUSED if (search_dirs.empty()) { search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir()); @@ -80,35 +112,32 @@ MonoAssembly *gdmono_MonoAssemblyPreLoad(MonoAssemblyName *aname, char **assembl } } - String name = mono_assembly_name_get_name(aname); - bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); + return NULL; +} - String path; +MonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path) { - for (int i = 0; i < search_dirs.size(); i++) { - const String &search_dir = search_dirs[i]; + GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path)); - if (has_extension) { - path = search_dir.plus_file(name); - if (FileAccess::exists(path)) - return gdmono_load_assembly_from(name.get_basename(), path); - } else { - path = search_dir.plus_file(name + ".dll"); - if (FileAccess::exists(path)) - return gdmono_load_assembly_from(name, path); + MonoDomain *domain = mono_domain_get(); - path = search_dir.plus_file(name + ".exe"); - if (FileAccess::exists(path)) - return gdmono_load_assembly_from(name, path); - } + Error err = assembly->load(domain); + + if (err != OK) { + memdelete(assembly); + ERR_FAIL_V(NULL); } - return NULL; + GDMono::get_singleton()->add_assembly(domain ? mono_domain_get_id(domain) : 0, assembly); + + return assembly->get_assembly(); } void GDMonoAssembly::initialize() { - mono_install_assembly_preload_hook(&gdmono_MonoAssemblyPreLoad, NULL); + // TODO refonly as well? + mono_install_assembly_preload_hook(&GDMonoAssembly::_preload_hook, NULL); + mono_install_assembly_search_hook(&GDMonoAssembly::_search_hook, NULL); } Error GDMonoAssembly::load(MonoDomain *p_domain) { @@ -153,7 +182,7 @@ no_pdb: ERR_FAIL_COND_V(status != MONO_IMAGE_OK || assembly == NULL, ERR_FILE_CANT_OPEN); - if (mono_image_get_entry_point(image)) { + if (p_domain && mono_image_get_entry_point(image)) { // TODO should this be removed? do we want to call main? what other effects does this have? mono_jit_exec(p_domain, assembly, 0, NULL); } diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 89e091549c..710b674622 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -86,6 +86,14 @@ class GDMonoAssembly { Vector<uint8_t> pdb_data; #endif + static bool no_search; + static Vector<String> search_dirs; + + static MonoAssembly *_search_hook(MonoAssemblyName *aname, void *user_data); + static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data); + + static MonoAssembly *_load_assembly_from(const String &p_name, const String &p_path); + friend class GDMono; static void initialize(); |