% -*- latex -*-

\chapter{Virtual Objects}
\label{chap:VirtualObjects}

\index{virtual objects|(}
\index{objects!virtual|(}

\VTKm contains a base class called \vtkm{VirtualObjectBase}.
Any class built in \VTKm that has virtual methods and is intended to work in both the control and execution environment should inherit from \vtkm{VirtualObjectBase}.
Hierarchies under \vtkm{VirtualObjectBase} can be used in conjunction with \vtkmcont{VirtualObjectHandle} to transfer from the control environment (where they are set up) to the execution environment (where they are used).
For a refresher on the differences between the control and execution environments, please look back to Chapter~\ref{chap:GeneralApproach}.

In addition to inheriting from \vtkm{VirtualObjectBase}, virtual objects have to satisfy 2 other conditions to work correctly.
First, they have to be a plain old data type that can be copied with \textidentifier{memcpy} (with the exception of the virtual table, which \vtkmcont{VirtualObjectHandle} will take care of).
Second, if the object changes its state in the control environment, it should call \textidentifier{Modified} on itself so the \vtkmcont{VirtualObjectHandle} will know it update the object in the execution environment.
The following example shows a simple implementation of a \vtkm{VirtualObjectBase} that describes 2D shapes and determines whether a provided point is within a given shape.

\vtkmlisting{Using \textidentifier{VirtualObjectBase}.}{UsingVirtualObjectBase.cxx}

\begin{commonerrors}
  Certain devices will still correctly process a \vtkm{VirtaulObjectBase} derived object without calling \textidentifier{Modified} in the control environment to indicate that the data has changed.
  This is because certain devices utilize the same memory space for the control/execution environments and updates to the object in one space are reflected in the other.
  However, this will not work for all device types. 
  To implement code that will work for all device types it is important to call \textidentifier{Modified} whenever the control environment object's state is changed.
\end{commonerrors}

Virtual Objects implement the virtual methods, but a given \vtkmcont{VirtualObjectHandle} is what transfers those virtual method implementations into the execution environment.
Each \vtkmcont{VirtualObjectHandle} takes a template parameter, \textidentifier{VirtualBaseType}, which serves as the base class that acts as the interface.  
This base class must inherit from \vtkm{VirtualObjectBase}.

A derived object can be bound to the handle either during construction or using the \textidentifier{Reset} function on previously constructed handles.
These functions accepts a control side pointer to the derived class object, a boolean flag stating if the handle should acquire ownership of the object (i.e. manage the lifetime), and a type-list of device adapter tags where the object is expected to be used.

Once the handle is constructed, you can get an execution side pointer by calling the \textidentifier{PrepareForExecution} function.
The device adapter passed to this function should be one of the devices passed in during the set up of the handle.
The following example shows how to implement a \vtkmcont{VirtualObjectHandle} that utilizes the \textidentifier{ShapeType} \vtkm{VirtualObjectBase} extension implemented above.

\vtkmlisting{Using \textidentifier{VirtualObjectBase}.}{UsingVirtualObjectHandle.cxx}

\begin{didyouknow}
  Virtual methods are implemented in c++ using what is known as a virtual table.
  When a class is compiled, each class that implements virtual methods is given a virtual table pointer.
  This pointer references a structure that describes the physical address of the function that should be called for a corresponding virtual function call.
  It becomes difficult to maintain this virtual to physical linkage when transferring data to different devices since the physical addresses will differ on the other device.
  Thankfully, you don't have to worry about these details.
  \VTKm implements custom transfer functions for each device in order to support seamlessly moving virtual tables from the control environment to the execution environment.
  You can read Chapter~\ref{chap:ImplementingDeviceAdapters} for more information.
\end{didyouknow}

We can put the above concepts into practice by implementing a worklet that will utilize our \textidentifier{VirtualObject} implementations in an execution environment.

\vtkmlisting{Using \textidentifier{VirtualObjects}.}{UsingVirtualObject.cxx}

\index{objects!virtual|)}
\index{virtual objects|)}
