VR-Engage  2.2
Loading...
Searching...
No Matches
Notification Example

Overview

Purpose: This example demonstrates how to monitor player state attributes and provide user feedback through VR-Engage's temporary notification system. It shows the pattern for registering callbacks on attribute changes and displaying timed notifications.

Observable Behavior: When running this example, you will see temporary notification messages appear when weapon selection changes. The notification displays "Weapon #N" where N is the weapon index, automatically dismisses after 3 seconds, and appears as an overlay in the VR-Engage UI.

Prerequisites: Understanding of Player Station Framework and familiarity with Player Attribute Store. Knowledge of callback/observer patterns is helpful.

Related Examples: The State Example demonstrates more complex state monitoring with custom UI.


Key Concepts Demonstrated

This example demonstrates player component lifecycle implementation using DtPlayerComponent with proper initialization and shutdown. The implementation is a minimal component focused solely on notification logic. For complete details on component initialization, see Component Initialization.

The example also covers attribute store callbacks for registering change notifications on player state attributes. It uses DtAttributeCallbackCollection for automatic connection management and demonstrates type-safe attribute access with template-based callbacks.

Finally, the example shows how to create temporary notifications for timed overlay messages that provide user feedback. The implementation uses the DtPlayerStationTempNotification service and establishes a pattern for non-intrusive user notifications.


Code Walkthrough

Component Registration

The plugin registers the notification component with VR-Engage's factory system:

// File: examples/notification/plugin.cxx
extern "C"
{
{
return true;
}
}
Example component demonstrating player attribute monitoring and temporary notifications.
Definition notifyLogic.h:43
void addCreator(std::string name="")
Registers a creator for a specific type.
Definition factory.h:112
Top-level class representing the VR-Engage application.
Definition playerStationApp.h:163
virtual DtComponentFactory & componentFactory()
Gets the component factory.
VRECOMMONCOMPONENTS_DLL bool initPlayerStationModule(makVre::DtPlayerStationApp *app)
Module initialization function declarations using C linkage.
constexpr auto DtNotifyLogicType
Type identifier string for DtNotifyLogic component registration.
Definition notifyLogic.h:24

The string "DtNotifyLogic" (defined as DtNotifyLogicType in the header) must match the componentType value in role configuration Lua files. Registration happens once at plugin load time, before any player stations are created.

Attribute Callback Registration

The component monitors the weapon index attribute and displays notifications on change:

// File: examples/notification/notifyLogic.cxx
bool DtNotifyLogic::initialize(DtPlayerStation* player, DtInitTable& config)
{
if (!DtPlayerComponent::initialize(player, config))
return false;
// Check for the "weaponIndex" state attribute
if (player->playerAttributeStore()->hasAttribute("weaponIndex"))
{
// Register callback for weapon changes
player->playerAttributeStore()["weaponIndex"],
this,
}
else
{
LOG_WARN("Example Notify") << "Failed to find state attribute \"weaponIndex\"" << std::endl;
}
return true;
}
virtual bool initialize(makVre::DtPlayerStation *player, makVre::DtInitTable &config) override
Initializes the component with player station and configuration.
virtual void handleWeaponIndexChanged(int index)
Callback invoked when the weaponIndex attribute changes.
void connect(DtAttributeHandle attr, OBJECT_T *object, void(OBJECT_T::*method)(const DtAttributeHandle &))
bool hasAttribute(const std::string &name) const
Checks if a child attribute exists.
virtual DtPlayerStation & player()
Gets the player station.
DtAttributeCallbackManager myAttributeCallbacks
Member-scope instance of Attribute callback manager.
Definition playerComponent.h:194
virtual DtAttributeHandle & playerAttributeStore()
Gets the player attribute store.
#define LOG_WARN(channel)
Macro to log a warning message to log files.
Definition logger.h:69

The DtAttributeCallbackCollection manages callback lifecycle automatically, disconnecting callbacks in shutdown() to prevent dangling references. The compiler ensures callback signatures match attribute types, and the code checks attribute existence before registration as a defensive measure.

Notification Display

When the weapon index changes, a temporary notification is displayed:

// File: examples/notification/notifyLogic.cxx
{
std::ostringstream stream;
stream << "Weapon #" << index;
// Create a 3-second notification message
myPlayer->app()->tempNotification()->newNotification(stream.str().c_str(), 3.0);
}
DtPlayerStation * myPlayer
Pointer to the owning player station.
Definition playerComponent.h:182
virtual DtPlayerStationTempNotification * tempNotification()
Gets the temporary notification handler.
Definition playerStationApp.h:740
virtual DtPlayerStationApp * app() const
Gets the player station application.
virtual void newNotification(const QString &text, double lifetime=3.0)
Displays a new temporary notification.

The notification duration (3.0 seconds) controls how long the message displays. The tempNotification() service provides non-blocking overlay display, and messages are automatically dismissed without user interaction. This pattern applies to any transient user feedback.


Deployment and Testing

Installation

Build the example (see Environment Setup & Build Guide):

cd examples\build
cmake --build . --config RelWithDebInfo --target notification

Install the plugin to the VR-Engage installation:

cmake --install . --config RelWithDebInfo

This copies the plugin to <VR-Engage-Install-Dir>\plugins64\vrEngage\release\exampleNotification.dll

Verify installation:

dir "<VR-Engage-Install-Dir>\plugins64\vrEngage\release\exampleNotification.dll"

Launching with the Example Simulation Model Set

The toolkit installs an example simulation model set for this component at <VR-Engage-Install-Dir>\data\simulationModelSets\examples\notification.sms. This SMS includes a pre-configured Human role that demonstrates the notification component. To launch VR-Engage with this SMS as the default:

vrEngage.exe -c -n 3 --setting "playerStationApp.defaultSimulationModelSets = {'<VR-Engage-Install-Dir>/data/simulationModelSets/examples/notification.sms'};"

The example SMS provides roles/human.lua, which inherits from the standard humanBase.lua role and adds the DtNotifyLogic component:

-- File: data/simulationModelSets/examples/notification/roles/human.lua
inherits = "@(vre-roles-dir)/humanBase.lua";
displayLayouts = {
"@(vre-roles-dir)/displayLayouts/human1ScreenHorizontal.lua";
"@(vre-roles-dir)/displayLayouts/humanVrLayouts.lua";
};
components = {
["notifyLogic"] = {
componentType = "DtNotifyLogic";
};
};

This configuration demonstrates how to extend an existing role with additional components. The components table merges with the inherited components from humanBase.lua.

Configuration

To add this component to your own role, add the following to your role configuration Lua file (e.g., <VR-Engage-Install-Dir>/data/simulationModelSets/<YourSMS>/roles/yourRole.lua):

["notifyLogic"] = {
componentType = "DtNotifyLogic";
-- No additional configuration parameters required
};

The component monitors the standard weaponIndex attribute, which must be present in your role's attribute store. This attribute is typically populated by weapon system components in vehicle or human roles.

Testing Procedure

  1. Launch VR-Engage with the notification SMS as described above
  2. Start an unhosted session or connect to an existing exercise
  3. Create a human entity (the notification SMS configures only the Human role with the DtNotifyLogic component)
  4. Select the Human role from the role selection screen and attach to the entity
  5. Change weapons using your configured weapon selection input (default: mouse wheel or number keys)
  6. Expected Behavior: A notification overlay appears showing "Weapon #N", displays for 3 seconds, then fades out automatically. New notifications appear for each weapon change.

Verification: Check the VR-Engage log file (the most recent *.log file in the MAK log directory, typically C:/MAK/logs or as configured via the MAK_LOG_DIR environment variable) for initialization messages. Successful initialization shows [NotifyLogic] Component initialized, while missing attributes produce [Example Notify] Failed to find state attribute "weaponIndex".

Troubleshooting

Plugin not loading: Verify the DLL is in <VR-Engage-Install-Dir>\plugins64\vrEngage\release\, check the VR-Engage log (most recent *.log file in the MAK log directory) for load errors, and ensure the role configuration includes the component group.

No notifications appear:

  • Symptom: Component loads but no messages display when changing weapons
  • Cause: weaponIndex attribute not present in player attribute store
  • Solution: Verify role includes weapon system components that populate this attribute

Component not in role:

  • Symptom: Log doesn't show component initialization
  • Cause: Component group not added to role configuration
  • Solution: Add a ["notifyLogic"] component group with componentType = "DtNotifyLogic" to your role Lua file

Technical Reference

File Structure

examples/notification/
├── CMakeLists.txt # Build configuration
├── README.md # This documentation
├── plugin.h/.cxx # Plugin entry point
└── notifyLogic.h/.cxx # Notification component
<VR-Engage-Install-Dir>/data/simulationModelSets/examples/
├── notification.sms # Example simulation model set
└── notification/
└── roles/
└── human.lua # Human role with notifyLogic component

Key Classes

Class Base Class Purpose Header
DtNotifyLogic DtPlayerComponent Monitors attributes and displays notifications notifyLogic.h

API Methods Used

  • DtPlayerComponent::initialize() - Component lifecycle initialization
  • DtPlayerAttributeStore::hasAttribute() - Check attribute existence
  • DtPlayerAttributeStore::operator[] - Access attribute by name
  • DtAttributeCallbackCollection::connect() - Register change callback
  • DtPlayerStationTempNotification::newNotification() - Display timed notification
  • DtPlayerStationApp::tempNotification() - Access notification service

Build Targets

  • Plugin: exampleNotification.dll (Windows)
  • Install Location: plugins64/vrEngage/release/

Related Documentation: