//## begin module%1.4%.codegen_version preserve=yes
//   Read the documentation to learn more about C++ code generator
//   versioning.
//## end module%1.4%.codegen_version

//## begin module%3C236AF10192.cm preserve=no
//	  %X% %Q% %Z% %W%
//## end module%3C236AF10192.cm

//## begin module%3C236AF10192.cp preserve=no
//## end module%3C236AF10192.cp

//## Module: BM__PushPullComponentImpl%3C236AF10192; Pseudo Package body
//## Source file: B:\OEP\CMC\CMC__Model\CMC__BuildingBlocks\BM__PushPullComponent\BM__PushPullComponentImpl.cpp

//## begin module%3C236AF10192.additionalIncludes preserve=no
//## end module%3C236AF10192.additionalIncludes

//## begin module%3C236AF10192.includes preserve=yes
#ifdef _MSC_VER
#pragma warning (disable:4786)
#endif

#include "ace/SString.h"
#include "vector.h"
#include "UM__ConcurrencyUtilities/UM__LockMacros.h"
#include "ace/Thread.h"
#include "BM__Component/BM__ComponentInstrumentation.h"
#include "SystemConfigurator/CMC__ComponentConfigurator.h"
#include "BM__Component/BM__ExtLockingInitInterface.h"
//## end module%3C236AF10192.includes

// UUEventSupplier
#include "InfrastructureUtilities/EventServiceUtilities/UUEventSupplier.h"
// UUEventSet
#include "InfrastructureUtilities/EventServiceUtilities/UUEventSet.h"
// UUElements
#include "InfrastructureUtilities/ObjectStateUtilities/UUElements.h"
// UUEvent
#include "InfrastructureUtilities/EventServiceUtilities/UUEvent.h"
// UUIdentifier
#include "InfrastructureUtilities/ConfigurationUtilities/UUIdentifier.h"
// BM__PushPullComponentImpl
#include "BM__PushPullComponent/BM__PushPullComponentImpl.h"
// BM__ClosedFunctionalFacet
#include "BM__ClosedComponent/BM__ClosedFunctionalFacet.h"
// BM__ClosedComponent
#include "BM__ClosedComponent/BM__ClosedComponent.h"
//## begin module%3C236AF10192.additionalDeclarations preserve=yes

static
bool idInEventSet(const UUIdentifier& id, const UUEventSet& events)
{
   int length = events.GetLength();
   for (int i = 0; i != length; ++i)
   {
      UUIdentifier eventId;
      eventId.SetId(events[i].source_);    

//    if (eventId == id)
//    For now, only match the group ids to allow for
//    a recepticle component that is a synch proxy.
//    A final solution may require to take in account
//    that there may be multiple recepticles that 
//    connect to the same type of components.
      if (eventId.GetGroupId() == id.GetGroupId())
      {
         return true;
      }
   }
   return false;
}

//## end module%3C236AF10192.additionalDeclarations


// Class BM__PushPullComponentImpl 

BM__PushPullComponentImpl::BM__PushPullComponentImpl (const UUIdentifier& id)
  //## begin BM__PushPullComponentImpl::BM__PushPullComponentImpl%3C236B1A0173.hasinit preserve=no
  //## end BM__PushPullComponentImpl::BM__PushPullComponentImpl%3C236B1A0173.hasinit
  //## begin BM__PushPullComponentImpl::BM__PushPullComponentImpl%3C236B1A0173.initialization preserve=yes
      : BM__EmptyImpl(id),
        data1_(GetId().GetGroupId()),
        data2_(GetId().GetItemId()),
        count_(0),
        eventToSupply_(0),
        eventSupplierAdapter_(0),
        initLatch_(false)
  //## end BM__PushPullComponentImpl::BM__PushPullComponentImpl%3C236B1A0173.initialization
{
  //## begin BM__PushPullComponentImpl::BM__PushPullComponentImpl%3C236B1A0173.body preserve=yes
  //## end BM__PushPullComponentImpl::BM__PushPullComponentImpl%3C236B1A0173.body
}


BM__PushPullComponentImpl::~BM__PushPullComponentImpl()
{
  //## begin BM__PushPullComponentImpl::~BM__PushPullComponentImpl%3C236AF10192_dest.body preserve=yes
  //## end BM__PushPullComponentImpl::~BM__PushPullComponentImpl%3C236AF10192_dest.body
}



//## Other Operations (implementation)
unsigned int BM__PushPullComponentImpl::GetData1 () const
{
  //## begin BM__PushPullComponentImpl::GetData1%3C236B0E0125.body preserve=yes

   UM__GUARD_INTERNAL_REGION;
   
   BM__ComponentInstrumentation::ReceiveDirectCall(GetId(), "GetData1");
   
   return data1_;

  //## end BM__PushPullComponentImpl::GetData1%3C236B0E0125.body
}

unsigned int BM__PushPullComponentImpl::GetData2 () const
{
  //## begin BM__PushPullComponentImpl::GetData2%3C236B110338.body preserve=yes

   UM__GUARD_INTERNAL_REGION;
   
   BM__ComponentInstrumentation::ReceiveDirectCall(GetId(), "GetData2");
   
   return data2_;

  //## end BM__PushPullComponentImpl::GetData2%3C236B110338.body
}

void BM__PushPullComponentImpl::Update (const UUEventSet& events)
{
  //## begin BM__PushPullComponentImpl::Update%3C236B1401C1.body preserve=yes

   UM__GUARD_EXTERNAL_REGION(GetExternalPushLock());
      
   BM__ComponentInstrumentation::EventConsumer(GetId(), "Update", events);

   unsigned int tempData1 = GetId().GetGroupId();
   unsigned int tempData2 = GetId().GetItemId();

   std::vector<BM__ClosedComponent*>::iterator devIter = devices_.begin();
   std::vector<BM__ClosedComponent*>::iterator endIter = devices_.end();

   for (; devIter != endIter; ++devIter)
   {
      BM__ClosedComponent* component = *devIter;
      const UUIdentifier& id = component->GetId();

      if (idInEventSet(id, events))
      {
         const BM__ClosedFunctionalFacet& facet = component->ProvideClosedFunctionalFacet();
          
         BM__ComponentInstrumentation::SendDirectCall(GetId(), "Update", component->GetId(), "GetData1");
         tempData1 += facet.GetData1();
            
         BM__ComponentInstrumentation::SendDirectCall(GetId(), "Update", component->GetId(), "GetData2");
         tempData2 += facet.GetData2();
      }
   }
      
//   char buffer[20];
//   count_++;
//   sprintf(buffer, "%d", count_);

   UM__GUARD_INTERNAL_REGION;
   data1_ = tempData1;
   data2_ = tempData2;
   
  //## end BM__PushPullComponentImpl::Update%3C236B1401C1.body
}

void BM__PushPullComponentImpl::AddConnection (BM__ClosedComponent* item)
{
  //## begin BM__PushPullComponentImpl::AddConnection%3C236B160319.body preserve=yes
   devices_.push_back(item);
  //## end BM__PushPullComponentImpl::AddConnection%3C236B160319.body
}

void BM__PushPullComponentImpl::SetSuppliedEvents (UUEventSet& events)
{
  //## begin BM__PushPullComponentImpl::SetSuppliedEvents%3C236B2300C7.body preserve=yes
   eventToSupply_ = &(events[0]);
  //## end BM__PushPullComponentImpl::SetSuppliedEvents%3C236B2300C7.body
}

void BM__PushPullComponentImpl::SetEventSupplierAdapter (UUEventSupplier* eventSupplierAdapter)
{
  //## begin BM__PushPullComponentImpl::SetEventSupplierAdapter%3C236B2A025D.body preserve=yes
   eventSupplierAdapter_ = eventSupplierAdapter;
  //## end BM__PushPullComponentImpl::SetEventSupplierAdapter%3C236B2A025D.body
}

void BM__PushPullComponentImpl::StateUpdated ()
{
  //## begin BM__PushPullComponentImpl::StateUpdated%3C236B3200C7.body preserve=yes
   
   PushEvents();

  //## end BM__PushPullComponentImpl::StateUpdated%3C236B3200C7.body
}

XTypes::UInt32Min BM__PushPullComponentImpl::GetMaxStateSize ()
{
  //## begin BM__PushPullComponentImpl::GetMaxStateSize%3C236B4E02DA.body preserve=yes

   //Multiply by 2 to allocate for each data item (data1, data2)
   return (sizeof(data1_) * 2);
   
  //## end BM__PushPullComponentImpl::GetMaxStateSize%3C236B4E02DA.body
}

void BM__PushPullComponentImpl::InternalizeState (UUStream& stream)
{
  //## begin BM__PushPullComponentImpl::InternalizeState%3C236B53003A.body preserve=yes
   //for each data item, read it into a temporary buffer, then set it into the
   //appropriate attribute (which will copy the data in)
   UM__GUARD_COMPONENT_STATE;
   unsigned int buffer;
   
   stream >> buffer;
   data1_= buffer;

   stream >> buffer;
   data2_= buffer;

  //## end BM__PushPullComponentImpl::InternalizeState%3C236B53003A.body
}

void BM__PushPullComponentImpl::ExternalizeState (UUStream& stream)
{
  //## begin BM__PushPullComponentImpl::ExternalizeState%3C236B56004A.body preserve=yes
   
   UM__GUARD_COMPONENT_STATE;

   //use the stream operator to stream out data members.   
   stream << data1_ << data2_;
   
  //## end BM__PushPullComponentImpl::ExternalizeState%3C236B56004A.body
}

void BM__PushPullComponentImpl::InitializeExternalLock (UULockInterface& externalLock)
{
  //## begin BM__PushPullComponentImpl::InitializeExternalLock%3C72C033020C.body preserve=yes

   if (!initLatch_)
   {
      initLatch_ = true;
      //First put component's own lock in the list
      BM__EmptyImpl::InitializeExternalLock(externalLock);

      //Ask dependent components to place their lock in the list
      std::vector<BM__ClosedComponent*>::iterator devIter = devices_.begin();
      std::vector<BM__ClosedComponent*>::iterator endIter = devices_.end();
      for (; devIter != endIter; ++devIter)
      {
         ((*devIter)->GetExtLockingInit())->InitializeExternalLock(externalLock);
      }
      initLatch_ = false;
   }

  //## end BM__PushPullComponentImpl::InitializeExternalLock%3C72C033020C.body
}

void BM__PushPullComponentImpl::InitializeExternalPushLock (UULockInterface& externalPushLock)
{
  //## begin BM__PushPullComponentImpl::InitializeExternalPushLock%3C72C033023B.body preserve=yes
   // For now, use external lock list
   InitializeExternalLock(externalPushLock);
  //## end BM__PushPullComponentImpl::InitializeExternalPushLock%3C72C033023B.body
}

void BM__PushPullComponentImpl::PushEvents ()
{
  //## begin BM__PushPullComponentImpl::PushEvents%3C76DBDB020C.body preserve=yes
   
   if (eventSupplierAdapter_)
   {
      BM__ComponentInstrumentation::EventSupplier(GetId(), "PushEvents", *eventToSupply_);
      
      eventSupplierAdapter_->Push(*eventToSupply_);
   }
   
  //## end BM__PushPullComponentImpl::PushEvents%3C76DBDB020C.body
}

// Additional Declarations
  //## begin BM__PushPullComponentImpl%3C236AF10192.declarations preserve=yes
  //## end BM__PushPullComponentImpl%3C236AF10192.declarations

//## begin module%3C236AF10192.epilog preserve=yes
//## end module%3C236AF10192.epilog

