1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// MCpp_MulticamObjectWithSignalingImpl.h - MULTICAM C++ API - MulticamObjectWithSignalingImpl
#if !defined(__MCPP_MULTICAMOBJECTWITHSIGNALINGIMPL_H__)
#define __MCPP_MULTICAMOBJECTWITHSIGNALINGIMPL_H__
 
#include "MCpp_MultiCamObjectWithSignaling.h"
#include "containers.h"
#include "CCallbacks.h"
 
namespace Euresys
{
  namespace MultiCam
  {
    inline MultiCamObjectWithSignaling::MultiCamObjectWithSignaling() : CbReg(false)
    {
      Callbacks = new Euresys::MultiCam::Internal::AssociativeArray < Callback* > ();
    }
 
    inline MultiCamObjectWithSignaling::~MultiCamObjectWithSignaling()
    {
      if (Callbacks != NULL)
      {
        Callbacks->DeleteAll();
        delete Callbacks;
      }
    }
 
    // Callback dispatcher routine
    inline void MultiCamObjectWithSignaling::CbRoutine(PMCSIGNALINFO mcInfo)
    {
      SignalInfo info;
      Callback *cb = NULL;
 
      GetSignalInfo(mcInfo, &info);
 
      if (info.Signal <= 0 )
        return;
 
      cb = Callbacks->At(info.Signal);
      if (cb == NULL)
        cb = Callbacks->At(MC_SIG_ANY);
 
      if (cb != NULL)
        cb->RunUntyped(this, info);
    }
 
    // WaitSignal
    inline void MultiCamObjectWithSignaling::WaitForSignal(MCSIGNAL Signal, unsigned int Timeout, SignalInfo &Info)
    {
      MCSTATUS status;
      MCSIGNALINFO mcInfo;
 
      status = McWaitSignal(Handle, Signal, Timeout, &mcInfo);
      if (status != MC_OK)
        ThrowMultiCamException(status, TYPE_WAIT_SIGNAL);
      GetSignalInfo(&mcInfo, &Info);
    }
 
    // GetSignalInfo
    inline void MultiCamObjectWithSignaling::GetSignalInfo(MCSIGNAL Signal, SignalInfo &Info)
    {
      MCSTATUS status;
      MCSIGNALINFO mcInfo;
 
      status = McGetSignalInfo(Handle, Signal, &mcInfo);
      if (status != MC_OK)
        ThrowMultiCamException(status, TYPE_GET_SIGNALINFO);
      GetSignalInfo(&mcInfo, &Info);
    }
 
    // Convert MCSIGNALINFO to Euresys.MultiCam.SignalInfo
    inline void MultiCamObjectWithSignaling::GetSignalInfo(PMCSIGNALINFO mcInfo, SignalInfo *Info)
    {
      Info->Signal = mcInfo->Signal;
 
      if (Info->Signal == MC_SIG_SURFACE_FILLED ||
        Info->Signal == MC_SIG_SURFACE_PROCESSING)
        Info->Surf = GetSurface(mcInfo->SignalInfo);
      else
        Info->Surf = NULL;
    }
 
    inline void MultiCamObjectWithSignaling::RegisterCallbackInternal(Callback *cb, MCSIGNAL Signal)
    {
      if (Signal < 0)
        ThrowMultiCamException(MC_OUT_OF_BOUND, TYPE_REGISTER_CB);
 
      // Register the user callback
      if (Callbacks->At(Signal) != NULL)
        delete Callbacks->At(Signal);
      Callbacks->Assign(Signal, cb);
 
      // Register the global callback function (if necessary)
      if (!CbReg)
      {
        MCSTATUS status = McRegisterCallback(Handle, GlobalCallbackFunction, this);
        if (status != MC_OK)
          ThrowMultiCamException(status, TYPE_REGISTER_CB);
        CbReg = true;
      }
    }
 
    inline void MultiCamObjectWithSignaling::RegisterRawCallback(void *CbFunction, void *CbContext, int Signal)
    {
      if (CbFunction == NULL)
      {
        Euresys::MultiCam::Exception e(MC_INTERNAL_ERROR, "Invalid callback function");
        throw e;
      }
 
      Callback *cb = new Euresys::MultiCam::CFunctionCallback(CbContext, (PMCPP_C_CALLBACK)CbFunction);
      RegisterCallbackInternal(cb, Signal);
    }
 
    inline void MultiCamObjectWithSignaling::UnregisterCallback(MCSIGNAL Signal)
    {
      if (Signal < 0)
        ThrowMultiCamException(MC_OUT_OF_BOUND, TYPE_UNREGISTER_CB);
 
      // Unregister the user callback
      Callback *cb = Callbacks->At(Signal);
      Callbacks->Assign(Signal, NULL);
      delete cb;
 
      // Unregister the global callback function (if necessary)
      if (CbReg)
      {
        int i;
        int count = Callbacks->GetCount();
        for (i = 0 ; i <= count && Callbacks->At(i) == NULL ; i++);
        if (i > Callbacks->GetCount())
        {
          MCSTATUS status = McRegisterCallback(Handle, NULL, NULL);
          if (status != MC_OK)
            ThrowMultiCamException(status, TYPE_UNREGISTER_CB);
          CbReg = false;
        }
      }
    }
  }
}
 
#endif