701 Commits

Author SHA1 Message Date
dave jones2
3bff6cb886 UE-188291 - Blueprint autoconversions can't handle default values
Blueprint autoconversions normally work by checking pairs of linked pins and inserting cast nodes. However, default literal values on nodes aren't linked, so they must be treated differently.

Since default values aren't linked, we need to check the old and new pin types during rewiring. We can't do this during validation stage since we've forgotten the old pin type by that point. Additionally, we should prevent any sort of data loss when handling the default values. The safest way to do so is:

1. Create a literal node from the old type.
2. Create a conversion node between the old and new type.
3. Link the nodes to the pin that has the default value.

The drawback to this technique is that it inserts nodes, but it's safer than directly modifying the default value on the new pin (eg: "1.1" could end up as "1"). We still provide a note that nodes were inserted, which gives the developer the choice of how to handle the conversion change.

#jira UE-188291
#rb phillip.kavan

[CL 26055966 by dave jones2 in 5.3 branch]
2023-06-16 12:12:03 -04:00
dave jones2
e203cea604 UE-183502 - BP autoconversion adds extraneous conversion nodes (resubmit)
(Resubmit: added check for "multiple self" connections. Even though the types mismatch, we permit these connections.)

The previous attempt to add automatic conversion nodes (24029327) had a flawed design: checking pin connections during rewiring might have an incomplete view of the types of the linked pins.

For example, suppose we have two native, BlueprintCallable functions. One returns a float, and the other accepts a single float. In a Blueprint, we have the output of one linked to the input of the other.

Later, we update both functions to use ints. During rewiring of the function with the return value, it might see that its connection is a float (because that node hasn't been rewired yet). As a result, it'll insert a cast node. Subsequently, when we later rewire the function with the input, it'll see that it's connected to a float, because of the recently inserted cast node. This will add yet another cast node. Since both pin types are the same, there shouldn't be any cast nodes to begin with.

The only safe way to insert cast nodes is after node construction has finished. Instead of handling this during rewiring, we can defer the type checking to early validation. Overall, this simplifies the autoconversion since we just need to iterate over pairs of pins, check for type mismatches, and insert cast nodes where appropriate.

This change effectively reverts CLs 24174262, 24029327, 24218437, and 25444139, and moves the type checking logic to EarlyValidation.

#jira UE-183502
#rb phillip.kavan

[CL 25834276 by dave jones2 in ue5-main branch]
2023-06-06 21:17:28 -04:00
ben hoffman
4759599dff [Backout] - CL25790092
Add a small bug fix to it. When attempting to create an auto-cast node from an Interface -> Object type, the UEdGraphSchema_K2::FindSpecializedConversionNode will NewObject whatever node type is required as a template to copy. This Template node does not have a parent graph (rightfully so) which means that the call to GetSchema would return null. When this happened with a Dynamic Cast node, it was checking on the schema being available in the SetPurity function where it was not before.

We don't want to set the parent graph on the template node during conversion because that isn't accurate because its a dummy template node, not something that is actually on the graph. It would also be adding references to that parent graph unnecessarily.
#rb Phillip.Kavan

Original CL Desc
-----------------------------------------------------------------
Fix potential crash when `bFavorPureCastNodes` is enabled.

`K2Node_Message` attempted to create an impure cast node when expanded, but `SetPurity(false)` had no effect in this case because inside it `IsNodePure` returned `false` even if the default cast purity was `Pure`. It resulted in the creation of a pure node, causing a crash because the Message node attempted to work with its (non-existent) exec pins.

#rb Phillip.Kavan

#ushell-cherrypick of 25757919 by kristof.morva1

[CL 25792482 by ben hoffman in ue5-main branch]
2023-06-05 11:05:42 -04:00
ben hoffman
4171fe00ac [Backout] - CL25758302
#fyi Phillip.Kavan
Original CL Desc
-----------------------------------------------------------------
Fix potential crash when `bFavorPureCastNodes` is enabled.

`K2Node_Message` attempted to create an impure cast node when expanded, but `SetPurity(false)` had no effect in this case because inside it `IsNodePure` returned `false` even if the default cast purity was `Pure`. It resulted in the creation of a pure node, causing a crash because the Message node attempted to work with its (non-existent) exec pins.

#rb Phillip.Kavan
#preflight 6479d868e319748a83f72c54

#ushell-cherrypick of 25757919 by kristof.morva1

[CL 25790092 by ben hoffman in ue5-main branch]
2023-06-05 08:30:10 -04:00
ben hoffman
10c18ce23e Fix potential crash when bFavorPureCastNodes is enabled.
`K2Node_Message` attempted to create an impure cast node when expanded, but `SetPurity(false)` had no effect in this case because inside it `IsNodePure` returned `false` even if the default cast purity was `Pure`. It resulted in the creation of a pure node, causing a crash because the Message node attempted to work with its (non-existent) exec pins.

#rb Phillip.Kavan
#preflight 6479d868e319748a83f72c54

#ushell-cherrypick of 25757919 by kristof.morva1

[CL 25758302 by ben hoffman in ue5-main branch]
2023-06-02 08:24:28 -04:00
bob tellez
89ca3b4813 [Backout] - CL25727793
[FYI] dave.jones2
Original CL Desc
-----------------------------------------------------------------
UE-183502 - BP autoconversion adds extraneous conversion nodes

The previous attempt to add automatic conversion nodes (24029327) had a flawed design: checking pin connections during rewiring might have an incomplete view of the types of the linked pins.

For example, suppose we have two native, BlueprintCallable functions. One returns a float, and the other accepts a single float. In a Blueprint, we have the output of one linked to the input of the other.

Later, we update both functions to use ints. During rewiring of the function with the return value, it might see that its connection is a float (because that node hasn't been rewired yet). As a result, it'll insert a cast node. Subsequently, when we later rewire the function with the input, it'll see that it's connected to a float, because of the recently inserted cast node. This will add yet another cast node. Since both pin types are the same, there shouldn't be any cast nodes to begin with.

The only safe way to insert cast nodes is after node construction has finished. Instead of handling this during rewiring, we can defer the type checking to early validation. Overall, this simplifies the autoconversion since we just need to iterate over pairs of pins, check for type mismatches, and insert cast nodes where appropriate.

This change effectively reverts CLs 24174262, 24029327, 24218437, and 25444139, and moves the type checking logic to EarlyValidation.

#jira UE-183502
#preflight 647102108145a219b1209905
#rb phillip.kavan

[CL 25748352 by bob tellez in ue5-main branch]
2023-06-01 19:38:24 -04:00
dave jones2
58bc468b87 UE-183502 - BP autoconversion adds extraneous conversion nodes
The previous attempt to add automatic conversion nodes (24029327) had a flawed design: checking pin connections during rewiring might have an incomplete view of the types of the linked pins.

For example, suppose we have two native, BlueprintCallable functions. One returns a float, and the other accepts a single float. In a Blueprint, we have the output of one linked to the input of the other.

Later, we update both functions to use ints. During rewiring of the function with the return value, it might see that its connection is a float (because that node hasn't been rewired yet). As a result, it'll insert a cast node. Subsequently, when we later rewire the function with the input, it'll see that it's connected to a float, because of the recently inserted cast node. This will add yet another cast node. Since both pin types are the same, there shouldn't be any cast nodes to begin with.

The only safe way to insert cast nodes is after node construction has finished. Instead of handling this during rewiring, we can defer the type checking to early validation. Overall, this simplifies the autoconversion since we just need to iterate over pairs of pins, check for type mismatches, and insert cast nodes where appropriate.

This change effectively reverts CLs 24174262, 24029327, 24218437, and 25444139, and moves the type checking logic to EarlyValidation.

#jira UE-183502
#preflight 647102108145a219b1209905
#rb phillip.kavan

[CL 25727812 by dave jones2 in ue5-main branch]
2023-06-01 11:29:35 -04:00
kirill zorin
de8db5ff76 Converting ARO-facing raw pointers to TObjectPtr ahead of raw pointer ARO API deprecation.
#rb zousar.shaker
#rb markus.breyer
#rb robert.manuszewski

#preflight 646391406b1406b54ab15460

[CL 25489627 by kirill zorin in ue5-main branch]
2023-05-16 10:52:49 -04:00
patrick boutot
7b306e0840 MVVM: Add the FieldNotify pattern to the base Blueprint. The pattern will be removed from the Widget and from the ViewmodelBase class. A BP variable that has the FieldNotify flag will use a different setter. If the variable is replicated, the OnRep function will broadcast the FieldNotification event. FieldNotify variables cannot be used as a ref argument.
#rb dan.oconnor, leon.huang
#jira UE-182297
#preflight 6436d2cef12d5de7056ef8d9

[CL 25026926 by patrick boutot in ue5-main branch]
2023-04-13 11:55:18 -04:00
phillip kavan
f74451e319 Generated Blueprint skeleton class functions will no longer parent themselves to interface class functions in the fast path, while also ensuring backwards-compatibility for existing call sites to implemented interface functions.
Notes:
- See 24252017 for additional context/review notes. The original change was backed out due to not handling mismatched object->object pin contexts on existing function call nodes (rare), so this version adds that part. An A/B screenshot is attached to the latest swarm review.

#rnx
#jira UE-157527
#rb Dave.Jones2
#preflight 63e75b9e043416e7ad4699b3

[CL 24315905 by phillip kavan in ue5-main branch]
2023-02-20 11:42:54 -05:00
George Rolfe
dce2b73049 Exported K2 map and container nodes to allow out-of-module inheritance
#jira UE-176097
#rb dan.oconnor
#preflight 63ecb65c956709374afc2b9b

[CL 24242024 by George Rolfe in ue5-main branch]
2023-02-15 16:32:42 -05:00
Phillip Kavan
b95ab41921 Allow self pins that redirect from interface->object type to pass without explicitly inserting an auto-conversion node during reconstruction of function call nodes.
Notes:
- This change is part of an upcoming regression fix (UE-157527) that will merge in from another stream that doesn't yet include type redirect support (UE-172222).

#rnx
#jira UE-157527, UE-172222
#rb Dave.Jones2
#preflight 63eb3afdf36e1a5ece5311a8

[CL 24218437 by Phillip Kavan in ue5-main branch]
2023-02-14 14:42:38 -05:00
joe pribele
f25f5c1d55 FBPTerminal::ObjectLiteral to TObjectPtr from UObject to avoid loading object during Bluepirnt compilation
https://p4-swarm.epicgames.net/reviews/23978331

#rb dan.oconnor zousar.shaker
#preflight 63ea7b5a923476b686e61d09

[CL 24180560 by joe pribele in ue5-main branch]
2023-02-13 13:22:08 -05:00
bob tellez
096493d9a4 [Backout] - CL24063026
[FYI] Phillip.Kavan
Original CL Desc
-----------------------------------------------------------------
Generated Blueprint skeleton class functions will no longer parent themselves to interface class functions in the fast path, while also ensuring backwards-compatibility for existing call sites to implemented interface functions.

Epidemiology:
- There was a regression introduced with the change to BPCM in 4.17 which started causing all newly-placed function call nodes to use the interface class as the Target pin type, rather than the 'self' type.
- However, the compiled function context was still inferred as the 'self' type, which resulted in emitting to bytecode only EX_Context w/o the required EX_InterfaceContext.
- This meant at runtime the VM would read an FScriptInterface value (16 bytes) into a UObject* ptr value (8 bytes) allocated on the stack (execContext), which caused a stack overrun (recently surfaced by ASAN).
- That regression is now fixed in the BPCM, however..
- Since we also allow object->interface connections to pass w/o casting when the object type implements the interface, this appeared to work the same as before the regression from a user perspective. However, it created an inconsistency for Target pin types that led to some odd UX; for example, if you choose to no longer implement the interface, now you might have a local function call site w/ an interface-typed Target pin that you can no longer connect self to/broken connection.
- Fixing the BPCM issue also meant that Target pins reverted back to 'self' object type on existing nodes, which caused a backcompat issue from being linked to interface pins (as that requires an interface->object conversion and will fail validation).
- Fixing that *seemed* relatively straightforward; I added a bit of code to modify the node expansion to spawn an intermediate cast node. However..
- Discovered that dynamic cast nodes had an issue where ones we dropped as an autocast via TryCreateConnection() would not be pure (i.e. no exec pins) even though it was explicitly being set in the autocast logic.
- This meant that any intermediate autocast nodes for interface->self end up being dropped as impure, with no connection to the exec pins, so they would end up being pruned at compile time. (this problem was due to another regression that traced back a long long ways..it was introduced in UE 4.6).
- Fixing that required a change to the way in which Dynamic Cast nodes manage the internal pure/impure state (since it can be toggled by the user, and it also has a default setting for new nodes).
- After fixing that, existing connections now continue to work (including previously-connected interface array outputs), while dragging new connections from interface->self will now add an explicit autocast node.
- An additional fix was made to prevent users from connecting an array of interfaces output to a function call node's Target pin for new connections (existing connections will continue to function per above).
--> Since call nodes support a ForEach-style expansion, the array connection was being allowed to pass, but then it would try to add an autocast node as if it were a scalar type, which doesn't support the expansion, so it could not be connected (broken UX).

#jira UE-157527
#rb Dave.Jones2, Dan.OConnor, Ben.Zeigler, Marc.Audy
#preflight 63dd78f4cc75b137677aaa32

[CL 24067070 by bob tellez in ue5-main branch]
2023-02-08 00:27:06 -05:00
phillip kavan
3981030897 Generated Blueprint skeleton class functions will no longer parent themselves to interface class functions in the fast path, while also ensuring backwards-compatibility for existing call sites to implemented interface functions.
Epidemiology:
- There was a regression introduced with the change to BPCM in 4.17 which started causing all newly-placed function call nodes to use the interface class as the Target pin type, rather than the 'self' type.
- However, the compiled function context was still inferred as the 'self' type, which resulted in emitting to bytecode only EX_Context w/o the required EX_InterfaceContext.
- This meant at runtime the VM would read an FScriptInterface value (16 bytes) into a UObject* ptr value (8 bytes) allocated on the stack (execContext), which caused a stack overrun (recently surfaced by ASAN).
- That regression is now fixed in the BPCM, however..
- Since we also allow object->interface connections to pass w/o casting when the object type implements the interface, this appeared to work the same as before the regression from a user perspective. However, it created an inconsistency for Target pin types that led to some odd UX; for example, if you choose to no longer implement the interface, now you might have a local function call site w/ an interface-typed Target pin that you can no longer connect self to/broken connection.
- Fixing the BPCM issue also meant that Target pins reverted back to 'self' object type on existing nodes, which caused a backcompat issue from being linked to interface pins (as that requires an interface->object conversion and will fail validation).
- Fixing that *seemed* relatively straightforward; I added a bit of code to modify the node expansion to spawn an intermediate cast node. However..
- Discovered that dynamic cast nodes had an issue where ones we dropped as an autocast via TryCreateConnection() would not be pure (i.e. no exec pins) even though it was explicitly being set in the autocast logic.
- This meant that any intermediate autocast nodes for interface->self end up being dropped as impure, with no connection to the exec pins, so they would end up being pruned at compile time. (this problem was due to another regression that traced back a long long ways..it was introduced in UE 4.6).
- Fixing that required a change to the way in which Dynamic Cast nodes manage the internal pure/impure state (since it can be toggled by the user, and it also has a default setting for new nodes).
- After fixing that, existing connections now continue to work (including previously-connected interface array outputs), while dragging new connections from interface->self will now add an explicit autocast node.
- An additional fix was made to prevent users from connecting an array of interfaces output to a function call node's Target pin for new connections (existing connections will continue to function per above).
--> Since call nodes support a ForEach-style expansion, the array connection was being allowed to pass, but then it would try to add an autocast node as if it were a scalar type, which doesn't support the expansion, so it could not be connected (broken UX).

#jira UE-157527
#rb Dave.Jones2, Dan.OConnor, Ben.Zeigler, Marc.Audy
#preflight 63dd78f4cc75b137677aaa32

[CL 24067044 by phillip kavan in ue5-main branch]
2023-02-08 00:26:29 -05:00
dave jones2
d9397ab592 UE-172222 - Improve redirect support for Blueprints. (resubmit)
A reflected Blueprint type can now be changed without breaking existing content, so long as an autocast function exists for the two types.

Previously, pin reconstruction would give up if two pin types didn't match exactly, which resulted in orphaned pins and compilation errors. Now, it'll first try to find an autocast function for the two types, and insert a cast node into the graph if one is found.

Additionally, notes will be added whenever a new cast node was added, which serves as a notice that users might want to update their API to use the new type change.

#jira UE-172222
#preflight 63d85cf57a39a1802189bdda
#rb phillip.kavan

[CL 24029327 by dave jones2 in ue5-main branch]
2023-02-06 09:08:45 -05:00
steve robb
ad6364e24e Replaced some enable-if/disable-if overloads with if constexpr blocks in a single function.
#rb devin.doucette
#preflight 63d45377f626715201acf9cb

[CL 23897639 by steve robb in ue5-main branch]
2023-01-27 23:12:19 -05:00
dave jones2
3c9c912448 Fixed static analysis warnings.
#jira none
#preflight 63d2e9f55d0c0164cc3b913e
#rb ben.hoffman

[CL 23884340 by dave jones2 in ue5-main branch]
2023-01-27 11:23:35 -05:00
steve robb
cf0094122b Fixed logic in FBindingObject::IsA<>().
#rb none
#preflight 63d29a6f5428dc67b1bac2e8
[FYI] robert.manuszewki

[CL 23868870 by steve robb in ue5-main branch]
2023-01-26 11:08:06 -05:00
nate strohmyer
6741c13774 Making latent BPs more descriptive in Tooltips
Adding Latent BP info to aync task nodes

#Jira UE-172965, UE-172960
#rb dan.oconnor
#preflight 63bda40ec45a2c81e013dd70

[CL 23759334 by nate strohmyer in ue5-main branch]
2023-01-18 12:53:59 -05:00
dave jones2
7b2e42b662 [Backout] - CL23629872 (Assorted BP compilation issues)
#fyi dave.jones2
Original CL Desc
-----------------------------------------------------------------
UE-172222 - Improve redirect support for Blueprints.

A reflected Blueprint type can now be changed without breaking existing content, so long as an autocast function exists for the two types.

Previously, pin reconstruction would give up if two pin types didn't match exactly, which resulted in orphaned pins and compilation errors. Now, it'll first try to find an autocast function for the two types, and insert a cast node into the graph if one is found.

Additionally, notes will be added whenever a new cast node was added, which serves as a notice that users might want to update their API to use the new type change.

#jira UE-172222
#preflight 63b72580af3ebedd9988ae4c
#rb benjamin.fox,dan.oconnor

[CL 23657454 by dave jones2 in ue5-main branch]
2023-01-11 18:54:32 -05:00
dave jones2
1f3ca97244 UE-172222 - Improve redirect support for Blueprints.
A reflected Blueprint type can now be changed without breaking existing content, so long as an autocast function exists for the two types.

Previously, pin reconstruction would give up if two pin types didn't match exactly, which resulted in orphaned pins and compilation errors. Now, it'll first try to find an autocast function for the two types, and insert a cast node into the graph if one is found.

Additionally, notes will be added whenever a new cast node was added, which serves as a notice that users might want to update their API to use the new type change.

#jira UE-172222
#preflight 63b72580af3ebedd9988ae4c
#rb benjamin.fox,dan.oconnor

[CL 23629872 by dave jones2 in ue5-main branch]
2023-01-10 13:35:44 -05:00
dan oconnor
ed1ffa4216 Add UPARAM(Required) markup for marking function parameters as required (must be linked to some other node in a Blueprint) - example usage:
UFUNCTION(BlueprintCallable)
static void TestRequiredIntParameter(UPARAM(Required) int32 Value);

Useful for marking pointer params as required so they are not null by default, but also applicable to complex types with custom make nodes

#jira
#rb Jordan.Hoffmann
#preflight 63b89fff763c6c10645b94c4

[CL 23604737 by dan oconnor in ue5-main branch]
2023-01-06 17:49:02 -05:00
danny couture
8c00ca57f9 Make BlueprintTypePromotion thread-safe for async loading in editor
- Scenario is: A module gets loaded and triggers a RefreshPromotionTables on the game-thread while the ALT reads FindBestMatchingFunc from the table.

#rnx
#jira UE-173083
#rb Dan.OConnor
#preflight 63b71395763c6c1064aec427

[CL 23590450 by danny couture in ue5-main branch]
2023-01-05 13:22:10 -05:00
jordan hoffmann
f87af1b9fb [CrashFix] Crash in FortniteGameWin64EditorPerf Warm LazyLoad Zen when fixing up transform scale method pins
#jira UE-172685
#rb phillip.kavan
#preflight 6398f32135203bc7aa8f8163

[CL 23497708 by jordan hoffmann in ue5-main branch]
2022-12-13 17:02:15 -05:00