@@ -1468,6 +1468,33 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
14681468 Template->Set (I.Keyword (" Load" ), I.FunctionTemplate (fn, ClassToExport));
14691469 }
14701470
1471+ Local<Value> C_Operator (UStruct* StructToExport, Local<Value> Value)
1472+ {
1473+ auto Instance = FStructMemoryInstance::FromV8 (Value);
1474+
1475+ // If given value is an instance
1476+ if (Instance)
1477+ {
1478+ auto GivenStruct = Instance->Struct ;
1479+ if (Instance->Struct ->IsChildOf (StructToExport))
1480+ {
1481+ return Value;
1482+ }
1483+ }
1484+ else if (auto ScriptStruct = Cast<UScriptStruct>(StructToExport))
1485+ {
1486+ if (Value->IsObject ())
1487+ {
1488+ auto v = Value->ToObject ();
1489+ auto Target = (uint8*)(FMemory_Alloca (ScriptStruct->GetStructureSize ()));
1490+ ReadOffStruct (v, ScriptStruct, Target);
1491+ return ExportStructInstance (ScriptStruct, Target, FNoPropertyOwner ());
1492+ }
1493+ }
1494+
1495+ return Local<v8::Value>();
1496+ }
1497+
14711498 void AddMemberFunction_Struct_C (Local<FunctionTemplate> Template, UStruct* StructToExport)
14721499 {
14731500 FIsolateHelper I (isolate_);
@@ -1479,30 +1506,7 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
14791506
14801507 if (info.Length () == 1 )
14811508 {
1482- auto Value = info[0 ];
1483-
1484- auto Instance = FStructMemoryInstance::FromV8 (Value);
1485-
1486- // If given value is an instance
1487- if (Instance)
1488- {
1489- auto GivenStruct = Instance->Struct ;
1490- if (Instance->Struct ->IsChildOf (StructToExport))
1491- {
1492- info.GetReturnValue ().Set (info[0 ]);
1493- }
1494- }
1495- else if (auto ScriptStruct = Cast<UScriptStruct>(StructToExport))
1496- {
1497- if (Value->IsObject ())
1498- {
1499- auto v = Value->ToObject ();
1500- auto Target = (uint8*)(FMemory_Alloca (ScriptStruct->GetStructureSize ()));
1501- GetSelf (isolate)->ReadOffStruct (v, ScriptStruct, Target);
1502- auto out = GetSelf (isolate)->ExportStructInstance (ScriptStruct, Target, FNoPropertyOwner ());
1503- info.GetReturnValue ().Set (out);
1504- }
1505- }
1509+ info.GetReturnValue ().Set (GetSelf (isolate)->C_Operator (StructToExport,info[0 ]));
15061510 }
15071511 };
15081512
@@ -1622,118 +1626,125 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
16221626
16231627 auto ClassToExport = reinterpret_cast <UClass*>((Local<External>::Cast (info.Data ()))->Value ());
16241628
1625- auto self = info.This ();
1626-
1627- UObject* Associated = nullptr ;
1628-
1629- // Called by system (via ExportObject)
1630- if (info.Length () == 1 && info[0 ]->IsExternal ())
1631- {
1632- auto ext = Local<External>::Cast (info[0 ]);
1629+ if (info.IsConstructCall ())
1630+ {
1631+ auto self = info.This ();
16331632
1634- Associated = reinterpret_cast <UObject*>(ext-> Value ());
1633+ UObject* Associated = nullptr ;
16351634
1636- if (!Associated->IsValidLowLevel ())
1635+ // Called by system (via ExportObject)
1636+ if (info.Length () == 1 && info[0 ]->IsExternal ())
16371637 {
1638- Associated = nullptr ;
1639- }
1640- }
1638+ auto ext = Local<External>::Cast (info[0 ]);
16411639
1642- // Called by user (via 'new' operator)
1643- if (!Associated)
1644- {
1645- const bool bIsJavascriptClass =
1646- ClassToExport->GetClass ()->IsChildOf (UJavascriptGeneratedClass::StaticClass ()) ||
1647- ClassToExport->GetClass ()->IsChildOf (UJavascriptGeneratedClass_Native::StaticClass ());
1640+ Associated = reinterpret_cast <UObject*>(ext->Value ());
16481641
1649- auto PreCreate = [&]() {
1650- if (bIsJavascriptClass)
1642+ if (!Associated->IsValidLowLevel ())
16511643 {
1652- GetSelf (isolate)-> ObjectUnderConstructionStack . Push ( FPendingClassConstruction (self, ClassToExport)) ;
1644+ Associated = nullptr ;
16531645 }
1654- };
1646+ }
16551647
1656- // Custom constructors
1657- if (ClassToExport-> IsChildOf ( AActor::StaticClass ()) )
1648+ // Called by user (via 'new' operator)
1649+ if (!Associated )
16581650 {
1659- if (info.Length () == 0 )
1660- {
1661- I.Throw (TEXT (" Missing world to spawn" ));
1662- return ;
1663- }
1651+ const bool bIsJavascriptClass =
1652+ ClassToExport->GetClass ()->IsChildOf (UJavascriptGeneratedClass::StaticClass ()) ||
1653+ ClassToExport->GetClass ()->IsChildOf (UJavascriptGeneratedClass_Native::StaticClass ());
16641654
1665- auto World = Cast<UWorld>(UObjectFromV8 (info[0 ]));
1666- if (!World)
1667- {
1668- I.Throw (TEXT (" Missing world to spawn" ));
1669- return ;
1670- }
1671-
1672- FVector Location (ForceInitToZero);
1673- FRotator Rotation (ForceInitToZero);
1674-
1675- UPackage* CoreUObjectPackage = UObject::StaticClass ()->GetOutermost ();
1676- static UScriptStruct* VectorStruct = FindObjectChecked<UScriptStruct>(CoreUObjectPackage, TEXT (" Vector" ));
1677- static UScriptStruct* RotatorStruct = FindObjectChecked<UScriptStruct>(CoreUObjectPackage, TEXT (" Rotator" ));
1678- static TStructReader<FVector> VectorReader (VectorStruct);
1679- static TStructReader<FRotator> RotatorReader (RotatorStruct);
1680-
1681- if (info.Length () > 1 )
1655+ auto PreCreate = [&]() {
1656+ if (bIsJavascriptClass)
1657+ {
1658+ GetSelf (isolate)->ObjectUnderConstructionStack .Push (FPendingClassConstruction (self, ClassToExport));
1659+ }
1660+ };
1661+
1662+ // Custom constructors
1663+ if (ClassToExport->IsChildOf (AActor::StaticClass ()))
16821664 {
1683- if (!VectorReader.Read (isolate, info[1 ], Location)) return ;
1665+ if (info.Length () == 0 )
1666+ {
1667+ I.Throw (TEXT (" Missing world to spawn" ));
1668+ return ;
1669+ }
16841670
1685- if (info.Length () > 2 )
1671+ auto World = Cast<UWorld>(UObjectFromV8 (info[0 ]));
1672+ if (!World)
16861673 {
1687- if (!RotatorReader.Read (isolate, info[2 ], Rotation)) return ;
1674+ I.Throw (TEXT (" Missing world to spawn" ));
1675+ return ;
16881676 }
1689- }
16901677
1691- PreCreate ();
1692- Associated = World->SpawnActor (ClassToExport, &Location, &Rotation);
1693- }
1694- else
1695- {
1696- UObject* Outer = GetTransientPackage ();
1697- FName Name = NAME_None;
1678+ FVector Location (ForceInitToZero);
1679+ FRotator Rotation (ForceInitToZero);
16981680
1699- if (info.Length () > 0 )
1700- {
1701- if (auto value = UObjectFromV8 (info[0 ]))
1681+ UPackage* CoreUObjectPackage = UObject::StaticClass ()->GetOutermost ();
1682+ static UScriptStruct* VectorStruct = FindObjectChecked<UScriptStruct>(CoreUObjectPackage, TEXT (" Vector" ));
1683+ static UScriptStruct* RotatorStruct = FindObjectChecked<UScriptStruct>(CoreUObjectPackage, TEXT (" Rotator" ));
1684+ static TStructReader<FVector> VectorReader (VectorStruct);
1685+ static TStructReader<FRotator> RotatorReader (RotatorStruct);
1686+
1687+ if (info.Length () > 1 )
17021688 {
1703- Outer = value;
1689+ if (!VectorReader.Read (isolate, info[1 ], Location)) return ;
1690+
1691+ if (info.Length () > 2 )
1692+ {
1693+ if (!RotatorReader.Read (isolate, info[2 ], Rotation)) return ;
1694+ }
17041695 }
1705- if (info.Length () > 1 )
1696+
1697+ PreCreate ();
1698+ Associated = World->SpawnActor (ClassToExport, &Location, &Rotation);
1699+ }
1700+ else
1701+ {
1702+ UObject* Outer = GetTransientPackage ();
1703+ FName Name = NAME_None;
1704+
1705+ if (info.Length () > 0 )
17061706 {
1707- Name = FName (*StringFromV8 (info[1 ]));
1707+ if (auto value = UObjectFromV8 (info[0 ]))
1708+ {
1709+ Outer = value;
1710+ }
1711+ if (info.Length () > 1 )
1712+ {
1713+ Name = FName (*StringFromV8 (info[1 ]));
1714+ }
17081715 }
1716+
1717+ PreCreate ();
1718+ Associated = NewObject<UObject>(Outer, ClassToExport, Name);
17091719 }
17101720
1711- PreCreate ();
1712- Associated = NewObject<UObject>(Outer, ClassToExport, Name);
1713- }
1721+ if (bIsJavascriptClass)
1722+ {
1723+ const auto & Last = GetSelf (isolate)-> ObjectUnderConstructionStack . Last ();
17141724
1715- if (bIsJavascriptClass)
1716- {
1717- const auto & Last = GetSelf (isolate)->ObjectUnderConstructionStack .Last ();
1725+ bool bSafeToQuit = Last.bCatched ;
17181726
1719- bool bSafeToQuit = Last. bCatched ;
1727+ GetSelf (isolate)-> ObjectUnderConstructionStack . Pop () ;
17201728
1721- GetSelf (isolate)->ObjectUnderConstructionStack .Pop ();
1729+ if (bSafeToQuit)
1730+ {
1731+ return ;
1732+ }
1733+ }
17221734
1723- if (bSafeToQuit )
1735+ if (!Associated )
17241736 {
1737+ I.Throw (TEXT (" Failed to spawn" ));
17251738 return ;
17261739 }
17271740 }
17281741
1729- if (!Associated)
1730- {
1731- I.Throw (TEXT (" Failed to spawn" ));
1732- return ;
1733- }
1734- }
1735-
1736- FPendingClassConstruction (self, ClassToExport).Finalize (GetSelf (isolate), Associated);
1742+ FPendingClassConstruction (self, ClassToExport).Finalize (GetSelf (isolate), Associated);
1743+ }
1744+ else
1745+ {
1746+ info.GetReturnValue ().Set (GetSelf (isolate)->C_Operator (ClassToExport, info[0 ]));
1747+ }
17371748 };
17381749
17391750 auto Template = I.FunctionTemplate (ConstructorBody, ClassToExport);
@@ -1801,24 +1812,31 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
18011812
18021813 FIsolateHelper I (isolate);
18031814
1804- auto self = info.This ();
1815+ if (info.IsConstructCall ())
1816+ {
1817+ auto self = info.This ();
18051818
1806- TSharedPtr<FStructMemoryInstance> Memory;
1807-
1808- if (info.Length () == 2 && info[0 ]->IsExternal () && info[1 ]->IsExternal ())
1809- {
1810- IPropertyOwner& Owner = *reinterpret_cast <IPropertyOwner*>(Local<External>::Cast (info[1 ])->Value ());
1819+ TSharedPtr<FStructMemoryInstance> Memory;
1820+
1821+ if (info.Length () == 2 && info[0 ]->IsExternal () && info[1 ]->IsExternal ())
1822+ {
1823+ IPropertyOwner& Owner = *reinterpret_cast <IPropertyOwner*>(Local<External>::Cast (info[1 ])->Value ());
1824+
1825+ Memory = FStructMemoryInstance::Create (StructToExport, Owner, Local<External>::Cast (info[0 ])->Value ());
1826+ }
1827+ else
1828+ {
1829+ Memory = FStructMemoryInstance::Create (StructToExport, FNoPropertyOwner ());
1830+ }
18111831
1812- Memory = FStructMemoryInstance::Create (StructToExport, Owner, Local<External>::Cast (info[0 ])->Value ());
1832+ GetSelf (isolate)->RegisterScriptStructInstance (Memory, self);
1833+
1834+ self->SetAlignedPointerInInternalField (0 , Memory.Get ());
18131835 }
18141836 else
18151837 {
1816- Memory = FStructMemoryInstance::Create ( StructToExport, FNoPropertyOwner ( ));
1838+ info. GetReturnValue (). Set ( GetSelf (isolate)-> C_Operator ( StructToExport, info[ 0 ] ));
18171839 }
1818-
1819- GetSelf (isolate)->RegisterScriptStructInstance (Memory, self);
1820-
1821- self->SetAlignedPointerInInternalField (0 , Memory.Get ());
18221840 };
18231841
18241842 auto Template = I.FunctionTemplate (fn, StructToExport);
0 commit comments