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

#include "Stock_i.h"
#include <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 (void)
  {
    ++this->ref_count_;
  }

  virtual void _remove_ref (void)
  {
    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 (void)
  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 ());
}