Modules

Introduction

This section seeks to act as guide to implement new HPTK modules. Structure of HPTK modules is described in detail here.

HPTK modules can be child of:

  • AvatarModel.

  • BodyModel.

  • PartModel (HandModel or FingerModel).

Requirements

Custom HPTK modules must fulfill the following requirements:

  • Follow MVC pattern.

  • Overriden functions must call their base function.

  • View must expose only safe operations.

    • It shouldn't be possible to make the module fail from the view.

  • View must hide the reference to its model.

  • Controller must self-register in its parent's registry as soon as possible (Awake).

  • Controller must search the reference to the other 2 components if missing.

  • Controller shouldn't update if its GameObject is disabled.

  • Model must work with only the reference to its parent module.

    • Numbers and strings must have a default value.

    • Missing references must be searched in the scene automatically if they are missing.

    • If some mandatory references or value could not be found, a warning or error message should be logged and the module should be automatically disabled.

Code skeletons

Model:

public class CustomModel : HPTKModel
{
    // Parent can also be AvatarModel, BodyModel, PartModel or FingerModel
    public HandModel hand;

    public int someValue = 5;
    public Transform someRef;
    
    CustomController _controller;
    public CustomController controller
    {
        get
        {
            if (!_controller)
            {
                _controller = GetComponent<CustomController>();
                if (!_controller) _controller = gameObject.AddComponent<CustomController>();
            }
    
            return _controller;
        }
    }
    
    CustomView _view;
    public CustomView view
    {
        get
        {
            if (!_view)
            {
                _view = GetComponent<CustomView>();
                if (!_view) _view = gameObject.AddComponent<CustomView>();
            }
    
            return _view;
        }
    }
    
    public override void Awake()
    {
        base.Awake();
        
        if (!someRef)
        {
            // Find someRef automatically
        }
    }
}

View:

[RequireComponent(typeof(CustomModel))]
public class CustomView : HPTKView
{
    CustomModel model;

    public HandView hand { get { return model.hand.specificView; } }

    // Public properties
    
    // Public events
    
    // Public functions

    public override sealed void Awake()
    {
        base.Awake();
        model = GetComponent<CustomModel>();
    }
}

Controller:

[RequireComponent(typeof(CustomModel))]
public class CustomController : HPTKController
{
    [ReadOnly]
    public CustomModel model;

    public override void Awake()
    {
        base.Awake();
        model = GetComponent<CustomModel>();
        SetGeneric(model.view, model);
        
        // ...
    }
    
    public void OnEnable()
    {
        model.hand.registry.Add(this);
    }
    
    public void OnDisable()
    {
        model.hand.registry.Remove(this);
    }

    public override void ControllerStart()
    {
        base.ControllerStart();
        
        // ...
    }
    
    public override void ControllerUpdate()
    {
        base.ControllerUpdate();
  
        // ...
    }
}

Last updated