• Sonuç bulunamadı

5.5. Federelerin Oluşturulması

5.5.3. Tedarikçi federesi

5.5.3.1. Tedarikçi federesinin işleyişi

Tedarikçi federesinin görevi, üretici federesine B alt ürününü temin etmektir. Bu işlemi gerçekleştirebilmek için üretici federesinden bir takım bilgileri elde etmesi gerekmektedir. B alt ürününü üretmesi neticesinde oluşan bilgileri ise üretici federesine göndermektedir. Tedarikçi federesinin programının ana algoritması aşağıda verilmektedir:

void main(int argc,char *argv[]) { int i, Bid; Urun *obj; FederasyonaKatil(); OzellikTutamaciniAl(); OzellikleriYayimlaAboneol(); EtkilesimleriYayimlaAboneol();

for (i=0; i<10; i++)

{

cout<<"________________________________________________"<<endl; obj->SetSipAlindi(0);

obj->SetGuncellendi(0);

while ((!Urun::SipAlindi()) && (!Urun::Guncellendi()))

{ TickRTI(); } Bid=SiparisB(); BUrunuUret(Bid); BuretildiEtkilesimiGonder (); cout<<"___________________________________________"<<endl; SiparisSil(Bid); } FederasyondanAyril(); }

Ana programı yukarıda verilen tedarikçi federesinin işlem akış şeması Şekil 5.18’de verilmektedir.

Tedarikçi federesi çalışmaya başlamadan önce üretim federesi çalıştırılmış ise, URETIM federasyonu oluşturulmuş olacaktır. Ancak her ihtimale karşı tedarikçi federesi öncelikli olarak federasyonun oluşturulup oluşturulmadığına bakmaktadır. Eğer oluşturulmamış ise önce federasyon oluşturulur ve ardından federasyona katılma işlemi gerçekleştirilmektedir. Bu işlemi gerçekleştirmek üzere rti_arayuz.cpp dosyasında FederasyonaKatil() fonksiyonu tanımlanmış, ana programda ise bu fonksiyon kullanılmıştır.

FED dosyası içerisinde var olan HLA-OMT yapısındaki nesneleri C++ içerisinde kullanılabilir hale getirilmesi gerekmektedir. Bu amaçla OzellikTutamaciniAl() fonksiyonu geliştirilmiştir. Yine rti_arayuz.cpp içerisinde tanımlanan bu fonksiyon, ana programda hazır fonksiyon olarak kullanılmaktadır.

Tedarikçi federesinin ilgi duyduğu (abone olma) veya üzerinde işlem yapıp güncelleyeceği (yayımlama) nesne özelliklerinin ve etkileşimlerin federasyona haber verilmesi gerekmektedir. Hangi nesne özelliklerinin yayımlanıp hangilerine abone olunacağı OzellikleriYayimlaAboneol() fonksiyonu ile, hangi etkileşimlerin yayımlanıp hangilerine abone olunacağı ise EtkilesimleriYayimlaAboneol() fonksiyonu ile gerçekleştirilmektedir. Bunlar da rti_arayuz.cpp dosyasında tanımlanmışlardır.

Yukarıda yapılan işlemler ile tedarikçi federesi bir bakıma asıl algoritmaya hazır hale getirilmiştir. Tedarikçi federesinin çalışma şartlarını üretici federesine uygun hale getirmek için federe on iterasyon çalıştırılmıştır. Ana döngünün başına, üretici federesinden sipariş açıldığına dair bilginin ve üretici federesinde gerçekleştirilen güncellemelerin alınıp alınmadığını kontrol etmek için ilgili mantıksal değişkenlere aşağıdaki satırlar ile sıfır değeri atanmaktadır.

obj->SetSipAlindi(0); obj->SetGuncellendi(0);

Şekil 5.18. Tedarikçi federesinin işlem akış şeması BAŞLA Federasyon oluşturulmuş? Federasyonu oluştur Federasyona katıl FED dosyasından nesneleri al Özellikleri / Etkileşimleri yayımla ve abone ol B alt ürününü üret Sipariş alındı? (ve)

Güncelleme sağlandı? B siparişi sil Devam? Federasyondan ayrıl H E E H B alt ürünü üretildi etkileşimi gönder E H

Yukarıdaki fonksiyonlar, Urun.h dosyasında tanımlanmıştır ve sırasıyla “sip_alindi” ve “guncellendi” değişkenlerine değer atamaktadır. Daha sonra ana programda aşağıdaki döngü ile işlemlere devam edilip edilmeyeceği kontrol edilmektedir:

while ((!Urun::SipAlindi()) && (!Urun::Guncellendi())) {

TickRTI(); }

Bu ifadeler, sipariş alınmadığı ve güncellenme yapılmadığı müddetçe TickRTI() fonksiyonunu çalıştırılmaktadır. TickRTI() fonksiyonunun içerisinde bulunan rtiAmb.tick() komutu, federenin güncellenmesini temin etmektedir. Yani RTI’dan gelen (üretici federesi tarafından gönderilen) işlemler RTI elçisinin (ambassador) tick() fonksiyonu sayesinde işletilmekte ve sonuçlar tedarikçi federesine gelmiş olmaktadır. İşte bu esnada üretici federesinin güncellediği miktar, A alt ürününün başlama ve bitiş zamanları ile siparişin gönderilme etkileşimi tedarikçi federesinde karşılığını bulmaktatır. Yukarıdaki sonsuz döngü gibi görülen döngüden de bu şekilde çıkmak ve işlemlere devam etmek mümkün hale gelmektedir. Döngüden çıkma şartı, sipariş açıldı etkileşiminin alınması (sip_alindi = 1) ve güncellemelerin yapılmış olmasıdır (guncellendi = 1). İlgili değişkenlerin bir (1) değerini alması, tedarikçi federesinin elçi dosyası olan TedFederateAmbassador.cpp dosyasında gerçekleşmektedir. Sipariş alındığında receiveInteraction fonksiyonu tetiklenmekte, güncellemeler alındığında ise reflectAttributesValues fonksiyonu tetiklenmektedir. Bu fonksiyonlarının içerisine yazılan kodlar sayesinde ilgili değişkenlere bir (1) değeri atanmakta ve sonsuz döngüden çıkılmaktadır. Elçi dosyasının reflectAttributesValues fonksiyonunda bulunan aşağıdaki ifadelerden obj->SetGuncellendi(1) satırı ile “guncellendi” değişkenine bir (1) değeri atanmaktadır: if (attrHandle = = baszamanAID)

{

int basZaman,gbasZaman;

basZaman = ntohl(gbasZaman);

obj->SetABasZaman(basZaman);

cout<<"A Bas zaman alindi...: "<<Urun::ABasZaman()<<endl; obj->SetGuncellendi(1);

}

Benzer şekilde, elçi dosyasının receiveInteraction fonksiyonunda bulunan aşağıdaki ifadelerden obj->SetSipAlindi(1) satırı ile “sip_alindi” değişkenine bir (1) değeri atanmaktadır:

if (theInteraction = = siparisAcildiID) {

cout <<"Siparis acildi bilgisi alindi..." <<endl; obj->SetSipAlindi(1);

}

Güncellemeler sağlandıktan ve siparişin açılma etkileşimi alındıktan sonra program devam etmektedir. Sırada, B alt ürününün üretilmesi işlemleri vardır. Bu işlemler, Bid=SiparisB() ve BUrunuUret(Bid) fonksiyonları ile gerçekleştirilmektedir.

B alt ürününün başlama zamanı, siparişin açılma, dolayısıyla A alt ürününün başlama zamanı ile aynı olmaktadır. Bitiş zamanı ise miktar değeri ile üretim süresinin çarpılması sonucu elde edilmektedir. Bu bilgiler hesaplandıktan sonra değerlerin RTI kurallarına göre nesne özelliklerine atanması gerekmektedir. Ardından da üretici federesine bilgilerin gitmesini sağlamak için RTI’ın updateAttributeValues fonksiyonu kullanılmalıdır. İlgili işlemler BUrunuUret() fonksiyonu içerisinde aşağıdaki gibi tanımlanmıştır:

gbasZaman = htonl(basZaman); gbitZaman = htonl(bitZaman);

RTI::AttributeHandleValuePairSet *isimDegerSeti; isimDegerSeti = RTI::AttributeSetFactory::create(2);

isimDegerSeti->add(bitzamanBID , (char*)&gbitZaman, sizeof(gbitZaman)); try

{

rtiAmb.updateAttributeValues(RTI::ObjectHandle(id), *isimDegerSeti, NULL);

cout<<"B basZaman: "<<basZaman<<" B bitZaman: "<<bitZaman<<endl; }

catch (RTI::Exception&e) {

cerr<<"Baslangic ve Bitis Zamanlarini Guncellemede Hata: "<<&e<<endl; }

isimDegerSeti->empty(); delete isimDegerSeti;

Yukarıdaki ifadeler ile B alt ürününün üretilmesi ve bilgilerin güncellenmesi temsil edilmiştir. Daha sonra, B alt ürününün üretilmesinin bittiğini, etkileşim ile üretici federesine iletme işlemi gelmektedir. Bu işlemi BuretildiEtkilesimiGonder() fonksiyonu yerine getirmektedir. Hatırlanacağı gibi üretici federesi C ürününü üretmeye geçmeden önce tedarikçi federesinden bu etkileşimi alması gerekmekteydi. Buraya kadar ifade edilenler ile tedarikçi federesinin ana döngüsünün bir adımı gerçekleşmiş olmaktadır. Program yeniden ikinci adım için döngünün başına giderek üretici federesinden gelecek bilgileri bekleyecektir. Üretici federesi bu arada C ürünü üretmeyi bitirecek, federasyon zamanını C ürününün bitiş zamanına öteleyecek ve başa dönerek yeni sipariş açacaktır. Bilgiler karşılıklı iletilerek etkileşim sağlanacak ve federasyon bir bütün olarak işletilmiş olacaktır.