Delegates

The Xojo docs about delegates are quite sparse about what you can or cannot do with them and whether they can or cannot take certain kinds of parameters. What they do say is that

A Delegate data type is an object representing a specific method. It is a function pointer with a method signature.

I was recently asked if a delegate that did not make use of any external dynamic library could take an object parameter. The delegate definition and the code creating the delegate are all inside a single Xojo project.

Delegates are kind of esoteric but like many things, when you need one you need one and it may be the only way to do what it is you want to do.

Inside a single Xojo project “delegation” can be done in several ways. Before Delegates what you might often find that an interface would be used. This would work for code all in the same project, but could lead to a lot of interfaces with one method just to be able to declare the delegate. When you use a delegate definition and AddressOf to create the delegate the difference is negligible. In both cases you define a new type, either the interface or the delegate, and then in some way have to implement that type so you can make use of it.

One key difference is that with an interface you can’t just use it with any method that has the proper signature. It has to be implemented by a class and then you need an instance of that class. So there can be more work with an interface in this case.

But notice I wrote that both a Delegate and and Interface define a new data type. What that means is that you can use the delegate name in a DIM statement just like you would use Integer, String, Color, Text etc.

dim delegateReference as MydelegateType

And then you can assign values to it – but in the case of a delegate you need to make sure you assign values that match the signature the delegate was defined with. This is the same as if you declare a variable as an integer you can’t assign a string to it.

For instance if we had the following :

Delegate NoParamDelegate() 
Delegate OneIntParamDelegate(i as integer)

Sub NoParamMethod()
End Sub
Sub OneParamMethod(i as integer)
End Sub
Sub InvalidOneParmMethod(s as string)
End Sub

dim noParam as NoParamDelegate
dim oneParam as OneIntParamDelegate

We have two delegates defined – the NoParamDelegate and OneIntParamDelegate. One takes no parameters. The other takes one integer parameter.

What that means is that the NoParamDelegate can ONLY be assigned to contain the AddressOf a method that takes NO parameters. It cannot hold ANY other pointer to any other method. Given the previous definitions :

// would compile
noParam = AddressOf NoParamMethod
oneParam = AddressOf OneIntParamMethod

// will not compile - you get a type mimatch
noParam = AddressOf OneIntParamMethod
oneParam = AddressOf NoParamMethod

// will not compile 
// although this method has one param the parms do not match types
noParam = AddressOf InvalidOneParmMethod
oneParam = AddressOf InvalidOneParmMethod

Delegates are “fussy” – you MUST assign the addressof a method that has the EXACT SAME SIGNATURE the delegate was defined with.

But once you do this you CAN pass whatever data types you want within your own project.

If you happen to use a delegate to call EXTERNAL code, which is sometimes done in the case of interfacing with system libraries and other non-Xojo code, you often use a Ptr although you can use a delegate as well if you make sure you define the delegate with the signature that matches the external codes (this can be tricky sometimes)

If you do match up the types one thing you will run into is that Xojo objects can not be passed to external code this way. You can only pass ptr’s, structures – careful here as you need to know the specific calling conventions in use – and other simple types. Xojo will coerce many things to the correct type for you just as it does for declares.

EmbeddedWindowControl

If you’ve ever used a container control on a layout and then tried to manipulate the controls at runtime with code like


For i As Integer = 0 To Self.ControlCount - 1
  Dim ctrl As Control = Self.Control(i)  
  // now manipulate this control or call its methods
Next

you’ve probably run into the EmbeddedWindowControl

Its what you get when you use a Container Control on a layout either by placing one at design time or dynamically adding one at runtime.

Note that you get an EmbeddedWindowControl – not an instance of the Container you placed there. So any code you use that tests if a control ISA specific instance will fail for your containers. You don’t get a reference to the instance you get this EmbeddedWindowControl instead. So you cant call any methods you have added to the container control or reference any properties of it.

Its been most annoying. There have been several requests for something to be done so the container the EmbeddedWindowControl was created from can be accessed. Like this one and this one and this one.

And today, for a project I was working on, I needed this and decided to figure out how to make this possible.

The result is this little sample program with one module that extends EmbeddedWindowControl in a way you can get the container control that the embedded window control was created from.

To make use of this simply copy the EmbeddedWindowControlExtensions module into your project. Then when you iterate a set of controls on a layout you can do

For i As Integer = 0 To Self.ControlCount - 1
  
  Dim ctrl As Control = Self.Control(i)
  
  If ctrl IsA EmbeddedWindowControl Then
    
    Dim cc As ContainerControl = EmbeddedWindowControl(ctrl).Container 
    
    If cc <> Nil Then
      // you now have an actual reference to the container control
      // so you can use its methods, properties, etc
      // but you will need to cast it first
    End If
    
  End If
  
Next

Enjoy !

Knowing if a property thats an enum has been set

Interesting question from a dev I’ve know for a long time.

If I have a property that’s an enum, how do I tell that it’s not been set?

And this is a good question.

Because an enum is, at its core, an integer when you declare one and run its always initialized to the default value for an integer – 0.

And so if you use this fact you can actually detect that its been set or cleared.

Simply make you list of enumerated values NOT use 0 as a valid value.

Public Enum myEnum
valueName1 = 1
valueName2 = 2
valueName3 = 3
End Enum

And now any time the value is 0 when your code starts to run you can tell any property that is declared to be a myEnum is or is not set by checking

Private Property someProperty as myEnum

Sub Open() Handles Open
  
  If 0 = Integer(someProperty) Then
    break
    // someProperty has never been set or has been deliberately set to 0
  End If
End Sub

Interfaces

Interfaces are one of those things in Xojo, and many other computing languages, that can really help you make your code more reusable and generic.

For instance, suppose you need a class that is a “List”. You could write a single class, called list, that you could add items to, remove items from, and generally manipulate in a “list like way”. You might go so far as to look up some other languages implementation of list and create a Xojo equivalent. But in general you would have (as wikipedia notes)

Operations
Implementation of the list data structure may provide some of the following operations:
- a constructor for creating an empty list;
- an operation for testing whether or not a list is empty;
- an operation for prepending an entity to a list
- an operation for appending an entity to a list
- an operation for determining the first component (or the "head") of a list
- an operation for referring to the list consisting of all the components of a list except for its first (this is called the "tail" of the list.)
- an operation for accessing the element at a given index.

But note that wikipedia, and most other place that have such a “spec” dont say how this is implemented. Just what the API is. And this is a perfect place to use an interface.

Now in Xojo MOST times you dont need to define the CONSTRUCTOR in an interface. You can but it is unusual and depending on what classes you intend to have implement this interface there can be restrictions on which constructors must exist (ie/ if you want a UI control like listbox to implement this interface it may need a constructor with no parameters)

So I would NOT add this to the interface.

But everything else can be specified in an interface.

an operation for testing whether or not a list is empty - possibly a method named "IsEmpty" that returns a boolean ?
an operation for prepending an entity to a list - possibly a method named "Prepend" that takes an element and adds it to the "front" of the list
an operation for appending an entity to a list - possibly a method named "Append" that takes an element and adds it to the "end" of the list
an operation for determining the first component (or the "head") of a list - maybe a method called "FirstItem" or "Head" that returned the first item
an operation for referring to the list consisting of all the components of a list except for its first (this is called the "tail" of the list.) a method called "Tail" that returns the list with the first item removed
an operation for accessing the element at a given index - a method called "ElementAt" that takes an index parameter and returns the element at that index

And that would be an interface that confirmed to Wikipedias notion of “List”

The interstingthing is that Xojo already has many classes that behave in ways that are “list like” in many ways. Listbox, popupmenu,combobx and a few others already have methods like AddRow, RemoveRow and many of the others that are “list manipulation and inquiry” type methods. You can find out if a listbox is empty (listcount = 0), you can remove and access rows at specific positions.

But Xojo doesnt define and use an interface for this class or any other that share similarties. However, you can add your own.

In order to do this you need to define the interface in a very generic way so that adding a row to a listbox, which may have 1 or more columns, still makes sense. Some input parameters might need to be variants instead of something more specific. And, for some things the right return value may have to be a variant instead of something more specific.

Still you might come up with an API for “list” like things that looks like :

Interface List
  Sub AddRow(ParamArray values() as string)
  End Sub
  
  Sub AddRowAt(ParamArray values() as string, zeroBasedInxed as integer)
  End Sub
  
  Sub FirstRowIndex() as integer
  End Sub
  
  Sub LastAddedRowIndex() as integer
  End Sub
  
  Sub LastRowIndex() as integer
  End Sub
  
  Sub RemoveAllRows()
  End Sub
  
  Sub RemoveRowAt(zeroBasedIndex as integer)
  End Sub
  
  Sub RowCount() as integer
  End Sub
  
  Sub RowTag() as Variant
  End Sub
  
  Sub RowTagAt(zeroBasedIndex as integer) as variant
  End Sub
  
  Sub RowValue() as Variant
  End Sub
  
  Sub RowValueAt(zeroBasedIndex as integer) as Variant
  End Sub
  
  Sub SelectedRowCount() as Integer
  End Sub
  
  Sub SelectedRowIndex() as integer
  End Sub
End Interface

And then you can apply this to your own classes. custom subclasses of listbox, combobox, popup menu and other controls that have list like aspects to them.

Once you do this you can then write generic methods that manipulate Lists, without regard to whether its a custom user class implementing the interface, a listbox, a popupmenu etc because all of them will return TRUE when you do

If <something that implements list> IsA List Then
End If

This is very handy and very powerful and wildly under utilised.

Making platform specific error codes generic

A few threads on the forums have commented that the URLConnection isnt quite as easy to use as many might expect. In particular there are comments about having to know what error codes a platform might return makes it harder to use than it should be.

Normally Xojo hides this level of detail from us.

I was thinking about this problem and have come up with something of a solution that makes it possible to both know the specific error code and yet still write code that is portable.

My solution relies on the fact that, at compile time, numeric constants will take on one of many possible values if you set up platform specific versions of a numeric constant. Its possible to set up a constant with a specific value for macOS, Windows, Linux, and iOS (as well as a couple that are legacy types) as follows :

If you were to compile this code on macOS the Foo constant would have the value 1, on Windows it would be 2 and so on. The nice thing is that code could simply use the symbolic constant Foo instead of having to rely on the specific value. Instead of writing

// is someVariable = Foo on macOS ?
if someVariable = 1 then
   // do whatever should be done 
end if

you could, and probably should write

// is someVariable = Foo on macOS ?
if someVariable = Foo then
   // do whatever should be done 
end if

This is has the added benefit of making your code more robust since a simple change to a constant is all thats required to instead of finding all the magic number 1’s everywhere. But how does this help us to making generic platform specific error codes (which I admit is a bit of an oxymoron ?)

An enumerated value can be set from one of several possible sources. It can have no specific value assigned, have a literal value, an enumerated value from another enum, or a constant.

IF Enum2 is is defined as

Public Enum Enum2
  value1 = 10
End Enum

Enum1 can be defined as

Public Enum Enum1
  value1 // no specific value assigned
  value2 = 99999
  value3 = enum2.value1
  value4 = kConst
End Enum

That we can use a constant is especially notable as we just saw we can make a constant platform specific. So its possible to have an enumerated value that takes on the value of a platform specific version of a constant (but be careful with this as you would not want to have many enumerated values with the same value as that makes them harder to use)

If we defined our enum as

Public Enum kDemoEnum
  value1 = kConstant
End Enum

and the constant as

Public Const kConstant as Number = -1
  OS X, default language, 1
  Windows, default language, 2
end Const  

when we compiled on macOS the value for kDemoEnum.value1 would be 1, on Windows 2 and on any other it would be -1 (the default for the enum)

So now you can make enumerations that give you the flexibility of named values without having to know the specific values AND a generic set of enumerated values that reflect platform specific values taken from constants.

Use carefully.

UPDATE ! – here’s an example

App vs App

App Battles ! Winner takes all. Last man standing and all that !

No – nothing quite so fun (although it can be a lot of fun)

This has to do with the App class at design time vs the App METHOD (yes it’s a method) at runtime.

The app class at design time can be renamed however you want. You could call it “MyApp”. And for most things that would have no impact. But, you’ll note I don’t say for ALL things.

If you start a new Desktop Application and rename the App class to MyApp I can demonstrate where there are differences.

In the new app’s Window1. Open event lets just do something simple like

dim s as string = App.<press tab>

What you should notice is that none of the defined constants autocomplete. The methods and properties of any Application will show. But no defined constants.

This makes sense because the constants do not exist on Application but they do exist on MyApp.

If we add a few properties to MyApp they also won’t autocomplete. Again the App METHOD, at runtime, returns an Application (or Console Application, Service Application, WebApplication or iosApplication depending on the project type)

Again none of the instances that the App method returns define any of the properties we added to our custom Application instance. And so they will not autocomplete.

What’s an App to do ?

We can definitely deal with this.

One way is to not rename the App class in your project – although this wont alleviate all issues. It will just ignore some for a while. And that is, for many uses, OK.

Or we could cast the return value of the App method to be our defined class type with code like

dim s as string = MyApp(App).<press tab>

This is ALMOST always safe – except in the handful of spots that App can actually be NIL – yay !

It may be better to write something like

dim s as string
if App isa MyApp then
  s = MyApp(App).<press tab>
end if

so a nil return from App won’t matter

Either way the confusion comes from the App METHOD and the App class in your project having the same name. This can make it very unclear whats wrong. And then, when you REALLY need to know why this is, if you’ve ignored this until now you wont know why this weirdness exists.

Unless of course you read this post 😛

Implementing the Factory pattern in Xojo

When using the “factory” pattern you should only be able to get a valid instance from the factory and NO other way. Thats kind of the point of the pattern – to reduce the number of points at which instances can be created. Normally in Xojo you might have a module with a method that can create instances, and its the only one allowed to do this. The constructors for the classes the factory method can create should be protected or private so they cannot be directly invoked using New outside the module.

Usually it might look something like (note this code will not compile)

Module People

  Public Interface IPerson
      Public Function GetName() as string
  End Interface

  Public Class Villager
    Implements IPerson
      Public Function GetName() as string
        return "Village Person"
      End Function

      Protected Sub Constructor()
      End Sub
  End Class

  Public Class CityPerson 
    Implements IPerson
      
      Public Function GetName() as string
        return "City Person";
      End Function

      Protected Sub Constructor()
      End Sub
  End Class

  Public Enum PersonType
    Rural
    Urban
  End Enum

  Public Function GetPerson(type as PersonType) as IPerson
  
    select case type
    case PersonType.Rural
      return new Villager()
    case PersonType.Urban
      return new CityPerson()
    else
        raise new UnsupportedOperationException
    end select
  End Function

End Module

An alternative would be to not use an Interface for IPerson but to make it a base class – they end result is similar.

But, you cant do either in Xojo. At least not quite like my code above shows.

If you have a factory method in the module it cannot invoke their constructors. They are only callable by items in the class hierarchy. It has no special means to access the private or protected constructors of the classes it contains.

So you cant easily restrict construction to ONLY the factory method since what you really need is a “module” or “namespace” scope. And that doesn’t exist.

What you need to do is create an INTERFACE for the various classes in the namespace you intend to expose and make the classes in your namespace implement these interfaces. In addition you need to make the interfaces PUBLIC so they can be used outside the module. As well you need to make the classes that implement the interfaces PRIVATE so you can’t actually try and instantiate them outside the module. This has the unfortunate side effect of making it so you can only use the classes in the module via their interfaces. Remember what we really wanted was just to make it so the only legal way to get an instance was to use the factory.

Note that by having to do everything via an interface this means that “properties” are exposed by pairs of getter / setter methods. Fortunately in Xojo this has little semantic impact except that you have to write the code for it.

All code not in the module must use the interfaces as that’s all you have available.

But now because the classes in the module are PRIVATE you can put as many public constructors on them as you desire. They won’t be callable by anything outside of the module so instances cannot be created in ANY way except by calling the factory method in the module.

Module scope would help reduce this work needed to implement the Factory Pattern by making it possible to implement the module’s classes with “module” scoped constructors. This way you could have the factory return any of the parent or subclass instances and you could skip all the interfaces.

A sample of the initial implementation that doesnt work and the fixed version is here

C Unions

An interesting question came up on the forums the other day about how to mimic “Unions” from C.

Turns out I had answered this some time ago – its close but not exactly the same as in C. But it is close enough to be functional and close enough for most uses.

And it’s not mentioned anywhere in the Xojo docs. Not even in advanced topics.

The requirement was a need to be able to interpret a set of data (4 bytes in the forums post case) in one of two different ways. One was as 4 separate byte values, and the other as 2 16 bit values.

In the example I had given previously the need was a common “record” type that had an identifying “record type” byte as the first byte and several other interpretations of the data that followed. In all cases the records were the same total size but their contents varied.

In the example I have the three structures following :

Structure Structure1
  switchCode as uint8 
  rest(4) as uint8
End Structure

Structure Structure2
  switchCode as  uint8
  val1 as uint16
  val2 as uint16
End Structure

Structure Structure3
  switchCode as uint8 
  val1 as uint32
End Structure

Note that each has, in this set up, a byte at the beginning that is at a common offset and that is used to determine which of the three structures is the correct one to be using to interpret the data. In some cases there may be some other indicator or mechanism to know which way to interpret the data.

In this example all structures are defined to be the same total size. This is NOT required. A C union will be the largest of any of the defined union members. So make sure you account for this when you decide what memoryblock size to use for the initial data buffer.

The data buffer is just a memoryblock of whatever size is needed. To interpret the data differently a Ptr is used. And since Ptr’s can interpret the data they point at via a structure we can, once the mb is assigned to the Ptr, now interpret the data using any of our defined structures.

Dim mb As new MemoryBlock(5)

mb.Byte(0) = &h20
mb.UInt16Value(1) = 32
mb.UInt16Value(3) = 254

Dim p As ptr = mb

Dim s1 As structure1 =  p.structure1 // makes it so I can read the
            // data in mb using the fields from structure1
            // but I could use any of the three OR 
            // some other mechanism to figure out which structure
            // to use to inspect the data

Select Case s1.switchcode

Case &h20
  Dim s2 As structure2 =  p.structure2 
// makes it so I can read the data in mb using 
// the fields from structure2

  Dim value1 As UInt16 = s2.val1
  Dim value2 As UInt16 = s2.val2
  Break

Case &h21
  Dim s3 As structure3 =  p.structure3 
// makes it so I can read the data in mb using 
// the fields from structure3

  Dim value1 As UInt32 = s3.val1
  Break

Case &h22  
  Dim struct1 As structure1 =  p.structure1 
// makes it so I can read the data in mb using 
// the fields from structure1

  Dim value1 As UInt8 = struct1.rest(0)
  Dim value2 As UInt8 = struct1.rest(1)
  Dim value3 As UInt8 = struct1.rest(2)
  Dim value4 As UInt8 = struct1.rest(3)

  Break

End Select

Using this technique we can “overlay” the structure onto the raw data in the memoryblock and read it out using the structures fields.
Very handy especially for those cases where you need to read from file formats, memory formats that involve C unions.

About Attributes

A recent feedback case made me think that there may be a real lack of information about attributes.

A lot of people believe that attributes are key value pairs that must have a valid identifier as the NAME and ALWAYS have a quoted string for a value.

This is incorrect.

Attribute name can be quoted strings – meaning you can, by using a quoted string for the name – have names that include spaces that would normally be invalid.

Secondly you CAN have an attribute VALUE that is NOT a quoted string. When you do this the value that you will see at runtime comes from a CONSTANT with the name placed in the value.

An example is here