@@ -1468,6 +1468,33 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
1468
1468
Template->Set (I.Keyword (" Load" ), I.FunctionTemplate (fn, ClassToExport));
1469
1469
}
1470
1470
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
+
1471
1498
void AddMemberFunction_Struct_C (Local<FunctionTemplate> Template, UStruct* StructToExport)
1472
1499
{
1473
1500
FIsolateHelper I (isolate_);
@@ -1479,30 +1506,7 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
1479
1506
1480
1507
if (info.Length () == 1 )
1481
1508
{
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 ]));
1506
1510
}
1507
1511
};
1508
1512
@@ -1622,118 +1626,125 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
1622
1626
1623
1627
auto ClassToExport = reinterpret_cast <UClass*>((Local<External>::Cast (info.Data ()))->Value ());
1624
1628
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 ();
1633
1632
1634
- Associated = reinterpret_cast <UObject*>(ext-> Value ());
1633
+ UObject* Associated = nullptr ;
1635
1634
1636
- if (!Associated->IsValidLowLevel ())
1635
+ // Called by system (via ExportObject)
1636
+ if (info.Length () == 1 && info[0 ]->IsExternal ())
1637
1637
{
1638
- Associated = nullptr ;
1639
- }
1640
- }
1638
+ auto ext = Local<External>::Cast (info[0 ]);
1641
1639
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 ());
1648
1641
1649
- auto PreCreate = [&]() {
1650
- if (bIsJavascriptClass)
1642
+ if (!Associated->IsValidLowLevel ())
1651
1643
{
1652
- GetSelf (isolate)-> ObjectUnderConstructionStack . Push ( FPendingClassConstruction (self, ClassToExport)) ;
1644
+ Associated = nullptr ;
1653
1645
}
1654
- };
1646
+ }
1655
1647
1656
- // Custom constructors
1657
- if (ClassToExport-> IsChildOf ( AActor::StaticClass ()) )
1648
+ // Called by user (via 'new' operator)
1649
+ if (!Associated )
1658
1650
{
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 ());
1664
1654
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 ()))
1682
1664
{
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
+ }
1684
1670
1685
- if (info.Length () > 2 )
1671
+ auto World = Cast<UWorld>(UObjectFromV8 (info[0 ]));
1672
+ if (!World)
1686
1673
{
1687
- if (!RotatorReader.Read (isolate, info[2 ], Rotation)) return ;
1674
+ I.Throw (TEXT (" Missing world to spawn" ));
1675
+ return ;
1688
1676
}
1689
- }
1690
1677
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);
1698
1680
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 )
1702
1688
{
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
+ }
1704
1695
}
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 )
1706
1706
{
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
+ }
1708
1715
}
1716
+
1717
+ PreCreate ();
1718
+ Associated = NewObject<UObject>(Outer, ClassToExport, Name);
1709
1719
}
1710
1720
1711
- PreCreate ();
1712
- Associated = NewObject<UObject>(Outer, ClassToExport, Name);
1713
- }
1721
+ if (bIsJavascriptClass)
1722
+ {
1723
+ const auto & Last = GetSelf (isolate)-> ObjectUnderConstructionStack . Last ();
1714
1724
1715
- if (bIsJavascriptClass)
1716
- {
1717
- const auto & Last = GetSelf (isolate)->ObjectUnderConstructionStack .Last ();
1725
+ bool bSafeToQuit = Last.bCatched ;
1718
1726
1719
- bool bSafeToQuit = Last. bCatched ;
1727
+ GetSelf (isolate)-> ObjectUnderConstructionStack . Pop () ;
1720
1728
1721
- GetSelf (isolate)->ObjectUnderConstructionStack .Pop ();
1729
+ if (bSafeToQuit)
1730
+ {
1731
+ return ;
1732
+ }
1733
+ }
1722
1734
1723
- if (bSafeToQuit )
1735
+ if (!Associated )
1724
1736
{
1737
+ I.Throw (TEXT (" Failed to spawn" ));
1725
1738
return ;
1726
1739
}
1727
1740
}
1728
1741
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
+ }
1737
1748
};
1738
1749
1739
1750
auto Template = I.FunctionTemplate (ConstructorBody, ClassToExport);
@@ -1801,24 +1812,31 @@ class FJavascriptIsolateImplementation : public FJavascriptIsolate
1801
1812
1802
1813
FIsolateHelper I (isolate);
1803
1814
1804
- auto self = info.This ();
1815
+ if (info.IsConstructCall ())
1816
+ {
1817
+ auto self = info.This ();
1805
1818
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
+ }
1811
1831
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 ());
1813
1835
}
1814
1836
else
1815
1837
{
1816
- Memory = FStructMemoryInstance::Create ( StructToExport, FNoPropertyOwner ( ));
1838
+ info. GetReturnValue (). Set ( GetSelf (isolate)-> C_Operator ( StructToExport, info[ 0 ] ));
1817
1839
}
1818
-
1819
- GetSelf (isolate)->RegisterScriptStructInstance (Memory, self);
1820
-
1821
- self->SetAlignedPointerInInternalField (0 , Memory.Get ());
1822
1840
};
1823
1841
1824
1842
auto Template = I.FunctionTemplate (fn, StructToExport);
0 commit comments