ChangeCurrentElement() question

Just starting out? Need help? Post your questions and find answers here.
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

ChangeCurrentElement() question

Post by Lunasole »

Hi.

I have some question about how ChangeCurrentElement() works.
It searches list item like map/hashtable does that (and which is fast), or just bruteforces some internal list of item pointers?
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: ChangeCurrentElement() question

Post by nco2k »

neither. the *NewElement parameter is a pointer to the elements address. it doesnt search anything. it just "jumps" to that position. it cant get any faster than that.

also, depending on what you are trying to do, you may not even need ChangeCurrentElement(). but thats some of the more advanced stuff. :)

Code: Select all

Structure MyStructure
  Foo.b
  Bar.b
EndStructure

NewList MyList.MyStructure()

AddElement(MyList())
MyList()\Foo = 1
MyList()\Bar = 2
*FirstElement.MyStructure = @MyList()

AddElement(MyList())
MyList()\Foo = 3
MyList()\Bar = 4
*LastElement.MyStructure = @MyList()

Debug *FirstElement\Foo
Debug *FirstElement\Bar
Debug *LastElement\Foo
Debug *LastElement\Bar

Debug ""

*FirstElement\Foo = 5
*FirstElement\Bar = 6
*LastElement\Foo = 7
*LastElement\Bar = 8

ForEach MyList()
  Debug MyList()\Foo
  Debug MyList()\Bar
Next
c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: ChangeCurrentElement() question

Post by Lunasole »

nco2k wrote:neither. the *NewElement parameter is a pointer to the elements address. it doesnt search anything. it just "jumps" to that position. it cant get any faster than that.
Hah, I shouldn't ask such stupid things ^^
Just was too tired to do simplest checks with ShowMemoryViewer() + forgotten that already checked similar stuff about list internals ~1 year ago.
Anyway thanks
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
mestnyi
Addict
Addict
Posts: 1001
Joined: Mon Nov 25, 2013 6:41 am

Re: ChangeCurrentElement() question

Post by mestnyi »

Why "ChangeCurrentElement" does not it return the address?

Code: Select all

Structure Struct
  a.i
  b.s
EndStructure

NewList ThisList.Struct()

ChangeCurrentElement(ThisList(), GetGadgetData(Gadget))
*This.Struct = @ThisList()

If *This
  With *This
    ForEach ThisList()
      If ThisList()\a = \a
        Debug ThisList()\b
      EndIf
    Next
  EndWith
EndIf
You could use the same map

Code: Select all

*This.Struct = ChangeCurrentElement(ThisList(), GetGadgetData(Gadget))

Code: Select all

*This.Struct = FindMapElement(ThisList(), Str(GetGadgetData(Gadget)))
User avatar
Demivec
Addict
Addict
Posts: 4091
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: ChangeCurrentElement() question

Post by Demivec »

mestnyi wrote:Why "ChangeCurrentElement" does not it return the address?

Code: Select all

Structure Struct
  a.i
  b.s
EndStructure

NewList ThisList.Struct()

ChangeCurrentElement(ThisList(), GetGadgetData(Gadget))
*This.Struct = @ThisList()

If *This
  With *This
    ForEach ThisList()
      If ThisList()\a = \a
        Debug ThisList()\b
      EndIf
    Next
  EndWith
EndIf
You could use the same map

Code: Select all

*This.Struct = ChangeCurrentElement(ThisList(), GetGadgetData(Gadget))

Code: Select all

*This.Struct = FindMapElement(ThisList(), Str(GetGadgetData(Gadget)))
Why wouldn't you just use

Code: Select all

element = GetGadgetData(Gadget) 
ChangeCurrentElement(ThisList(), element)
*This.Struct = element
Last edited by Demivec on Tue Dec 19, 2017 7:00 am, edited 1 time in total.
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: ChangeCurrentElement() question

Post by nco2k »

@mestnyi
because you already know the address. FindMapElement() has to search for the element. same goes for SelectElement(), which btw also returns the address.

your code doesnt make any sense. you jump to an element and then you loop through the whole list? that destroys the whole purpose of ChangeElement() and pointers. if you dont understand how that stuff works, its best not to use it. you will only make your life difficult, by having to debug something you dont really understand.

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
mestnyi
Addict
Addict
Posts: 1001
Joined: Mon Nov 25, 2013 6:41 am

Re: ChangeCurrentElement() question

Post by mestnyi »

Why wouldn't you just use

Code: Select all

element = GetGadgetData(Gadget) 
ChangeCurrentElement(ThisList(), element)
*This.Struct = element
Because it's so beautiful and lighter.

Code: Select all

*This.Struct = ChangeCurrentElement(ThisList(), GetGadgetData(Gadget))
your code doesnt make any sense. you jump to an element and then you loop through the whole list?
Why does this make no sense?

Code: Select all

Structure Struct
  a.i
  b.s
EndStructure

NewList ThisList.Struct()

ChangeCurrentElement(ThisList(), GetGadgetData(Gadget))
*This.Struct = @ThisList()

;
; - code
;

Select EventType()
  Case #PB_EventType_LeftClick
    If *This
      With *This
        \a!1
        ForEach ThisList()
          If \a
            ThisList()\b = \b
            
          EndIf
        Next
      EndWith
    EndIf
EndSelect
User avatar
HeX0R
Addict
Addict
Posts: 992
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: ChangeCurrentElement() question

Post by HeX0R »

mestnyi wrote: Why does this make no sense?

Code: Select all

ChangeCurrentElement(ThisList(), GetGadgetData(Gadget))
*This.Struct = @ThisList()
Because anyone would do it like this:

Code: Select all

*This.Struct = GetGadgetData(Gadget)
There is no need for ChangeCurrentElement() in your example.
mestnyi
Addict
Addict
Posts: 1001
Joined: Mon Nov 25, 2013 6:41 am

Re: ChangeCurrentElement() question

Post by mestnyi »

HeX0R wrote:There is no need for ChangeCurrentElement() in your example.
:D :) :lol:
What are you talking about?
Here's a working example of your solution.

Code: Select all

; Here's a live example

EnableExplicit

Global Window_0=-1

Declare Window_0_Events(Event.i)

Procedure Window_0_CallBack()
  Window_0_Events(Event())
EndProcedure

;-
EnumerationBinary Prop
  #Spin
  #String
  #ComboBox
  #Button
EndEnumeration

Structure PropGadgetsStruct
  Window.i
  String.i
  Button.i
  ComboBox.i
  Spin.i
EndStructure

Structure PropStruct
  State.b
  Canvas.i
  Y.i
  iY.i
  Height.i
  Parent.i
  Gadget.PropGadgetsStruct
EndStructure

Global NewList Prop.PropStruct()

Procedure CallBack()
  Select EventType()
    Case #PB_EventType_LeftClick
       ChangeCurrentElement(Prop(), GetGadgetData(EventGadget())) : Protected *This.PropStruct = @Prop() ; comment
;       Protected *This.PropStruct = GetGadgetData(EventGadget()) ; uncomment
      
      If *This
        With *This
          \State!1
          
          If \State
            ResizeGadget( \Canvas, #PB_Ignore, #PB_Ignore, #PB_Ignore, \iY)
          Else
            ResizeGadget( \Canvas, #PB_Ignore, #PB_Ignore, #PB_Ignore, \iY+\Height)
          EndIf
          
          PushListPosition(Prop())
          While NextElement(Prop()) 
            If \State
              ResizeGadget( Prop()\Canvas, #PB_Ignore, GadgetY(Prop()\Canvas)-\Height, #PB_Ignore, #PB_Ignore)
            Else
              ResizeGadget( Prop()\Canvas, #PB_Ignore, GadgetY(Prop()\Canvas)+\Height, #PB_Ignore, #PB_Ignore)
            EndIf
          Wend
          PopListPosition(Prop())
        EndWith
      EndIf
      
  EndSelect
EndProcedure

Procedure Gadget()
  Protected ScrollArea_0
  
  ScrollArea_0 = ScrollAreaGadget(#PB_Any, 5, 5, 236, 446, 236-21, 456, 0)
  CloseGadgetList()
  
  ProcedureReturn ScrollArea_0
EndProcedure

Procedure Row(Gadget, Caption.s, Height=40)
  Static Index : Index+1
  Protected iY, iWidth, iHeight, Button_0, Container_0
  
  If IsGadget(Gadget) And OpenGadgetList(Gadget)
    If ListSize(Prop()) 
      LastElement(Prop()) 
      iY = Prop()\Y+Prop()\Height 
    EndIf
    iWidth = GetGadgetAttribute(Gadget, #PB_ScrollArea_InnerWidth)
    iHeight = GetGadgetAttribute(Gadget, #PB_ScrollArea_InnerHeight)
    
    Button_0 = CanvasGadget(#PB_Any, 0, iY, iWidth, Height, #PB_Canvas_Container) : CloseGadgetList()
    
    AddElement(Prop())
    With Prop()
      \Parent = Gadget
      \Canvas = Button_0
      \iY = Height
      \Y = \iY+iY
    EndWith
    
    If StartDrawing(CanvasOutput(Button_0))
      Box(0,0,iWidth,Height)
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(1,1,iWidth-2,Height-2,0)
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawText(20,(Height-TextHeight("A"))/2, Caption, 0)
      StopDrawing()
    EndIf
    
    SetGadgetData(Button_0, @Prop())
    BindGadgetEvent(Button_0, @CallBack())
  EndIf
  
  ProcedureReturn Index
EndProcedure

Procedure Item(Gadget, Caption.s, Type, Flag, Height=21)
  Protected iWidth, iHeight
  Protected b=18
  
  With Prop()
    If IsGadget(\Canvas) And OpenGadgetList(\Canvas)
      iWidth = GadgetWidth(\Canvas)
      
      If Type&#String
        If Type&#Button
          \Gadget\String = StringGadget(#PB_Any, 0,\iY+\Height,iWidth-b, Height, "") 
          \Gadget\Button = ButtonGadget(#PB_Any, iWidth-b,\iY+\Height,b, Height, "...") 
        Else
          \Gadget\String = StringGadget(#PB_Any, 0,\iY+\Height,iWidth, Height, "") 
        EndIf
      EndIf
      
      If Type&#Spin
        \Gadget\Spin = SpinGadget(#PB_Any, 0,\iY+\Height,iWidth, Height, -65535, 65535, #PB_Spin_Numeric)
      EndIf
      
      If Type&#ComboBox
        \Gadget\ComboBox = ComboBoxGadget(#PB_Any, 0,\iY+\Height,iWidth, Height)
      EndIf
      
      \Height+Height
      
      ResizeGadget(\Canvas, #PB_Ignore, #PB_Ignore, #PB_Ignore, \iY+\Height)
      
    EndIf 
  EndWith
  
EndProcedure

Procedure Add(Gadget, Caption.s, Type=0, Flag=0, Height=0)
  Protected Result
  
  If Type
    If Not ListSize(Prop()) Or (ListSize(Prop()) And Gadget <> Prop()\Parent)
      Row(Gadget, "", 0)
    EndIf
    
    If Height = 0 : Height = 19 : EndIf
    Result = Item(Gadget, Caption.s, Type, Flag, Height)
  Else
    If Height = 0 : Height = 32 : EndIf
    Result = Row(Gadget, Caption.s, Height)
  EndIf
  
  ProcedureReturn Result
EndProcedure

Procedure Window_0_Open(ParentID.i=0, Flag.i=#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  If IsWindow(Window_0)
    SetActiveWindow(Window_0)
    ProcedureReturn Window_0
  EndIf
  
  Window_0 = OpenWindow(#PB_Any, 10, 30, 246, 456, "Window_0", Flag, ParentID)
  Protected ScrollArea_0 = Gadget()
  ;   Add(ScrollArea_0, "Main")
  Add(ScrollArea_0, "ID:", #String)
  Add(ScrollArea_0, "Text:", #String)
  
  Add(ScrollArea_0, "Layouts")
  Add(ScrollArea_0, "X:", #Spin)
  Add(ScrollArea_0, "Y:", #Spin)
  Add(ScrollArea_0, "Width:", #Spin)
  Add(ScrollArea_0, "Height:", #Spin)
  Add(ScrollArea_0, "Pach:", #String|#Button)
  
  Add(ScrollArea_0, "Other")
  Add(ScrollArea_0, "Hide:", #ComboBox)
  Add(ScrollArea_0, "Disable:", #ComboBox)
  
  ProcedureReturn Window_0
EndProcedure

Procedure Window_0_Events(Event.i)
  Select Event
    Case #PB_Event_Gadget
      Select EventType()
        Case #PB_EventType_LeftClick
          Select EventGadget()
              
          EndSelect
      EndSelect
  EndSelect
  
  ProcedureReturn Event
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
  Window_0_Open()
  
  While IsWindow(Window_0)
    Define.i Event = WaitWindowEvent()
    
    Select EventWindow()
      Case Window_0
        If Window_0_Events( Event ) = #PB_Event_CloseWindow
          CloseWindow(Window_0)
          Break
        EndIf
        
    EndSelect
  Wend
CompilerEndIf
Post Reply