Using a Class for a Structure within a Class

I am trying to create a Class to implement a state machine. The state machine sits in one state at a time. A timer starts when a state is entered. If the timer expires, the machine goes to a certain state. If a button is pushed, it can go to a different state. There are outputs that change depending on state.

I think the correct way to do this is to use a class to create a data structure that I call a StateDescriptor for each state:

Class StateDescriptor
nextStateOnButtonPush As Integer = 0
nextStateOnTimeout As Integer = 0
numSecindsToTimeout As Integer
output As Integer
End Class

The class StateMachine will then declare an array of StateDescriptor:

dim state(10) As StateDescriptor

The class StateDescriptor should really only be visible in the class StateMachine. That is the only place it will be used. When I create these two classes, they are both viisible to the entire application. From my reading of the documentation, I really don’t what to use a Structure. That is to get the storage alignment correct and I don’t care about that.

The only way I can see to do this is to put both classes in a Module, but that doesn’t seem to be the correct way to organize it either.

Thank you in advance-
Mike M

Instead of an integer, why not have each StateDescriptor hold the next StateDescriptor?

I’m not really sure I see how that works. But, it still doesn’t solve my problem. I have a class StateDescriptor and class StateMachine. The class StateMachine is where I fill in the behavior of each of the StateDescriptors. How do I put the StateDescriptor class ‘inside’ the StateMachine class so that it is only visible there?

-Mike M

Oh, I didn’t understand the question.

Create a module. Put your StateMachine and StateDescriptor classes into that module, and make the former global and latter private.

then this StateDescriptor is a property of type StateDescriptor and in the StateMachine constructor (method) you create a new StateDescriptor object and assign it to your property.
for state names and values is usually a enum(eration) used.

dim state(10) As StateDescriptor
the use of var or dim in a method exists only in this scope.

@Kem_Tekinay – First and most, thank you for the time you’ve invested and the help your giving me! For awhile I thought this was the solution. I actually tenatively brought this up in my original post. But I’m now very confused. Please see the non-targeted reply I am going submit below.

@MarkusR- Thanks for your help on how to implement this. I think it would have taken me quite awhile to figure out this way to do it.

I’m still very confused about the putting the two classes in a module however. See non-targeted reply below.

This is the correct way to do it. StateDescriptor will be visible to StateMachine (because it is also in the module), but not to anything outside the module.

Thanks to @Kem Tekinay and @MarkusR, I know what I’m doing: putting both classes in a module. But, I’m still very confused and maybe somebody can help me better understand.

I have spent a couple hours now researching Modules vs Classes. Modules appear to be for global variables and objects that you reference throughout a program. What I’m trying to do is specify an object that implements a state machine. That sounds like a Class. So I create Class StateMachine and place it in a Module:

Module SomeName
(other globals, if I need them)
Public Class StateMachine
End Class
End Module

Now, in Class StateMachine I would like a data structure StateDescriptor to hold the information for each state. It will only be used in Class StateMachine. In C, I would use a struct. I like the idea of using a class instead, it seems much more flexible. It allows things like having code associated with the StateDescriptor for bounds checking, etc. If it were a struct, I’d place it in Class StateMachine. Xojo has a data structure like struct and that is Structure. But, the Language Reference says it’s not for this application but for memory organization to match APIs and so on and that a Class should be used instead. So, I add in Class StateDescriptor:

Module SomeName
(other globals, if I need them)
Public Class StateMachine
(constructor has dim state(10) As StateDescriptor)
End Class //StateMachine
Private Class StateDescriptor
nextStateOnButtonPush As Integer = 0
nextStateOnTimeout As Integer = 0
numSecondsToTimeout As Integer
output As Integer
End Class //StateDescriptor
End Module //SomeName

This is what I am doing. But, I am not-happy/confused because now I don’t have one object in the code that represents the state machine. The Module doesn’t really because I can’t instantiate a state machine module. Instead, I have to instantiate the state machine class from the SomeName module.

I guess what I really think is needed it a Class within a Class. I just searched the forum for this and found it was already discussed and it’s not part of the language. It’s a shame. I’ve fallen in love with the logical structure of Xojo and this is like a missing bone from the little finger of the language. But, from reading the forum, I also understand limited resources. So, I apply a splint.

But, unfortunately I have the personality trait that whenever I look at the language as a whole, I’m going to keep noticing that little splint down on the little finger.

You’re on the right track, but in the Inspector, set StateMachine to Global, not Public, and you will not need to prefix the module name when instantiating.

I’m concerned about this line of code. It shouldn’t be a Dim statement. It should be a property of the class. Otherwise it goes out of scope and you can’t use it in the rest of the class’ code.

I guess what I really think is needed it a Class within a Class.

That’s what the module is for, to encapsulate the classes and bundle them together.

1 Like

@Tim_Hare: Thank you very much! It took me a couple hours playing around with it to get it. Suppose I wanted to have more than one list of StateDescriptor objects in an instance of a StateMachine. (I don’t know why I’d want to do this. I’m trying to understand the language better). I could either:

  1. Create a new StateDescriptorList class that has a property that is an array of StateDescriptor objects and then make an array of StateDescriptorList objects in my StateMachine class, or

  2. Make an 2D array of StateDescriptor objects (an array of an array of StateDescriptor objects) in the StateMachine class?

Are the only objects that persists in between calls to Methods of a class a property of that class?

Mahalo (Hawaiian for showing respect, thank you)

Another option would be to have several properties that are arrays of StateDescriptor and are aptly named to make your code easier to read.

Yes. You can also access global variables.