summaryrefslogtreecommitdiff
path: root/TAO/docs/tutorials/Quoter/RT_Event_Service/Stock_i.cpp
blob: d793656d19638b8d9f93baea99962c1c7a6b216d (plain)
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
// $Id$

#include "Stock_i.h"
#include <orbsvcs/orbsvcs/Event_Utilities.h>

///derive a class from the tie template class to release itself by ref_count
class MyTieStock:public POA_RtecEventComm::PushSupplier_tie<Quoter_Stock_i>
{
  friend class Quoter_Stock_i;
  ACE_Atomic_Op<TAO_SYNCH_MUTEX, long> ref_count_;

protected:
  MyTieStock (Quoter_Stock_i *tp,
              CORBA::Boolean release)
    : POA_RtecEventComm::PushSupplier_tie<Quoter_Stock_i> (tp,release),
      ref_count_(0) {}

public:
  virtual void _add_ref (ACE_ENV_SINGLE_ARG_DECL)
  {
    ++this->ref_count_;
  }

  virtual void _remove_ref (ACE_ENV_SINGLE_ARG_DECL)
  {
    CORBA::ULong new_count = --this->ref_count_;

    if (new_count == 0)
      delete this;
  }
};

Quoter_Stock_i::Quoter_Stock_i (const char *symbol,
                                const char *full_name,
                                CORBA::Double price)
  : supplier_personality_ (*new MyTieStock (this, 0))
{
  this->data_.symbol = symbol;
  this->data_.full_name = full_name;
  this->data_.price = price;
}

Quoter_Stock_i::~Quoter_Stock_i (void)
{
  if (consumer_proxy_.in ())
    consumer_proxy_->disconnect_push_consumer ();
}

char *
Quoter_Stock_i::symbol () throw (CORBA::SystemException)
{
  return CORBA::string_dup (this->data_.symbol.in ());
}

char *
Quoter_Stock_i::full_name () throw (CORBA::SystemException)
{
  return CORBA::string_dup (this->data_.full_name.in ());
}

CORBA::Double
Quoter_Stock_i::price () throw (CORBA::SystemException)
{
  return this->data_.price;
}

void
Quoter_Stock_i::set_price (CORBA::Double new_price)
  throw (CORBA::SystemException)
{
  this->data_.price = new_price;
  if (CORBA::is_nil (this->consumer_proxy_.in ()))
    return;

  // Create the event
  RtecEventComm::EventSet event (1);
  event.length (1);
  RtecEventComm::Event &e = event[0];

  // Initialize the header
  const char *symbol = this->data_.symbol;
  e.header.type = int(symbol[0]) << 24;
  e.header.type |= int(symbol[1]) << 16;
  e.header.type |= int(symbol[2]) << 8;
  e.header.type |= int(symbol[3]);
  e.header.source = 1;

  // Initialize the payload
  e.data.any_value <<= this->data_;

  // Push it
  this->consumer_proxy_->push (event);
}

void
Quoter_Stock_i::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
  throw (CORBA::SystemException)
{
  // Forget about the consumer it is not there anymore
  this->consumer_proxy_ =
    RtecEventChannelAdmin::ProxyPushConsumer::_nil ();
}

void
Quoter_Stock_i::connect (RtecEventChannelAdmin::SupplierAdmin_ptr supplier_admin)
{
  this->consumer_proxy_ =
    supplier_admin->obtain_push_consumer ();
  RtecEventComm::PushSupplier_var supplier =
    this->supplier_personality_._this ();

   const char *symbol = this->data_.symbol;
   CORBA::ULong type = int(symbol[0]) << 24;
   type |= int(symbol[1]) << 16;
   type |= int(symbol[2]) << 8;
   type |= int(symbol[3]);

   CORBA::ULong source = 1;
   ACE_SupplierQOS_Factory publications;
   publications.insert (source, type, 0, 1);

   this->consumer_proxy_->connect_push_supplier (supplier.in (),
                                                 publications.get_SupplierQOS ());
}

#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)

template class POA_RtecEventComm::PushSupplier_tie<Quoter_Stock_i>;

#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)

#pragma instantiate POA_RtecEventComm::PushSupplier_tie<Quoter_Stock_i>

#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */