GPIO Test Application Part 4 – ViewModel

Previous: GPIO Test Application Part 3 – Model

This post is part 4 of 6 of the GPIO Test Application. You can find the initial post here: GPIO Test Application part 1 – Overview.

The ViewModel (VM) encapsulate all the functionality provided by the application.Each page, user control or dialog should have it’s own VM to implement the page, user control or dialog functionality.

For our Main Page, we have a MainPageVM which is the view model for this page.

MainPageVM vs Model

The MainPageVM creates and maintains the current instance of the LogicGateModel and makes it available to the UI. MainPageVM also performs operations on the Model.

Here, we see the intialization code that creates the Model:

private void Initialize()
{
    Logger.AddLogEntry("Initializing Main Window VM!");

    InitializeCommands();

    m_Model = new LogicGateModel();
    m_Model.PropertyChanged += Model_PropertyChanged;
    RecalculateOutput();

    Logger.AddLogEntry("Done Initializing Main Window VM!");
}

...

private LogicGateModel m_Model = null;
/// <summary>
/// This is the instance of the Model.
/// </summary>
public LogicGateModel Model
{
    get
    {
        return m_Model;
    }
}

When the model is created, the MainPageVM attaches an event handler to the PropertyChanged event of the LogicGateModel.

The handler is used to detect and act uppon changes in the values of LeftSwitch and RightSwitch. When those properties are changed, the MainPageVM recalculates the required outputs and updates the Model accordingly.  It also recalculates on changes to the IsEnabled function.

Bellow is the Model_PropertyChanged event handler code:

private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "LeftSwitch" || e.PropertyName == "RightSwitch")
    {
        RecalculateOutput();
    }
    else if(e.PropertyName== "IsEnabled")
    {
        if(Model.IsEnabled)
        {
            OnPropertyChanged("ShowSimulatedSwitches");
            RecalculateOutput();
        }
    }
}

MainPageVM functionality

Calculations

The calculation portion of the MainPageVM is pretty simple. A case statement performs the actual logic operation on the RightSwitch and LeftSwitch of the Model, then the result is pushed back to the RedLED (false) and GreenLED (true) properties of the model.

private void RecalculateOutput()
{
    Logger.AddLogEntry("Recalculating output!");

    bool result = false;
    switch(Logic)
    {
        case LogicTypeEnum.AND:
            result = Model.LeftSwitch && Model.RightSwitch;
            break;
        case LogicTypeEnum.OR:
            result = Model.LeftSwitch || Model.RightSwitch;
            break;
        case LogicTypeEnum.NAND:
            result = !(Model.LeftSwitch && Model.RightSwitch);
            break;
        case LogicTypeEnum.NOR:
            result = !(Model.LeftSwitch || Model.RightSwitch);
            break;
        case LogicTypeEnum.XOR:
            result = Model.LeftSwitch ^ Model.RightSwitch;
            break;
    }

    Model.GreenLED = result;
    Model.RedLED = !result;

}

Note: We could have used a more powerful pattern, such as the Strategy pattern, to select and perform the logic operation. But in the spirit of keeping the code readable a case statement is better.

Logic Property

The formula used to calculate the output is dependent on user input. The user selects the logic operation to perform then the application uses it to calculate the output. The Logic property of the MainPageVM is used to define the operation currently used. The MainPageVM also provides a list of available operations so that the View is able to display a list to the user. Following is the code related to the Logic property.

LogicTypeEnum represents the available operations.

public enum LogicTypeEnum
{
    AND,
    OR,
    NAND,
    NOR,
    XOR
}

Logic and LogicList properties provide the functionality to the View. Notice the call to RecalculateOutput on the Logic setter.

private LogicTypeEnum m_Logic = LogicTypeEnum.AND;
/// <summary>
/// This is the logic applied to the inputs to define how calculation is done.
/// </summary>
public LogicTypeEnum Logic
{
    get
    {
        return m_Logic;
    }
    set
    {
        if(value != m_Logic)
        {
            m_Logic = value;
            OnPropertyChanged();
            RecalculateOutput();
        }
    }
}

private List<LogicTypeEnum> m_LogicList = null;
/// <summary>
/// This is the list to populate the list or ddl used to select
/// the logic to apply on the inputs. 
/// </summary>
public List<LogicTypeEnum> LogicList
{
    get
    {
        if(m_LogicList == null)
        {
            m_LogicList = new List<LogicTypeEnum>();
            Array a = Enum.GetValues(typeof(LogicTypeEnum));
            foreach(var v in a)
            {
                m_LogicList.Add((LogicTypeEnum)v);
            }
        }
        return m_LogicList;
    }
}

Other Functionality

Other functionality have also been added to the MainFormVM. For debugging purpose the UI can display buttons on the Main Page simulating the right and left switches. Those buttons are only available if the GPIO fails to initialize which in turn enables the ShowSimulatedSwitches property on the VM.

There is also an Exit command that will close the application. This is useful to stop debugging sessions from the Main Page.

Conclusion

The MainPageVM performs all the function related to the calculation and maintains the information related to the calculation. This allows the Model to focus on content and not worry about functionality.

Next: GPIO Test Application Part 5 – View

, , , , ,

  1. Leave a comment

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: