Question about object oriented dot notation style in FB

New to FreeBASIC? Post your questions here.
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: Question about object oriented dot notation style in FB

Post by kcvinu »

@Tourist Trap,
Excellent explanation.. Thanks. Clearly understood.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Question about object oriented dot notation style in FB

Post by Tourist Trap »

Unfortunately it doesn't help too much here (repost):

Code: Select all

  type Y
   as integer Moon(1)
end type

type X extends Y
   declare property Moon(as integer)
   declare property Moon(Index as integer) as integer
   
End Type
property X.Moon(GetValue as integer)
   BASE.Moon(1) = GetValue
end property
property X.Moon(Index as integer) as integer
   return BASE.Moon(1)
end property


dim as X  xxx

? xxx.Moon(0)   'crash win10 64
? (xxx.Moon)(0)   'error 193: PROPERTY has no GET method/accessor


sleep
:)
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: Question about object oriented dot notation style in FB

Post by kcvinu »

@paul doe,
There is a big obstacle i have in this approach. I need to pass the combo box's handle to the ItemsClass to call the sendmessage function. When user puts an item to Items collection, they also want the item appear in the combo. For that, i need to send the ADDSTRING message to combo right after adding an item to Items collection. When i realized this problem the first thing i thought about was events. Is there any event i can raise so that this ItemsClass will get the handle of the combo box ?. After a few minutes, i realized that i am making things too complex.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Question about object oriented dot notation style in FB

Post by Josep Roca »

> After a few minutes, i realized that i am making things too complex.

Quite sure. For what you need to manage a collection of items when the combobox control already does it?
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Question about object oriented dot notation style in FB

Post by paul doe »

kcvinu wrote:...
After a few minutes, i realized that i am making things too complex.
Indeed you are. Are you implementing your own event based programming, or you're doing this through Windows API? There's no notion of 'events' in FB, but you can easily code it yourself through callbacks:

Code: Select all

/'	Simple example showing how to implement callbacks for an object method
		
		A callback is some function that gets injected into the object via a function pointer,
		so the function can be called from inside it.
		
		This is very useful, for example, to implement events (the callback function is the
		event handler). In this example, an event is invoked whenever the property "pName" gets changed '/
#ifdef class
	#undef class
	#define class type
#endif

'' simple typedef to pass parameters to the callback
type nameEventArgs
	public:
		declare constructor( byref oldN as const string )
		
		'' no need to make the members private
		as string oldName
	
	private:
		declare constructor()
end type

constructor nameEventArgs( byref oldN as const string )
	oldName = oldN
end constructor

/'	The class definition for an object. It only has a property, and a setter for installing
		the event handler '/
class SomeObject extends object
	public:		
		declare constructor( byref objName as const string )
		declare destructor()
		
		declare property pName() byref as const string
		declare property pName( byref newName as const string )
		
		declare sub setNameChangedCallback( byval cb as sub( byval instance as someObject ptr, byval e as nameEventArgs ptr ) )
		
	private:
		declare constructor()
		
		'' this var, once set, can be used just like any regular function
		m_pNameChangedCallback as sub( byval instance as someObject ptr, byval e as nameEventArgs ptr )
		as string m_name
end type

constructor SomeObject( byref objName as const string )
	if( objName = "" ) then
		m_name = "unknown"
	else
		m_name = objName
	end if
	
	? m_name & " created."
end constructor

destructor SomeObject()
	? m_name & " destroyed"
end destructor

property SomeObject.pName() byref as const string
	return( m_name )
end property

property SomeObject.pName( byref newName as const string )
	if( newName <> m_name ) then
		dim as nameEventArgs param = nameEventArgs( m_name )
		m_name = newName
		
		'' it's important to check if the callback is really there, otherwise the code will
		'' unceremoniously crash
		if( m_pNameChangedCallback <> 0 ) then
			'' the function gets invoked in the usual way, and passed this instance and some parameter ptrs
			m_pNameChangedCallback( @this, @param )
		end if
	end if
end property

sub SomeObject.setNameChangedCallback( byval cb as sub( byval instance as someObject ptr, byval e as nameEventArgs ptr ) )
	'' sets the var to hold a pointer to the callback function
	m_pNameChangedCallback = cb
end sub

sub nameChangedHandler( byval instance as someObject ptr, byval e as nameEventArgs ptr )
	'' this callback function is invoked whenever the 'name' property changes
	'' in other words, it acts as an event handler for a "NameChanged" like event
	? e->oldName & " name has changed. Its new name is: " & instance->pName  
end sub

/'
	And now for some trivial test code
'/
'' instantiate an object
dim as SomeObject o = SomeObject( "John" )

'' set the callback for this object with the addressOf (@) operator
o.setNameChangedCallback( @nameChangedHandler )

'' and whenever the property 'pName' is changed, it invokes the callback function.
o.pName = "Paul"
o.pName = "Jenny"

sleep()
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Question about object oriented dot notation style in FB

Post by fxm »

Tourist Trap wrote:Unfortunately it doesn't help too much here (repost)
No bug on the first PRINT:

Code: Select all

type Y
   as integer Moon(1) = {1, 2}
end type

type X extends Y
   declare property Moon(as integer)
   declare property Moon(Index as integer) as integer
   
End Type
property X.Moon(GetValue as integer)
   BASE.Moon(1) = GetValue
end property
property X.Moon(Index as integer) as integer
   return BASE.Moon(1)
end property


dim as X  xxx

? xxx.Moon(0)   'crash win10 64
'? (xxx.Moon)(0)   'error 193: PROPERTY has no GET method/accessor


sleep
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Question about object oriented dot notation style in FB

Post by Tourist Trap »

paul doe wrote:
A callback is some function that gets injected into the object via a function pointer,
so the function can be called from inside it.

This is very useful, for example, to implement events (the callback function is the
event handler). In this example, an event is invoked whenever the property "pName" gets changed
The definition and the example deserve a special mention. It explains this generally poorly explained stuff in a very effective way. Thanks.
fxm wrote:
No bug on the first PRINT
Can it be a problem with FBEDIT on win10 so?
Edit: no it crashes even if launched via a command line... weird.

Asm output, if of any use:

Code: Select all

 	.file	"q3ens).c"
	.intel_syntax noprefix
	.section .rdata,"dr"
.LC0:
	.ascii "q3ens).bas\0"
.LC1:
	.ascii "UNIVERSE\0"
	.text
	.globl	_ZN1X15UNIVERSE__set__Eu7INTEGER
	.def	_ZN1X15UNIVERSE__set__Eu7INTEGER;	.scl	2;	.type	32;	.endef
_ZN1X15UNIVERSE__set__Eu7INTEGER:
	push	rbp
	mov	rbp, rsp
	sub	rsp, 64
	mov	QWORD PTR 16[rbp], rcx
	mov	QWORD PTR 24[rbp], rdx
.L2:
	lea	rcx, .LC0[rip]
	call	fb_ErrorSetModName
	mov	QWORD PTR -8[rbp], rax
	mov	rax, QWORD PTR -8[rbp]
	mov	QWORD PTR -16[rbp], rax
	lea	rcx, .LC1[rip]
	call	fb_ErrorSetFuncName
	mov	QWORD PTR -24[rbp], rax
	mov	rax, QWORD PTR -24[rbp]
	mov	QWORD PTR -32[rbp], rax
	mov	rax, QWORD PTR 16[rbp]
	lea	rdx, 8[rax]
	mov	rax, QWORD PTR 24[rbp]
	mov	QWORD PTR [rdx], rax
.L3:
	mov	rax, QWORD PTR -32[rbp]
	mov	rcx, rax
	call	fb_ErrorSetFuncName
	mov	rax, QWORD PTR -16[rbp]
	mov	rcx, rax
	call	fb_ErrorSetModName
	nop
	leave
	ret
	.globl	_ZN1X15UNIVERSE__get__Eu7INTEGER
	.def	_ZN1X15UNIVERSE__get__Eu7INTEGER;	.scl	2;	.type	32;	.endef
_ZN1X15UNIVERSE__get__Eu7INTEGER:
	push	rbp
	mov	rbp, rsp
	sub	rsp, 80
	mov	QWORD PTR 16[rbp], rcx
	mov	QWORD PTR 24[rbp], rdx
	mov	QWORD PTR -48[rbp], 0
	lea	rcx, .LC0[rip]
	call	fb_ErrorSetModName
	mov	QWORD PTR -8[rbp], rax
	mov	rax, QWORD PTR -8[rbp]
	mov	QWORD PTR -16[rbp], rax
	lea	rcx, .LC1[rip]
	call	fb_ErrorSetFuncName
	mov	QWORD PTR -24[rbp], rax
	mov	rax, QWORD PTR -24[rbp]
	mov	QWORD PTR -32[rbp], rax
.L5:
	mov	edx, 1
	mov	rcx, QWORD PTR 16[rbp]
	call	_ZN1X15UNIVERSE__get__Eu7INTEGER
	mov	QWORD PTR -40[rbp], rax
	mov	rax, QWORD PTR -40[rbp]
	mov	QWORD PTR -48[rbp], rax
	nop
.L6:
	mov	rax, QWORD PTR -32[rbp]
	mov	rcx, rax
	call	fb_ErrorSetFuncName
	mov	rax, QWORD PTR -16[rbp]
	mov	rcx, rax
	call	fb_ErrorSetModName
	mov	rax, QWORD PTR -48[rbp]
	leave
	ret
	.def	__main;	.scl	2;	.type	32;	.endef
	.section .rdata,"dr"
.LC2:
	.ascii "\0"
	.text
	.globl	main
	.def	main;	.scl	2;	.type	32;	.endef
main:
	push	rbp
	mov	rbp, rsp
	sub	rsp, 96
	mov	DWORD PTR 16[rbp], ecx
	mov	QWORD PTR 24[rbp], rdx
	call	__main
	mov	DWORD PTR -44[rbp], 0
	lea	rcx, .LC0[rip]
	call	fb_ErrorSetModName
	mov	QWORD PTR -8[rbp], rax
	mov	rax, QWORD PTR -8[rbp]
	mov	QWORD PTR -16[rbp], rax
	lea	rcx, .LC2[rip]
	call	fb_ErrorSetFuncName
	mov	QWORD PTR -24[rbp], rax
	mov	rax, QWORD PTR -24[rbp]
	mov	QWORD PTR -32[rbp], rax
	mov	rax, QWORD PTR 24[rbp]
	mov	r8d, 0
	mov	rdx, rax
	mov	ecx, DWORD PTR 16[rbp]
	call	fb_Init
	call	fb_InitSignals
.L9:
	lea	rax, -64[rbp]
	mov	QWORD PTR [rax], 0
	mov	QWORD PTR 8[rax], 0
	lea	rax, -64[rbp]
	mov	edx, 0
	mov	rcx, rax
	call	_ZN1X15UNIVERSE__get__Eu7INTEGER
	mov	QWORD PTR -40[rbp], rax
	mov	rax, QWORD PTR -40[rbp]
	mov	r8d, 1
	mov	rdx, rax
	mov	ecx, 0
	call	fb_PrintLongint
	mov	ecx, -1
	call	fb_Sleep
.L10:
	mov	rax, QWORD PTR -32[rbp]
	mov	rcx, rax
	call	fb_ErrorSetFuncName
	mov	rax, QWORD PTR -16[rbp]
	mov	rcx, rax
	call	fb_ErrorSetModName
	mov	ecx, 0
	call	fb_End
	mov	eax, DWORD PTR -44[rbp]
	leave
	ret
	.ident	"GCC: (x86_64-win32-sjlj-rev0, Built by MinGW-W64 project) 5.2.0"
	.def	fb_ErrorSetModName;	.scl	2;	.type	32;	.endef
	.def	fb_ErrorSetFuncName;	.scl	2;	.type	32;	.endef
	.def	fb_Init;	.scl	2;	.type	32;	.endef
	.def	fb_InitSignals;	.scl	2;	.type	32;	.endef
	.def	fb_PrintLongint;	.scl	2;	.type	32;	.endef
	.def	fb_Sleep;	.scl	2;	.type	32;	.endef
	.def	fb_End;	.scl	2;	.type	32;	.endef
sancho3
Posts: 358
Joined: Sep 30, 2017 3:22

Re: Question about object oriented dot notation style in FB

Post by sancho3 »

Personally I think Paul Doe's private member/public property method is what is best.
But if you are renaming here is the situation:

Code: Select all

ype ComboBox    
   Items As ItemsClass
   Declare Property GetItems(Byval Index As Integer) As String     
End Type
The property is returning one item. Not items. So if the name change is necessary route then change the property to item and the array to items()

Code: Select all

mycombobox.item(1) '- single item
i need to send the ADDSTRING message to combo right after adding an item to Items
You can make item a setter property as well:

Code: Select all

Declare Property item(Byval index as integer, Byref value As Const string)
Property CombocBox.item(Byval index as integer, Byref value As Const string)
	'
	' add my item
	' send my message
End Property

mycombobox.item(1) = new_item
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Question about object oriented dot notation style in FB

Post by fxm »

fxm wrote: A little twisted:

Code: Select all

.....
(cmb.Items).Add("Sample val1")  '' but parentheses here are mandatory
kcvinu wrote: @fxm,
Could you please tell me why those parenthesis were mandatory ?
Parentheses (around 'cmb.Items') are mandatory because of the overloading on the get-property's 'Items' name, to force the parser to first evaluate the property's call ('cmb.Items') with its eventual argument, in order to choose the right property before applying the final access to the last member ('Add("Sample val1")').
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: Question about object oriented dot notation style in FB

Post by kcvinu »

@Josep Roca,
Thanks for the reply. All these are part of some experiments with win api. A fun with learning.

@paul doe,
Thanks a lot for enlightening me with the callback idea as a substitution for class events. I never think about that. Let me study your code. I am sure i can learn new things from it. I will be back soon with my questions related to your code.

@Tourist Trap,
Yes, indeed. His definition is excellent.

@sancho3,
Thanks for the reply. Yeah, if the property "Item" is in Combobox class, then there is no problem and i can easily send messages with "This.Handle". But if the Item property is in ItemsList class (as per my first post) I need to pass the handle to that class. And obviously a name change will solve all the above said problems. But...

@fxm,
Thanks for the reply. Clearly understood.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Question about object oriented dot notation style in FB

Post by paul doe »

kcvinu wrote:@paul doe,
Thanks a lot for enlightening me with the callback idea as a substitution for class events. I never think about that. Let me study your code. I am sure i can learn new things from it. I will be back soon with my questions related to your code.
Sure, no prob.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Question about object oriented dot notation style in FB

Post by fxm »

kcvinu wrote:@fxm,
Thanks for the reply. Clearly understood.
If the subject interests you, in general parentheses for that case are often required for only the first expression of a code line (the left expression for an assignment or the one single expression for calling a method), no requested in general for the second expression (on the right when it exists).
Example:

Code: Select all

Type UDT0
    Dim As Integer int0
    Declare Sub int0set (Byval i As Integer)
    Declare Function int0get () As Integer
End Type

Sub UDT0.int0set (Byval i As Integer)
  This.int0 = i
End Sub

Function UDT0.int0get () As Integer
  Return This.int0
End Function

Type UDT1
  Dim As UDT0 int1 (1)
End Type

Type UDT2
  Dim As UDT1 _int2
  Declare Property int2 () Byref As UDT1
  Declare Property int2 (Byval index As Integer) Byref As UDT0
End Type

Property UDT2.int2 () Byref As UDT1
  Return This._int2
End Property

Property UDT2.int2 (Byval index As Integer) Byref As UDT0
  Return This._int2.int1(index)
End Property


Dim As UDT2 u2
(u2.int2).int1(0).int0 = 12      '' parenthese mandatory around overloaded property
Print u2.int2.int1(0).int0       '' parentheses not required around overloaded property
(u2.int2).int1(0).int0set(34)    '' parenthese mandatory around overloaded property
Print u2.int2.int1(0).int0get()  '' parentheses not required around overloaded property
(u2.int2(1)).int0 = 56           '' parenthese mandatory around overloaded property
Print u2.int2(1).int0            '' parentheses not required around overloaded property
(u2.int2(1)).int0set(78)         '' parenthese mandatory around overloaded property
Print u2.int2(1).int0get()       '' parentheses not required around overloaded property

Sleep
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: Question about object oriented dot notation style in FB

Post by kcvinu »

@fxm,
My head spins around... All setters needed to be covered with parenthesis. But getters are free.

@paul doe,
I've tried to use your callback idea in my ComboBox example. In your case, NameChange occures in SomeObject class. But in my case, List filling occuring in ItemsClass. And i need to send these list items to ComboBox class. And in your case, you explicitly set callback function. I dont want that method in my combo box.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Question about object oriented dot notation style in FB

Post by paul doe »

kcvinu wrote:I've tried to use your callback idea in my ComboBox example. In your case, NameChange occures in SomeObject class. But in my case, List filling occuring in ItemsClass. And i need to send these list items to ComboBox class. And in your case, you explicitly set callback function. I dont want that method in my combo box.
Then don't use it. Of course you explicitly set the callback functions, that's how's supposed to be done.

I don't quite understand what are you trying to accomplish. The 'Items' property (in this case, a collection of objects) of the combobox is to be made read only (you can't touch it from outside the object, nor are you supposed to). In Visual Studio, you simply can't assign the items property of one combobox into another. If you want to copy them, you need to do it manually:

Code: Select all

Public Class Form1
  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For i As Integer = 0 To ComboBox1.Items.Count - 1
      ComboBox2.Items.Add(ComboBox1.Items(i))
    Next
  End Sub
End Class
That's the way you set up a callback in Visual Basic.NET. See? On the sub prototype, there's a 'Handles' clause that specifies that the sub 'Form1_Load' handles the event 'Load' from the class 'MyBase', hence 'MyBase.Load'. Since FB doesn't include that capability, you must do it manually, hence the 'SetXXXCallback' helper function of the class example I provided. It's just simple convenience.
Post Reply