Announcement

Collapse
No announcement yet.

Nested class constructor

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    Nested class constructor

    Howdy!
    Native programing is more nasty than I thought. So I came across the nested class definition (in SScissorRectBox.h)
    Code:
    class SLATE_API SScissorRectBox : public SPanel
    {
    
    public:
        class FScissorRectSlot : public TSupportsOneChildMixin<FScissorRectSlot>
        {
        public:
            FScissorRectSlot(SWidget* InOwner)
                : TSupportsOneChildMixin<FScissorRectSlot>(InOwner)
            {}
        };
    
        SLATE_BEGIN_ARGS(SScissorRectBox)
        {
            _Visibility = EVisibility::SelfHitTestInvisible;
            _Clipping = EWidgetClipping::ClipToBounds;
        }
            SLATE_DEFAULT_SLOT(FArguments, Content)
        SLATE_END_ARGS()
    
        void Construct( const FArguments& InArgs );
    
        /**
         * See the Content slot.
         */
        void SetContent(const TSharedRef< SWidget >& InContent);
    
    private:
        virtual FVector2D ComputeDesiredSize(float) const override;
        virtual void OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const override;
        virtual FChildren* GetChildren() override;
        virtual int32 OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const override;
    
        FScissorRectSlot ChildSlot;
    };
    for which the object declaration in the following fashion
    Code:
    TSharedPtr<SScissorRectBox> ScissorRectBox = SNew(SScissorRectBox)[RebuildListWidget()];
    where RebuildListWidget() is declared as
    Code:
    virtual TSharedRef<SListView<UObject*>> RebuildListWidget();
    yields the error
    Code:
    default constructor of 'SScissorRectBox' is implicitly deleted because field 'ChildSlot' has no default constructor
    
    FScissorRectSlot ChildSlot;
    Now it makes me think that the additional lines
    Code:
    class FScissorRectSlot : public TSupportsOneChildMixin<FScissorRectSlot>
        {
        public:
            FScissorRectSlot(SWidget* InOwner)
                : TSupportsOneChildMixin<FScissorRectSlot>(InOwner)
            {}
           FScissorRectSlot()
           {}
        };
    should rectify the error. I haven't compiled the code because it means changing the Engine code. Just looking for the second opinion
    Last edited by The-Cowboy; 05-22-2019, 09:54 AM.
    https://ravimohan.net/
    https://github.com/ravimohan1991

    #2
    Simplest way is just add default value (of course if implementation provide support for handling nullptr as owner, but anyway pointer initialized with nullptr is always better than non-initialized pointer)
    Code:
    FScissorRectSlot(SWidget* InOwner = nullptr)

    Comment


      #3
      Cool, I will try that and report how it goes. Thanks!

      Edit:
      Oops, didn't see the data type in hurry. Do you mean to replace the
      Code:
      TSharedPtr<SScissorRectBox> ScissorRectBox = SNew(SScissorRectBox)[RebuildListWidget()];
      with
      Code:
      FScissorRectSlot(SWidget* InOwner = nullptr)
      ?
      Last edited by The-Cowboy; 05-25-2019, 07:32 PM.
      https://ravimohan.net/
      https://github.com/ravimohan1991

      Comment


        #4
        So, I could not resolve the error. Perhaps, I should report the error with different angle. Right now I am using the following declaration
        Code:
        TSharedPtr<SScissorRectBox> ScissorRectBox = SNew(SScissorRectBox)[SScissorRectBox::FScissorRectSlot(nullptr), RebuildListWidget()];
        with the hope that the nested class FScissorRectSlot will pick the nullptr for constructor purpose (I am assuming anything in the square brackets means arguments for SNew method).

        The sequence/cluster of errors spit is
        Code:
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/Core/Public/Templates/SharedPointerInternals.h:135:32: error: call to implicitly-deleted default constructor of 'SScissorRectBox'
        
        new ((void*)&ObjectStorage) ObjectType(Forward<ArgTypes>(Args)...);
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/Core/Public/Templates/SharedPointerInternals.h:186:14: note: in instantiation of function template specialization 'SharedPointerInternals::TIntrusiveReferenceController<SScissorRectBox>::TIntrusiveReferenceController<>' requested here
        
        return new TIntrusiveReferenceController<ObjectType>(Forward<ArgTypes>(Args)...);
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/Core/Public/Templates/SharedPointer.h:1692:108: note: in instantiation of function template specialization 'SharedPointerInternals::NewIntrusiveReferenceController<SScissorRectBox>' requested here
        
        SharedPointerInternals::TIntrusiveReferenceController<InObjectType>* Controller = SharedPointerInternals::NewIntrusiveReferenceController<InObjectType>(Forward<InArgTypes>(Args)...);
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/SlateCore/Public/Widgets/DeclarativeSyntaxSupport.h:1001:10: note: in instantiation of function template specialization 'MakeShared<SScissorRectBox, ESPMode::NotThreadSafe>' requested here
        
        return MakeShared<WidgetType>();
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/SlateCore/Public/Widgets/DeclarativeSyntaxSupport.h:1034:97: note: in instantiation of member function 'TWidgetAllocator<SScissorRectBox, false>::PrivateAllocateWidget' requested here
        
        : _Widget( TWidgetAllocator<WidgetType, TIsDerivedFrom<WidgetType, SUserWidget>::IsDerived >::PrivateAllocateWidget() )
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/SlateCore/Public/Widgets/DeclarativeSyntaxSupport.h:1111:9: note: in instantiation of member function 'TDecl<SScissorRectBox, RequiredArgs::T0RequiredArgs>::TDecl' requested here
        
        return TDecl<WidgetType, RequiredArgsPayloadType>(InType, InFile, OnLine, Forward<RequiredArgsPayloadType>(InRequiredArgs));
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealProjects/UnrealTournament/Source/UnrealTournament/Public/UMG/UTListView.cpp:48:50: note: in instantiation of function template specialization 'MakeTDecl<SScissorRectBox, RequiredArgs::T0RequiredArgs>' requested here
        
        TSharedPtr<SScissorRectBox> ScissorRectBox = SNew(SScissorRectBox)[SScissorRectBox::FScissorRectSlot(nullptr), RebuildListWidget()];
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/SlateCore/Public/Widgets/DeclarativeSyntaxSupport.h:33:2: note: expanded from macro 'SNew'
        
        MakeTDecl<WidgetType>( #WidgetType, __FILE__, __LINE__, RequiredArgs::MakeRequiredArgs(__VA_ARGS__) ) <<= TYPENAME_OUTSIDE_TEMPLATE WidgetType::FArguments()
        
        ^
        
        /home/the_cowboy/unrealworks/UnrealEngine/Engine/Source/Runtime/Slate/Public/Widgets/Layout/SScissorRectBox.h:63:19: note: default constructor of 'SScissorRectBox' is implicitly deleted because field 'ChildSlot' has no default constructor
        
        FScissorRectSlot ChildSlot;
        Since we are on that, I was wondering if I can get the "parsing" of the method definition (in DeclarativeSupportSyntax.h)
        Code:
        /**
         * Slate widgets are constructed through SNew and SAssignNew.
         * e.g.
         *      
         *     TSharedRef<SButton> MyButton = SNew(SButton);
         *        or
         *     TSharedPtr<SButton> MyButton;
         *     SAssignNew( MyButton, SButton );
         *
         * Using SNew and SAssignNew ensures that widgets are populated
         */
        
        #define SNew( WidgetType, ... ) \
            MakeTDecl<WidgetType>( #WidgetType, __FILE__, __LINE__, RequiredArgs::MakeRequiredArgs(__VA_ARGS__) ) <<= TYPENAME_OUTSIDE_TEMPLATE WidgetType::FArguments()
        Especially what do '\', '<<==' refer to here?
        https://ravimohan.net/
        https://github.com/ravimohan1991

        Comment


          #5
          \ at end of line means the define continues into the next line

          Comment


            #6
            Cool, thanks. But why new line is needed. Is it a text aesthetics thingy (if true it certainly beats the purpose).
            https://ravimohan.net/
            https://github.com/ravimohan1991

            Comment


              #7
              Bump! It'd be really a learning step for me if I get the right interpretation of the code in post #4. Especially what do the square brackets [ ] represent. Another live example is at https://github.com/EpicGames/UnrealT...idgetFactory.h line 180.
              https://ravimohan.net/
              https://github.com/ravimohan1991

              Comment


                #8
                Originally posted by The-Cowboy View Post
                Cool, thanks. But why new line is needed. Is it a text aesthetics thingy (if true it certainly beats the purpose).
                The \ will be always used to tell the compiler that what comes next should be handled as if it will continue in the same line. The purpose is just to make the text clear and it can be used for macros (#define) and also to tell that a string should me merged if used like:

                ... "string x" \
                "still string x"
                Nilson Lima
                Technical Director @ Rigel Studios Ltda - twitter: @RigelStudios
                Join us at Discord: https://discord.gg/uFFSEXY

                UE4 Marketplace: Cloudscape Seasons
                supporting: Community FREE Ocean plugin

                Comment


                  #9
                  Originally posted by The-Cowboy View Post
                  Bump! It'd be really a learning step for me if I get the right interpretation of the code in post #4. Especially what do the square brackets [ ] represent. Another live example is at https://github.com/EpicGames/UnrealT...idgetFactory.h line 180.
                  Those brackets without looking at the code tells me the operator[] is overloaded, then we should look at the definition for the overload operation and analyse whats happening there. I just passed by this thread, just giving the hint, not sure I will handle some time to look at.
                  Nilson Lima
                  Technical Director @ Rigel Studios Ltda - twitter: @RigelStudios
                  Join us at Discord: https://discord.gg/uFFSEXY

                  UE4 Marketplace: Cloudscape Seasons
                  supporting: Community FREE Ocean plugin

                  Comment


                    #10
                    You should be able to do this:

                    Code:
                        TSharedRef<SBox> MyBox = SNew(SBox);
                    
                        TSharedPtr<SScissorRectBox> ScissorRectBox = SNew(SScissorRectBox)
                        .Content()
                        [
                            MyBox
                        ];
                    However to me seems like that "SScissorRectBox" class is incomplete.
                    The Construct() function should deal with this stuff by itself since "FScissorRectSlot" constructor won't get called by SScissorRectBox's default.
                    | Finite State Machine | Savior | USQLite | Object-Pool | Sound-Occlusion | Property Transfer | Magic Nodes | MORE |

                    Comment


                      #11
                      Thanks Lima and XaVIeR for the helpful posts. The "SScissorRectBox" is indeed incomplete, I might probably open a pull request (I am not positive because Epic didn't accept my last request, but hey, world is based on hope).
                      https://ravimohan.net/
                      https://github.com/ravimohan1991

                      Comment


                        #12
                        Don't stop contributing just because the last thing wasn't accepted. :-D

                        Comment


                          #13
                          Done https://github.com/EpicGames/UnrealEngine/pull/5989
                          https://ravimohan.net/
                          https://github.com/ravimohan1991

                          Comment


                            #14
                            The slot has to be passed a valid parent the issue is a missing constructor in SScissorRectBox:
                            SScissorRectBox::SScissorRectBox() :ChildSlot(this) {}
                            I've added this in CL 7282470 it will be in 4.24

                            In the PR discussion there were also question about it wrt to dealing directly with slots.
                            This just isn't the way Slate intends you to work with slots it's implementation attempts to keep protect the user from some details here.

                            Comment

                            Working...
                            X