3D dosyalar veya file formatlar 3D model ve scene’ler için bir databese’dir. 3D model/scene database’i algoritması kadar dinamik ve hızlı olacaktır.]]>
Video Game ve Metaverse sektörlerini
Bu makale’den önce The Story of Arsuite Immersive Intelligence makalesine bir göz atmanız iyi olabilir.
Arsuite yaklaşık 6 yıl süren çok uzun bir yolculuktan sonra olgunlaştı. Arsuite ilk başladığında Core Engine dışındaki her bileşen şimdiki topology’de 80% uygun şekilde tasarlanmıştı. Yani Arsuite’nin sahip olması gereken cloud-native alt yapı, Smart Asset Manager gibi sahip olacağı/olduğu bileşenler 2017 yılında ince ince ve detaylı olarak tasarlanmış ve planlanmıştı. Bugün 20% lik bir iyileştirme/değiştirme yapmış olsak da tüm platform ve platformun geleceği teknik kapasite 2017 de hesaplanmıştı.
Zaman zaman sıkıcı, korkutucu en çok da heyecanlı bu yolculuğun biraz uzun olmasının en büyük nedeni tüm ekibin hedeflere olan bağlılığıydı.
Şöyle düşünün, yeni bir platform ve engine geliştirmek istiyorsunuz. Siz geliştirmeye başladığınızda olukça yaygın ve neredeyse 25-30 yıldır kullanılan bazı engine ve platformlar var. Bunların kemikleşmiş bir alışkanlıkları ve toplulukları var. Siz tüm bunların dışında birşey yapmak istiyorsunuz. Ancak daha önce yapılmadığından elinizde örnek alabileceğiniz hiçbir başlangıç noktası yok. Sanırız işin en korkutucu yanı burasıydı.
Başlangıçta hızlıca bir MVP hazırlamak için meşhur game engine ve çeşitli platformlarla denemeler yaptık. Örneğin bir game engine’de sadece o platformun editöründen build alabiliyorsunuz, başka türlü alamıyorsunuz. Biz yaptığımız denemelerde o platformun editörünü bypass edip direk engine üzerinden build/export alabilir duruma gelmiştik. Mobile platformlar için özellikle Android platformlar için mobil uygulama geliştirmeyi de otomatize etmiştik. Kullanıcı birkaç parametre giriyor, template seçiyor ve ta-da Android AR App hazır. 2017-2018 aralığında WebAR çok erken evre olduğundan mobile app çözümleri aramıştık.
Paralelde 3D model algoritmaları, 3D model rendering ve loading algoritmaları üzerine uzun araştırma ve tartışmalar hiç eksik olmuyordu. Aslında game engine platformları ile yaptığımız testlerde çok şey öğrendik. Ancak bu testlerde iki paha biçilemez tecrübe edindik.
Arsuite ekibi enterprise dünyada uzun süre yazılım geliştirmiş cloud-native, modüler ve dinamik mimariler konusunda oldukça derin bir tecrübeye sahip olduğundan elde edilen sonuçlar kimseyi memnun etmiyordu. Ekip olarak amacımız sadece yeni bir engine ya da platform geliştirmek değil, gerçekten modern mimariler üzerine kurulmuş günümüz dünyasının ihtiyaçlarını karşılayan farklı bir engine ve platform yaratmak olduğundan testler oldukça çetin geçiyordu.
Günümüzde kullanıcılar her şeye her yerden her zaman erişmek istiyorlar. Tüm chat, foto, video, alış-veriş, bankacılık, ticaret ve video game gibi tüm ürünlerin internette yani cloud-native olmasını istiyorlar. Bu listeyi daha da uzatabiliriz ancak burada dikkat çekici nokta tüm bankalar gibi hantal sektörler bile cloud-native’e hızlıca adapte olmuşken teknolojinin merkesinde olan video game ve 3D endüstrisi hala ayak diremektedir.
Tamamen teknoloji ve yazılım üzerinden para kazanan Video Game ve 3D endüstrisinin kendilerini geliştirmek yerine kullanıcılardan binlerce dolarlık setup’lar istemesi traji-komik değil mi?
Arsuite olara yola çıktığımızda kendimize uzun bir soru/problem listesi yaptık. Örneğin herhangi bir tasarımcı bilinen game editorlerinden birisinde bir AR/XR sahne yaratıp bunu WebGL vb alt yapılarda web/mobile platformlara uyumlu olarak, ya da bir VR gözlüğü hedef alarak build alıp export edebilir. “Ancak bu tek parça ve statik bir APP şeklinde olacaktır.” Buraya kadar herşey süper, peki sonra?
Bizce problem bu aşamadan sonra başlıyor. Aşağıda sektörün önünde bloker olarak ortaya çıkan 10 tane temel soru listeledik. Ancak soruların sayısı buradakinden çok daha fazladır.
Bu sorular cevap ararken yaptığımız testler ve topluluklar ile görüşmelerimiz sonucunda temel problemin Video Game ve 3D endüstrisinin oyun ve 3D assetlere yaklaşım stratejilerinde olduğunu gördük.
Video Game ve 3D sektöründe 3D assetlere atomik data blokları olarak değil de monolith data blokları olarak yaklaşılıyor. Örneğin bir 3D model içerisine yeni bir birim/parça eklendiğinde bu yeni birim doğrudan o 3D modele eklemleniyor. Yani o modelin ayrılamaz/unmodüler bir parçası haline geliyor. Cloud-Native dünya’da modüler olmayan ürünlerin yaşama şansı çok azdır.
3D dosyalar veya file formatlar 3D model ve scene’ler için bir databese’dir. 3D model/scene database’i algoritması kadar dinamik ve hızlı olacaktır.
Reminder: Aslında Video Game ve 3D endüstrisinin 98%’i sadece kullanıcıdır. Yani bazı platform, game engine, game editör ve 3D designer araçları var ve bunlarla oyun ya da 3D model geliştirmeye çalışan kullanıcılar var. O nedenle çoğu kullanıcı atomik parçalarla ya da teknolojinin core mimarisi ile çok ilgilenmiyor.
Arsuite ise olaya çok farklı açılardan yaklaşmaktadır. Arsuite’de herşey dinamik ve güncellenebilir birer atomik veri bloğudur. Arsuite’de her asset kendi içerisinde ve büyük resimde SoC prensibi çerçevesinde atomik parçalara bölünerek saklanmakta ve yönetilmektedir. Böylece Arsuite’de herşey, her yerde ve her zaman plug-and-play olarak kullanılmaktadır.
Globalde yaygın birkaç 3D dosya formatını Arsuite/Arsx ile karşılaştırmalı inceleyelim. Bu karşılaştırmadan sonra neden Arsx sorusunu cevaplamaya çalışalım. Bu inceleme bir eleştiri değil, sadece bir analizdir.
USD/USDz dosya formatı bir 3D sahnede olması gereken tüm animasyon ve interaktif özellikleri taşıyabiliyor. Ancak usd tüm texture, material vb dataları tek bir dosyada tutuyor. Run-time’da değiştiremiyor ve sıkıştıramıyorsunuz. Arsuite/arsx dosya format ile 10MB olan bir AR sahnesi/3Dmodel usd formatında 80-100MB civarında olabiliyor. Ek olarak Usd/usdz yi draco vb bir algoritma ile sıkıştırabilirsiniz ancak iPhone telefonlarda AR olarak açamıyorsunuz. (.arsx, usd’den 8 kat küçük ve 14 kat hızlıdır.)
OBJ dosya formatı herşeyi düz bir text/string olarak tutuyor. Animasyon, pinteraktivite ve gelişmiş sıkıştırmayı desteklemiyor. Linkte görebileceğiniz 3 Million Polygons Sample – Aston Martin DBX örneğindeki araba modelinin .obj dosya formatındaki boyutu 445 MB’tır. Arsuite/arsx dosya formatındaki boyutu ise 65 MB’tır. (.arsx, obj’den 7 kat küçük ve ortalama 320 kat hızlıdır.)
FBX dosya formatı dataları LinkedList mimarisine yakın bir algoritmada tek bir dosyada tutuyor. Animasyon, interactivite ve binary compression gibi özellikleri destekliyor. Yine 3 Million Polygons Sample – Aston Martin DBX örneğindeki araba modeli .fbx binary compression ile 118 MB’tır. Arsuite/arsx dosya formatındaki boyutu ise 65 MB’tır. (.arsx, fbx’ten yaklaşık 2 kat küçük ve 30 kat hızlıdır.)
GLTF/GLB şu anda Arsuite/arsx rakip olarak gördüğümüz tek dosya formatıdır. Gltf, draco gibi bir algoritma ile sıkıştırıldığında şimdilik .arsx ten 10-30 % civarında daha küçüktür. Ancak her koşulda arsx load/render time olarak gltf ‘ten yaklaşık 10 kat daha hızlıdır.
Özetle, OBJ dosya formatı 1980’de, FBX dosya formatı ise 1996 yılında yayınlanmıştır. Bugüne kadar sektöre başarıyla hizmet ettiklerinden en yaygın iki dosya formayı olmayı başardılar. Bu dosya formatları için birçok güncelleme yapıldı. Ancak hiçbiri yapısal anlamda günümüz cloud-native gereksinimleri göz önünde bulundurularak yapılmadı. Cloud-Native mimariler için bu dosya formatları ile birçok ara çözüm üretilebilir ancak bu ara çözümler süreci daha da karmaşıklaştıracaktır, biz denedik, siz denemeyin.
Dosya formatı bu kadar önemli mi diyenler, sizi de duyuyoruz. Bu dosyalar 3D polygon ve assetler için birer database’dir. Database ve data algoritamalarının önemine değinmeye bile gerek yok. Siz database’inizi ne kadar iyi seçer ve kurgularsanız elde edeceğiniz sonuçlar o kadar şaşırtıcı olacaktır. Bu bağlamda Arsx kendine has data mimarisi ve dynamic asset loading vb özellikler ile çok daha farklı bir konumdadır. Örneğin .arsx 3D modele ait sadece temel bilgileri özel bir algoritma ile tutmaktadır.
Arsuite & Others Comparison Table daki average speed kolonuna bakmanızı rica ederiz. Buradaki testler 1.5 milyon polygona sahip bir 3D model ve Nvidia GTX860 ekran kartı ile yapılmıştır. Arsuite Youtube kanalında videosunu bulabilirsiniz.
Arsuite/arsx engine ile diğerleri arasındaki gerçek fark dosya boyutu büyüdükçe ortaya çıkmaktadır. Örneğin 1.5 milyon polygona sahip bir .obj 3D modelin load/render zamanı 320sn civarında iken 3 milyon polygona sahip bir obj 3D modelin load/render süresi 960-1200 saniyelere çıkmaktadır. 1.5 milyon polygona sahip aynı 3D modelin Arsuite/arsx load/render süresi sadece 1 saniye iken 3 milyon polygona sahip aynı modelin Arsuite/arsx load/render süresi sadece 1.1-1.2 saniye arasındadır. Yani dosya boyutu büyüdükçe Arsuite/Arsx engine ailesinin gerçek gücü ortaya çıkmaktadır. This is the Magic.
Burada sadece Obj, Fbx, Usd, Gltf dosya formatlarını inceledik. Dikkat ederseniz sadece bu 4 dosya formatı bile mimari, boyut ve hız açısından birbirinden çok farklıdır. Arsuite/arsx ile olan performans farklılıklarından yola çıkarak kendi aralarındaki farkları hesaplayabilirsiniz. Piyasada 60 dan fazla 3D model dosya formatı var, hepsinin temelde birbirine benzer algoritmalara sahip olduğunu söyleyebiliriz. En önemli nokta cloud/stream based web/mobile oyun ve uygulamaları için uygun değillerdir. Hepsi 3D modelleri monolith bir data blok olarak oluşturmaktadır.

Günümüzde dinamik olduğunu iddia eden tüm platformlar dinamik bir 3D sahne yaratırken tüm 3D model, texture ve materyalleri 3D sahne içerisine koymakta, bake/build/export almaktadır. Örneğin bir sandalye için XR sahnesine ihtiyacımız olsun. Bu sandalye 10 farklı ahşap, 10 farklı kumaş’a sahip olsun. Çapraz kombinasyonları yok sayarak 20 farklı görünüm yaratıldığını varsayalım. Bu durumda matematik şöyle oluşacaktır.
Bu durumda XR app’imiz toplamda 120 texture/materyale sahip olacaktır. Bu rakamlar minimize rakamlardır. Daha yüksek bir görüntü kalitesi istediğinizde bu rakam 240’a kadar çıkacaktır. Bu sandalye XR app’i kullanıcıya gönderilmek istenildiğinde tüm materyal ve assetler tek bir app/dosya içerisinde tek bir paket olarak gönderilecektir.
Oyuncu ya da son kullanıcı belki de hiç kullanmayacağı birçok dosyayı download etmek zorunda kalacaktır. Belkide bir kullanıcı olarak bana sadece 2 farklı deseni denemek yeterli olacaktı. Bu durumda 3D model ve 8-10 texture’dan sonra benim başka dosyaya ihtiyacım kalmayacaktı. Ancak 3D model + 120 dosya indirmek zorunda kaldım. 3D designer’lar bilirler ki yüksek kaliteli texture’ler 3D modellerden daha büyük dosya boyutlarına sahiptirler. Bir son kullanıcı olarak ben neden 7-8mb yerine 100-240 mb dosya indireyim?
Daha kötüsü bu 3D sahne/model/app artık değiştirilemezdir. Yani sonradan yeni bir desen/texture eklemek istediğinizde bu app’i yeniden bake/build/export almak zorundasınız. Kullanıcı ise en güncel sahne için tüm app’i yeniden indirmelidir. Günümüz cloud-based dünyada değiştirilemez/güncellenemez statik asla data kabul edilemezdir. Arsuite/Arsx bu ve buna benzer birçok soruna çözüm olarak geliştirilmiştir ve geliştirilmeye devam etmektedir.
Hangi mühendislik alanında olursanız olun yeni, farklı ve daha gelişmiş birşeyler yaratmak isteyen herkes projesine en temelden başlamalıdır. En atomik parçaları yaratmak zorunda olmasak da en atomik parçaları iyice özümsemeli, içlerinden en uygun olanı seçip projeye öyle başlanmalıdır.
Arsuite olarak biz de kendi data mimarimizi ve cloud platformumuzu en temelden tasarlayıp sıfırdan yaratmak zorunda kaldık. Bazı bileşenlerin hazır olmasını çok isterdik ancak maalesef böyle bir şansımız olmadı.
Arsuite/Arsx sadece 3D modele ait temel bilgileri taşıyan bir veritabanıdır. Hiçbir detay ve sahiplik bilgisi barındırmaz. Örneğin texture, materyal veya animasyon gibi bileşenler Arsx’e run time ‘da yüklenir. Bu sayede Arsx her zaman, her şartta çağrıldığı sahne gereksinimlerine göre şekillenir. Bu yükleme yöntemi core yazılım mühendisliğinde Dependency Injection ile benzerlik gösterir. Ancak Arsuite olarak biz buna Dynamic Asset Loading diyoruz. Arsuite Platformunda sadece Arsx değil her bileşen dinamik ve modülerdir. Arsuite’de herşey atomik modüller olarak ele alınır ve her atomik bileşen run time’da sahneye yüklenir.
Dynamic Asset Loading modülarite ve cloud-native işlemler için çok elzem bir özelliktir. Dynamic Asset Loading sadece mikro işlemlerde olduğu kadar makro işlemlerde de harikalar yaratmaktadır. Geliştirdiğimiz bu teknoloji sayesinde 3D sahne ve modelleri çok küçük paraçalara bölerek modül modül istediğimiz istediğimiz yere hızlıca iletebilmekteyiz. Küçük parçalar olarak ele alınan 3D sahneler modüler olarak kullanılacakları yerde run-time’da birleştirilip kullanılmaktadır.

Arsuite 3D dünyanın farklı gereksinimleri ve performans kaygıları nedeniyle hazır cloud servisleri kullanmamaktadır. Arsuite globalde değişik lokasyonlarda kendisine ait serverlar üzerinde cloud service provider olarak hizmet vermektedir.
Arsuite server-side rendering yapmamaktadır. Her Arsuite/Arsx sahne client cihazlarında run-time’da load ve render edilir. Bu kural en küçüğünden en büyüğüne kadar tüm sahneler için geçerlidir. Client Side Rendering Arsuite/Arsx engine ailesinin en önemli alameti farikalarındandır.
Eğer altyapınız ve teknolojileriniz özel olarak tasarlanmamış ve top-nutch optimizasyonlara sahip değilse Hyper-Realistic ya da Photo-Realistic sahnelerin client-side yaratılması oldukça zorlayıcı olabilir. Yüksek kaliteli dosyaların client’a ulaştırılması, client’ta load/render edilmesi ve client’lar arasındaki iletişimi yönetmek için özelleştirilmiş akıllı araçlar geliştirmelisiniz.
Assetlerin sınıflandırılamsı ve yönetilmesi Video Game ve 3D dünyasında geliştirme ve tasarım yapan herkesin çok yakından bildiği bir problemdir. Dosyaların büyüklüğü ve çeşitliliği assetlerin yönetimini güçleştirmektedir.
3D file formatların birer database olduğunu söylemiştik. Çok büyük ve monolith 3D dosyalar/database’ler aslında 3D dünyadaki bu dosya/veri çeşitliliğini yönetebilmek için ortaya çıkmıştır diyebiliriz. Bir 3D model/sahne için 3D mesh, texture, material, rig ve animasyon gibi birçok bilgi gerekmektedir. Bu kadar çok ve farklı özelliklere sahip verilerin yönetilmesi sıkıntılı bir süreçtir. Game developer ve 3D designer’in bu gibi konularla vakit kaybetmemesi gerektiğinden 3D design tool geliştiricileri 3D dosya formatlarını tüm bu datayı içinde tutacak şekilde geliştirmeyi tercih etmişlerdir. Bu tercih o günün şartlarında iyi bir çözüm olsa da bu günün cloud-native dünyasının kurallarına uyum sağlayamamaktadır.
Arsuite smart ve centralized asset manager bir 3D sahne için gerekli olan 3D mesh, texuture, material, skybox ve animatiom gibi bileşenleri unique ve çok gelişmiş bir algoritma ile dağıtık olarak saklar ve yönetir. Örneğin yukarıdaki gibi bir sandalye 3D modelini Arsuite’ye bir kez yükleyip milyonlarca 3D sahne içerisinde kullanabilirsiniz. Bu sandalyeyi her sahne içinde farklı bir texture veya material kombinasyonu ile kullanabilirsiniz.
Arsuite bu sahnenin oluşması gerekli tüm data ve assetleri distrubited olarak değişik yerlerde saklar. Client/Kullanıcı bu sahneyi incelemek istediğinde aSAM tüm bileşenleri bulur ve bir stream şeklinde kullanıcıya gönderir. Tüm render ve load işlemleri client/kullanıcı makinasında run time’da yapılır.
Cloud-Native ve Distributed bir ürün geliştiriyorsanız load balancing hayatınızda oldukça önemli bir yere sahip olacaktır. Load balancing ürünler basitçe platformlar üzerindeki yük dağılımını yönetrler. Ancak buraya kadar sık sık ifade ettiğimiz nedenlerle cloud gaming ve 3D dünyada geleneksel bir load balancing ürünü çok yetersiz kalacaktır.
Örneğin bir oyuncu herhangi bir noktadan bir oyuna bağlandığında LB o oyuncuyu en uygun server’a yönlendirecektir. 3D dünya ve game’ler klasik web sitelerinden oldukça farklıdır. 3D dünya ve game’lerde kullanıcılar veya oyuncular sürekli bir aksiyon ve birbirlleri ile iletişim içinde olmalıdırlar. Singapur’daki bir oyuncu ile İngiltere’deki bir oyunun birbirleri ile en hızlı ve kesintisiz şekilde iletişimde halinde olmaları gerekebilir. Bu durumda klasik LB lerin yapacağı hiçbir şey yoktur. Bu kesintisiz bağlantıyı kurmak için daha farklı ve akıllı çözümlere ihtiyaç vardır.
Arsuite smart Connection Router herhangi bir kullanıcı/oyuncuya sisteme giriş yaptığı andan çıkış yaptığı ana kadar yardımcı olur ve bağlantısını yönetir. Server ile kullanıcı arasındaki en iyi bağlantıyı kurarken oyuncular arasındaki tüm bağlantıların sağlıklı ve adil olmasını da sağlar. aTUBE tüm client-server bağlantıları ile server durumlarını sürekli olarak kontrol eder ve en iyi bağlantı performansının sağlandığından emin olur. Örneğin X oyunundaki A oyuncusu ile B oyuncusunun sahip olduğu bağlantı hızları oyun kalitesini ve fair-play’i etkileyecek seviyede ise oyunları uyarır ya da match etmez.
3D assetleri ve dataları atomik olarak dağıtık mimaride sakladık, client-server ve client-client bağlantılarını oldukça optimize şekilde kurduktan sonra geriye data’ları kullanıcılara göndermek kalıyor. Gönderilecek datalar çok çeşitli, 3D ve büyük boyutlarda olacağından daha dikkatli ve farklı yaklaşılması gerekiyor. Arsuite Smart Stream API client’ın cihaz özelliklerine ve bağlantı gücüne bağlı olarak 3D sahneleri ve assetleri client’a gödermektedir. Örneğin yukarıdaki sandalye bir kullanıcıya 2K texture ve 2K skybox ile gönderilirken başka bir kullanıcıya 4K texture ve 4K skybox ile gönderilebilir.
Arsuite ai-powered bir platform değildir. Arsuite platformu oldukça gelişmiş bir AI’dır.
3D sahnelerin tasarımından, client’a ulaştırılmasına kadar her bir adım Arsuite akıllı araçları tarafından izlenmekte ve yönetilmektedir.
Şöyle bir örnek verelim. Bir A kullanıcısı herhangi bir T anında X sahnesini çağırdığında unique bir key üretilir ve bu key ile A kullanıcısının tüm hareketleri izlenir. Bu izleme esnasında kullanıcı her zaman en kesintisiz düğüm noktasına ve uygun server’a yönlendirilir. Kullanıcı deneyiminde bir hata varsa sistem anında uyarı üretir ve kullanıcı en iyi servise yönlendirilir. Böylece kullanıcının/oyuncunun en iyi hizmeti alması sağlanır. Oluşan hatalar senaryo bazlı olarak uçtan-uca takip edilebildiğinden anında çözüm üretilir.
Reminder: Bu izleme sadece kullanıcı deneyimini iyileştirmek için yapılan anonim bir izlemedir. Kullanıcın kişisel bilgileri hiçbir zaman bu izlemenin scope’u içerisinde değildir.
Arsuite, Architecting Tomorrow’s Immersion, Today!
Alper Akalin
]]>
Okyanusun iki farklı ucundaki buzdolapları birbiri ile veri alışverişi yaparken video oyunlarının ya da Metaverse’lerin birbiri ile veri alış verişi yapamaması, yapmaması kadar aptalca birşey olamaz değil mi? ]]>
Günümüzde teknoloji ile ilgisi olsun olmasın Endüstry 4.0 ve IoT (nesnelerin interneti) kavramlarını duymayan kalmamıştır. Bu trend akımlara göre çok kısa bir süre içerisinde üretim tamamen otomatize (robotic) olacak, dünyadaki tüm elektronik aletler, robotlar vs birbiri ile konuşabilecek, iletişim kurabilecektir. Uç bir örnekte UK deki Leo’nun evindeki buzdolabı ile Brezilyadaki Juila’nın buzdolabı konuşacak, bilgi paylaşacak ve en iyi saklama koşulları için fikir alış verişinde bulunabilecektir.
Aslında burada gerçek bir yenilikten söz etmek mümkün değildir. Ancak burada çok büyük bir entegrasyon ve birlikte çalışabilirlik (interoperability) söz konusudur. Bunun için kurulacak ağ ve alt yapı gerçekten heyecan verici ve muazzam bir devrimdir.
Okyanusun iki farklı ucundaki buzdolapları birbiri ile veri alışverişi yaparken video oyunlarının ya da metaverse’lerin birbiri ile veri alış verişi yapamaması, yapmaması kadar aptalca birşey olamaz değil mi?
Arkadaşlar mevcut teknolojilerle ve game enginelerle şu anda bu yapılamamaktadır, bazı durumlarda yapılmamaktadır. Evet, aptalca ama durum böyle. Ticari kaygılarla ve büyük yoğunlukla teknik kısıtlarla günümüzde video game’ler arasında bir entegrasyon veya iletişim kurulamamaktadır.

Modern dünyadaki yeni trendler ve Metaverse yaklaşımının ortaya çıkması ile birlikte gelecekte tüm oyunlar arasında kesinlikle birçok entegrasyon kurularak birbirleri ile çalışmaları ve konuşmaları sağlanacaktır. Örneğin, oyuncular sahip oldukları bir oyun karakteri ile bir oyundan diğerine kolayca geçebileceklerdir.
Aslında her oyun kendi içinde bir Metaverse olduğundan metaverse’ler arasında veri alışverişi ve birlikte çalışabilirlilik (interoperability) elzemdir.
Diğer türlü Metaverse’lere ve game’lere her yerden erişim mümkün olmayacak ve bunlar arasında bir entegrasyon ve birlikte çalışabilirlilikten asla söz edilemeyecektir. Bu da metaverse killer, game broken bir durumdur.
Gelecekteki tüm immersive metaverse’ler ve belirli düzeyde game’ler için geliştirme ve özellikle erişim platformları (arayüzleri) no app required olarak cloud-native tasarlanmalı ve aşağıdaki özellikleri içermelidir.

Şu anda dünyada kullanılan oyun ve metaverse tasarım, geliştirme ve yayınlama yapılan platformların, editörlerin ve ürünlerin 95% i desktop ya da mobil uygulamalardır. Tasarım, geliştirme ve yayınlama yapmak için devasa editörler dowload etmek ve kullanmak zorundasınız. Geliştiriciler kendi bilgisarlarında tasarım, geliştirme ve yayınlama yapmalıdırlar.
Örneğin bazı yaygın game engine’leri kullandığınızda tasarım için koskoca bir game engine ve editörü download etmeniz gerekmektedir. Bu editörleri kullanarak bir şeyler yarattığınızda ise o sahneleri build-export alarak küçük app ler üretmeniz gerekmektedir. Bu küçük APP’lerin yönetilmesi ve kullanıcıya ulaştırılması oldukça karmaşık ve zorlu bir süreçtir.
Hatırlatma: O game engineler AR, XR, VR, Metaverse sahneleri oluşturmak için yaratılmadı. Bu nedenle onlarla çalıştığınızda gereksiz bir çok kod ve/veya asset’le uğraşmak zorunda kalacaksınız. Asıl önemli o engineler hiçbir zaman sizin yaptıklarınıza odaklanmayacaklar çünkü onlar game odaklılar.
Arsuite şu anda dünyadaki ilk ve tek tamamen cloud native çalışan 3D design & development platformdur. Arsuite’ye ait tüm engine ve servislere tamamen cloud-native olarak erişilir tüm web browser’lardan tüm Arsuite servisleri çalışır.
Arsuite alt yapısı yukarıdaki diagramda özetlenmiştir. Bu alt yapı 2017 yılında kurgulanmış ve 2018 ‘in ikinci yarısında tümüyle aktif edilmiştir. Sizler de benzer bir platform kurmak istiyorsanız kesinlikle cloud-native olmalı ve dilerseniz bu diagramı kullanabilirsiniz. Elbette ticari ve alan kısıtlamaları nedeniyle bu diagramda temsil edilmeyen birçok özellik bulunmaktadır.
Arsuite platformunda geliştirme veya yayınlama gibi hiçbir işlem için application indirilmesine gerek yoktur. Her şeye, her toola ve her ürüne no app required olarak herhangi bir web/mobile browserdan, herhangi bir yerden anında erişilebilir.
3D, AR, XR, VR ve Metaverse ürünlerinin hızlı yaygınlaşması için erişiminin kolay olması gerektiği gibi tasarım ve geliştirme süreçlerinin de kolay olması gerekmektedir. Bu bağlamda çok derin bir 3D ve yazılım geliştirme tecrübesi olmayan kişilerin de sürece dahil edilmesi elzemdir. No-Code tasarım araçları tam da burada devreye girmektedir.
No-code yazılım geliştirme toolları ile ilgili oldukça fazla reklam ve makale ile karşılaşmışsınızdır. Bu no-code toolların tamamında 30-60% aralığında kod yazmanız gerekmektedir. Yani belli bir yazılım geliştirme tecürebesi gereklidir. Arsuite ise tamamen 100% no-code tasarım araçları sunmaktadır. Dilerseniz custom script yazmanıza da izin vermektedir.
Globaldaki birçok firma ya da platform aksini iddia etse de aslında static App-Driven bir alt yapı sunmaktadırlar. App-Driven yaklaşım ile yaratılan bir sahneye ait tüm bilgiler, 3D model, material ve texture’ler küçük bir uygulama içerisine kaydedilir. Yani App-Driven model de yaratılan her bir 3D, AR, XR, VR ya da Metaverse sahnesi ayrı ayrı birer APP olarak tasarlanmakta, geliştirilmekte ve yayınlanmaktadır.
Bu app’i download eden kullanıcı ya da tasarımcı sadece uygulamada ön tanımlı özelliklerin izin verdiği kadar işlem yapabilir. Bu sahneye yeni bir model, material ya da texture eklenmesi gerektiğinde sahneni yeni bir uygulama olarak baştan-sona tekrar yaratılması ya da güncellenmesi gerekmektedir.
Bir tek 3D model için aynı anda (AR + XR + Metaverse) sahnesi yaratmak istiyorsanız o tek 3D model için en az 3 farklı sahne APP üretmelisiniz. Eğer platform bazlı optimizasyon yapmak isterseniz (PC + Mac + iOS + Android) için farklı APP’ler üretmek zorunda kalabilirsiniz. Yani 3 x 4 = 12 farklı APP üretilmesi gerekmektedir. Bu da geliştirmeyi, güncellemeyi, yayınlamayı, kullanmayı ve kullanım sonucunda oluşan verileri analiz etmeyi zorlaştırmaktadır.
Örneğin, 1000 lerce ürün ya da sahnenin olduğu/olacağı bir e-ticaret platformu olsun. Bu platformdaki 1000’lerce ürün için 1000’lerce APP yaratmak, yayınlamak ve güncellemek pek akıllıca bir yatırım olmayacaktır.
Bu sahne APP lerinin yaratıldığı platformda bug veya hata olduğunda ya da platform da bir güncelleme yapıldığında büyük ihtimalle bu sahne APP lerinin doğru çalışabilmesi için tekrar yaratılmaları ya da tek tek güncellenmeleri gekecektir. Sonuç olarak;
Olası 12 APP güncellemesi gerekebilek senaryoyu sevmediniz, biliyoruz. Ama durum app-driven modelde başka çareniz yok.
Data-Driven yaklaşım ile ile yaratılan bir sahneye ait tüm bilgiler, 3D model, material ve textureler dağıtık veri kümeleri olarak kaydedilirler. Kullanıcı bir sahneyi incelemek istediğinde o sahneye ait bilgiler anlık olarak bu dağıtık veri kümelerinden toplanır ve işlenir.
Arsuite geleceğin data-driven / big data ve AI mimarilerine uygun tasarlanmıştır. Tüm 3D, AR, XR, VR ya da Metaverse’ye ait bilgiler ile bir APP oluşturulmaz ya da bu bilgiler bir APP içerisinde tutulmaz. Sahnelere ait tüm 3D model, material, asset veya textureler çok gelişmiş modern bir mimari içerisinde çeşitli database’lerde dağıtık olarak tutulurlar. Aslında tüm Arsuite platformunu tek bir AI gibi düşünebiliriz.
Arsuite AI kulanıcının cihazına ve network bağlantısına bağlı olarak kullanıcıya göndereceği dataya, data miktarına karar verir ve gönderir. Bu zeka Arsuite’ye inanılmaz bir, hız ve esnelik kazandırmaktadır. Arsuite’de App-Driven modelde olduğu tekrarlı app’ler yaratmaz, yayınlamaz ve maintaince etmez. Arsuite her şeyi bir data-stream olarak ele alır ve tek merkezden yönetir.Örneğin, Arsuite en iyi kullanıcı deneyimini sağlamak için kullanıcının cihaz gücüne ve network bağlantısına bağlı olarak; kullanıcıya göndereceği texture kalitesi gibi birçok parametreye kendi karar verip göndereceği data’yı optimize etmektedir.
App-Driven Model – 3D, AR, XR, VR & Metaverse Development Flow

Global pazardaki çözümlerin tamamında basit bir Augmented Reality sahne yaratıldığında bile bir APP yaratılmakta ve yayınlanmaktadır. Her yeni 3D, AR, XR, VR ya da Metaverse sahne yaratıldığında yukarıdaki döngü işletilmekte ve APP ler yaratılmaktadır. Bu sahnelerden birinde güncelleme gerektiğinde o sahneye ait APP buradaki akış içerisinde tekrar yaratılmalıdır.
Gelecekte gerçekten bir sürükleyici bir Metaverse olacaksa bu kesinlikle concrete App-Driven Model içerisinde olamaz.
Dynamic Data-Driven Model – 3D, AR, XR, VR & Metaverse Development Flow

Kullanıcı herhangi bir cihazda Arsuite’den bir 3D sahne açmaya başladığı anda o sahneye ait assetler sahneye yüklenmekte ve render edilmektedir. Sahne açma işlemi başlamadan önce o sahne bir bütün, bir küme, bir app şeklinde herhangi bir yerde tam olarak kayıtlı değildir. Yani Arsuite’de hiç bir aşamada önceden üretilmiş pre-baked edilmiş bir APP vb componenet yoktur.
Arsuite de herşey dinamik ve data driven mimaride çalışmaktad ve üretilmektedir. Bu da Arsuite’nin bir sahneye ait tüm assetleri gerçekten dinamik olarak gerçekten real time’da sahneye yüklenmesini sağlamaktadır.
Sahne açma isteği geldiğinde Arsuite Sürükleyici Zeka o sahneye ait bilgileri ve asetleri farklı konumlardaki server ve database’lerden toplar, birleştirir ve kullanıcıya gönderir. O sahne gerçek real-time da kullanıcının makinesinde yaratılır.
Dynamic Asset Loading, herhangi bir 3D sahneye Real-Time ya da Run-Time’da yeni bir özellik eklenebilmesi ya da var olan bir özelliğin anında değiştirilebilmesidir. Örneğin sahneye herhangi bir T anında yeni 3D model eklenebilmeli ya da sahnenin ışık vb özellikleri anında değiştirilebilmelidir.
Assetleri gerçek anlamda dinamik olarak yüklemek için tüm platform alt yapısının buna uygun olması gerekmektedir. Aksi durumda dynamic asset loading çalışmayacaktır.
Uyarı, Run-Time/Real-Time rendering ile Dynamic Asset Loading konuları birbirlerinden tamamen farklıdır, lütfen karıştırmayınız.
Real-Time Rendering bir sahnenin önceden değil doğrudan çalışma zamanında render edilmesi yöntemidir. Real-Time Renderin sahnenin nasıl yaratıldığı ile çok ilgilenmez. Var olan “static” sahneyi render eder ve kullanıcıya sunar.
Dynamic Asset Loading’te sahneye ait sadece bazı parametreler, bilgiler, materialler, assetler, gaz ve toz bulutları vardır. Bu bilgiler real-time’da toplanır, işlenir, render edilir ve kullanıcıya sunulur. Herşey dinamik bir data bloğu ya da data stream’i olduğundan kullanıcıya çok hızlı ulaştırılır ve kullanıcının run-time’da herhangi bir T anında değişiklik yapmasına izin verilir.
Takdir edersiniz ki App-Driven modelde yani önceden app olarak üretilmiş bir 3D sahnede gerçek bir Dynamic Asset Loading’ten söz edilemez.
Global pazardaki platformların büyük çoğunluğu static asset loading prensibi ile çalışırken bir kısmı dinamik asset loading mimarisini desteklediğini iddia etmektedir. Kısmi olarak dinamik asset loading’i destekleseler de Arsuite ile karşılaştırılamazlar.
O platformlar sadece bir yöntemle sahnede real-time ya da run-time da kısıtlı değişiklik yapabilmektedirler. Bunun için sahnede bazı özellik ve materialleri parametrik olarak geliştirip sahneyi öyle bake/build ediyorlar. Bu parametrelere bağlı olarak sahnede bir dinamiklik efekti yaratıyorlar. Ancak yine de tüm herşey o sahneye ait app içerisinde tanımlı olmak zorunda. Bu parametrelerin dışında bir istek geldiğinde gelen isteği işleme alamıyolar yani dinamik efekt kayboluyor. Yani gerçek anlamda real-time dynamic asset loading’ten söz etmek mümkün değildir.
Arsuite içerisinde assetler dinamik olarak gerçek real-time’da sahneye yüklenmektedir. Yani kullanıcı herhangi bir cihazda Arsuite’den bir 3D sahne açmaya başladığı anda o sahneye ait assetler sahneye yüklenmekte ve render edilmektedir. Sahne açma/render işlemi başlamadan önce o sahne bir bütün olarak herhangi bir yerde kayıtlı değildir. Yani sahne yoktur. Sahne, Arsuite platformu içerisinde dağıtık data mimaride data kümeleri olarak saklanmaktadır.
Sahne açma isteği geldiğinde Arsuite Sürükleyici Zeka o sahneye ait bilgileri farklı konumlardaki server ve database’lerden toplar, birleştirir ve kullanıcıya gönderir. Sahne real-time da kullanıcın makinesinde yaratılır.
Gelecekte gerçekten bir sürükleyici bir Metaverse olacaksa bu kesinlikle Data-Driven Model içerisinde olacaktır. Diğer türlü bu Metaverse’lere her yerden erişim mümün olmayacaktır. Metaverse’ler arasında bir entegrasyon ve birlikte çalışabilirlilikten asla söz edilemeyecektir. Bu da daha yaygınlaşamadan Metaverse’leri öldürecektir.

Buna karmaşık 3D dünyasının ilk, tek ve akıllı CMS’i diyebiliriz. Karmaşık 3D, AR, XR, VR ve Metaverse tasarım ve geliştirmesi için gerekli tüm model, material ve texturelerin yönetildiği intelligent ve centralized content management sistemidir.
Örneğin, 3D sahnelerdeki en önemli bileşen 3D modellerdir. iCAM’in en önemli özelliklerinden ya da avantajlarından bir tanesi, bir 3D model clouda bir kere yüklendikten sonra tekrar bir yükleme yapmaya gerek olmadan milyon tane farklı sahnede kullanılabilir. Yani tekrarlı yüklemeye gerek yoktur. Bu hem storage’den hem paradan tasarruf sağlamaktadır.
iCAM, Arsuite Dynamic Data Driven Infrastructure’nin en önemli yapı taşlarından bir tanesidir. Data & File stream konusunda mucizevi işlere imza atmaktadır. Çok iyi kurgulanmış, geliştirilmiş ve çok hızlı çalışan akıllı bir CMS olmadan dinamik, data-driven bir alt yapı kurulamaz ve işletilemez.

Arsuite Engine, ARSX ‘in özelliklerini en iyi şekilde ortaya çıkaran 3D renderin/loading ve 3D web game engine’mizdir. Örneğiş aşağıdaki test senaryosunu ele alalım.
Arsuite Engine + ARSX, .fbx tabanlı enginelerden en az 30 kat .obj tabanlı enginelerden en az 320 kat, .gltf tabanlı enginelerden en az 8 kat, .usdz tabanlı enginelerden en az 12 kat hızlıdır. Bu benchmark yukarıdaki koşullarda yapılmıştır.
Model boyutu veya modeldeki polygon sayısı büyüdükçe aramızdaki hız farkı katlanarak artmaktadır.
Patent kaygıları ile burada sıralayamadığımız bir çok özellik sayesinde Arsuite dünyanın en hızlı 3D engine’sine sahiptir.
App-Driven modelde herhangi bir 3D sahne için bir 3D sahne ve bu sahne için bir APP yaratılmaktadır. Bu milyonlarca 3D sahne için milyonlarca APP yaratılması demektir. Böyle bir durumda oluşacak data miktarı, iş yükü ve kaynak tüketimi inanılmaz boyutlarda olacaktır.
Burada oluşan kaynak israfı şirketlere çok fazla gereksiz maaliyet getirecek, gereksiz kaynak tüketiminden dolayı çevreye çok fazla zarar verecektir. Gelecekte herşeyin 3D ve Immersive olacağı düşünüldüğünde bu şekilde sorumsuzca ve aptalca üretilen datayı 5G değil direk 6G gelse bile taşıyamayacaktır.
Günümüzde birçok platform ya da firmanın oluşan bu 3D datayı doğru tasarlayamadığına ve yönetemediğine inanıyoruz. Aşağıdaki makalelerde şu anki 2D standartlarında günlük olarak inernete yüklenen datayı ve Arsuite’nin 5G/6G teknolojilerine bakış açısını görebilirsiniz.
Sihir nedir? 5G/6G ya da yeni nesil GPU/CPU’lar vaat edilen kurtarıcılar mıdır?
How Much Data Is Created Every Day? [27 Staggering Stats]
How Much Data is Created on the Internet Each Day?
Arsuite, architecting tomorrow’s immersion, today!
Alper Akalin
]]>
Magic is just a word for all the things that haven't yet discovered. We don't speculate on the magic. We create it! Arsuite Immersive Intelligence]]>
Bu makalede günümüzde yaygın olarak kullanılan hiçbir teknolojiyi eleştirmeyeceğiz. Bizce onlar kendi işlerini oldukça başarılı bir şekilde yapıyorlar. Biz onlardan ve onları yanlış kullananlardan o kadar çok şey öğrendik ki hepsine ne kadar teşekkür etsek azdır.
Aşağıdaki linkteki makale sizlere Arsuite’nin doğuşu hakkında, yeni nesil bir teknoloji platformunun nasıl yaratıldığı veya bir platformun yaratılacağı hakkında yararlı bilgiler sunabilir.
Arsuite Immersive Intelligence
Bu makalede günümüzde yaygın olarak yanlış yerde ve yanlış şekilde kullanılan teknolojileri ve kullananları hiç çekinmeden eleştireceğiz. Çünkü o yanlışların faturalarını biz de ödüyoruz. Örneğin çok güzel teknolojileri yanlış yerde kullanmaya çalışarak hiçbir şey üretemeyen, başaramayan insanların “Immersive ve Interactive 3D XR, VR, AR” teknolojilerinin yaygın kullanımı için 5G bağlantı hızına ve yeni nesil CPU/GPU’lara ihtiyacımız var demesinden bıktık. XR, VR, AR için yaratılmamış ve optimize edilmemiş bir game engine üzerinde yarattığınız sahnelerden nasıl bir sonuç veya nasıl bir başarı bekliyorsunuz anlamış değiliz. Haydi bu saçma balonu birlikte patlatalım.
5G gelse de, yeni nesil işlemciler yaratılmış olsa da data işleme ve streaming mimarisini iyi kurgulamış bir alt yapı her zaman sizden önde olacaktır. Siz tüketiciye bir sahne ya da bir tane 3D model gönderirken birileri 10 tane 3D sahne ya da 3D modeli aynı anda gönderecektir. Çok güzel bir arayüz ya da sahne tasarlayabilirken, o sahneyi minimal kaynak tüketimi ile nasıl stream veya render edeceğinizi bilmiyorsanız, 5G hızlarına ve next-gen CPU/GPU’lar ihtiyacımız var diyeceksiniz. Yok kardeşim lazım değil.
Şu anda AR/VR teknolojileri göreceli olarak dünyanın daha gelişmiş bölgelerinde daha yaygın kullanılıyor. Mevcut bağlantı hızlarında multi-user interactive VR/AR deneyimi için hiçbir engel yoktur. Şöyle bir örnek verelim video call toplantı yaparken herhangi bir gecikme yaşıyor musunuz? Hayır! (lütfen extreme hat kopmalarını göz ardı ediniz, bunlar 5G/7G de olacaktır.)
Hemen şu itiraz gelecektir. “Ama biz sadece bir video stream etmiyoruz, koca bir virtual dünyayı stream ediyoruz.” O zaman streaming mimarinizi ya da alt yapınızı gözden geçirmelisiniz. Bir şeyleri kesinlikle yanlış yapıyorsunuz.
Herhalde 5G ile gelmesi beklenen en büyük yeniliğin 1ms nin altındaki latency değerleri ve çok yüksek bant genişliği olduğunu duymayan kalmamıştır. Bu bir mucize midir, değil midir? Da Vinci Surgical System üzerinden 5G yi inceleyelim.
Evet, 5G böyle bir sistem için mucizedir. Bu sistem ile Amerikadaki bir cerrah Çindeki bir hastaya anında müdahele edebilir. Ancak mevcut 4G/4.5G teknolojilerinde edemez. Neden?
5G nin alameti farikası bandwidth genişliğinden gelir. Yani çok düşük gecikme ile çok yoğun ve büyük bir datayı yerden bir yere gönderebilirsiniz. Bunu bir fizikçi edası ile elektro manyetik dalga teoremleri ile açıklamayı çok isterdik. Kafa karıştırmayalım değil mi?
Bu durumda 5G yi şöyle basitleştirebiliriz. Elimizde tek kanallı bir kablo olsun. Bu kablonun iç yapısını ince bir boru şeklinde olduğunu varsayalım. Bu borudan aynı anda 5 belki 50 tane 8K filmi hiçbir gecikme olmadan çok uzaktaki bir arkadaşımıza gönderebiliriz. Böylesi yoğun data transferlerini mevcut 4G/4.5G teknolojisi destekleyemiyor. Ancak 5G de yakında gelecek gibi durmuyor.
Da Vinci Surgical System de Amerikadaki bir doktor Çindeki bir hastaya müdahele ederken ya da ameliyat ederken işlem yaptığı bölgeyi mümkün olan en yüksek netlik kalitesinde mümkün olan en kısa gecikme ile görebilmelidir. Aksi durumda operasyon başarısız olabilir ve hasta kaybedilebilir. Buradan hareketle Da Vinci Surgical System ‘i 4K ya da 8K kalitesindeki bir görüntüyü neredeyse sıfıra yakın bir gecikme ile Çin’den Amerika’daki doktora gönderebilmelidir. Amerika’daki doktor da operasyon bölgesine müdahele komutu verdiğinde bu komutunda neredeyse sıfıra yakın bir gecikme ile Çin’e gönderilmesi gerekmektedir. İşte bu sistemin sorunsuz olarak çift yönlü çalışması bir mucizedir.
Metaverse örneğini ela alalım. Bu Metaverse günümüzdeki gibi düşük kalitede aşırı low poly değil, “Ready Player One” daki gibi photorealistic, sürükleyici ve kusursuz olsun. Ek olarak bu Metaverse’de milyonlarca kişi aynı anda aktif olsun. Bu Metaverse’de oluşacak data trafiğini hayal edebiliyor musunuz?
Böylesi extreme örneklerde 5G’ye ihtiyacımız vardır. Ancak optimize edilmemiş platformlar 5G’de de beklenen şekilde çalışmayacaktır. Kesin bilgi!
Arkadaşlar peşinen söyleyelim yok!
Örneğin ismi AR dünyasında herkesçe bilinen çok meşhur AR gözlük üreticisi vardır. Sanırız 2010 de kuruldular. Bir dönem market değerlemeleri 6 milyar dolara kadar yükseldi. Sonra hızla 400 milyon dolara kadar düştü. Şimdilerde körfez sermayesi desteği alarak market değerlemelerini birkaç milyar dolara kadar çıkardılar. Buraya kadar herşey mükemmel. İnişli çıkışlı olsa da bir yatırım toplama başarı hikayesi yarattılar. Kimse itiraz edemez. Ancak yatırım toplamadaki başarı hikayesini bir teknoloji başarı hikayesine dönüştüremediler. Neden?
İlk olarak aşırı bir şekilde animation, interaktivite gibi jan janlı özelliklere odaklandılar. Market yaratma ve consumer isteklerinden dolayı böyle bir yöntem seçmiş olabilirler. Ancak bu makale yazıldığı tarihte hala çalışan bir gözlük satabilmiş değillerdi.
Kullandığınız eski yöntemler ya da teknolojilerle yarattığınız animatif AR, interaktif XR gibi immersive 3D sahnelerin oluşturacağı işlemci, memory, storage ve network yükünü hesaplamazsanız ya da hesaplayamazsanız bunları stream edemez ya da herhangi bir cihazda çalıştıramazsınız. Sadece After Effect ile yaratılmış projeksiyon videoları paylaşırsınız. Şu anda dünyada birçok firmanın yaptığı sadece video paylaşmaktır.
Buradaki game changer nokta kullandığınız tasarım ve geliştirme araçlarının neredeyse tümü sizlerin kullanmak istediği amaçlar için yaratılmadı. Yani bir game engine ‘den web ya da mobile browserlar için en üst seviyede optimize edilmiş herhangi bir immersive 3D sahne üretmesini bekleyemezsiniz. O game enginelerin de biz bunu yapıyoruz dememeleri de lazım ama yapıyoruz diyorlar.
Bizim açımızdan immersive dünyadaki birçok kritik hata çözümün yanlış yerde aranmasından kaynaklanmaktadır. Günümüzde yaygın olarak kullanılan 3D desing, rendering tooları ve game engineler genelde 2000 lerde ortaya çıkmışlardır. Bu bir sorun mu? Değil!
Sorun 2000 lerdeki teknik ve donanımsal kısıtlamalar nedeniyle veriye bakış açımız ve verileri tutma şeklimiz oldukça farklıydı. Aslında 2000 lerde datayı yazmak yani kaydetmek ile ilgili çekincelerimiz vardı demek daha doğru olur. O dönemde donamımlar yetersiz ve pahalı olduğundan kullanılmayacağını düşündüğümüz hiçbir datayı kaydetmezdik. Hatta gerekli olanları kısaltarak kaydettiğimiz günler de olmuştur. Bugün düşününce ya da böyle pat diye söyleyince baya komik geliyor.
Günümüzde ise neredeyse her şeyi kaydediyoruz, hatta kaydetmeyeni dövüyoruz. Bugün bir datayı kaydetmemek ya da silmek o datayı saklamaktan daha pahalı hale geldi. 20 yılda teknolojinin geldiği durum bu iken 2000 lerin bakış açısı ile yazılmış ve core parçaları hala o dönemin izlerini taşıyan uygulama ve frameworkler ile yeni bir şeyler yaratılamayacağı aşikardır. (öyle ise ne yapmak nereye varmak istenmektedir.)
Yanlış yaklaşımlar ve yapılan hatalar sonucunda immersive, interactive ve 3D “AR, XR, VR, Metaverse” teknolojilerinin kusursuz çalışması için 5G ya da yeni nesil CPU/GPU’lara ihtiyacımız var diyemezsiniz. İspatlayalım!
Var olan, yaygınlaşmış ve kabul görmüş teknolojilere uyumlu ürünler tasarlamak yerine; uyum problemi olan ürünler geliştirirseniz. Sonuç hüç şüphesiz hüsran olacaktır. İşin trajikomik tarafı bu ürünleri yeni bir teknoloji yaratmadan, yaygın kullanılan eski teknolojiler ile yaratmaya çalışıyorsunuz. Yani yaygın ve sık kullanılan teknolojilerle sıra dışı ama uyumsuz ürünler yaratmaya çalışıyorsunuz. Çalışmayın!
Massive data processing, data streaming ile 3D model, “AR ,XR, VR, Metaverse” teknoloji platform alt yapıları geliştirmek birbirlerinden çok farklı disiplinlerdir. Dersinize çalışın!
Yukarıdaki videoyu biraz konuşalım ve sonrasında globalde yaygın olan AR, XR, VR ve Metaverse tasarlama ve geliştirme yöntemlerini tartışalım.
150K polygon 3D model + 2K texture + 4K HDRI Skybox özellikerine sahip bu 3D “AR/XR” sandalye sahnesi Arsuite Designer Studio’da tasarlanmıştır. 3D sahne 10-12 MB sahne boyutuna sahiptir. Sizler sandalyeyi XR ve AR de inceleyebilirsiniz. Biz sadece AR üzerinden konuşacağız.
Sandalyeyi incelerken lütfen download ve açılma hızına dikkat ediniz. Biz 100 Mbit bağlantı hızında herhangi bir mobil cihazda 300-350 ms gibi bir sürede bu sahneyi download edip görüntüleyebiliyoruz.(download + render edebiliyoruz.) Bu sürenin 85-90% network gecikmesine 10-15% gibi bir sürede 3D model ve sahnedeki materyallerin render edilmesine harcanmaktadır. (iOS kullanıcıları için render süresi değişmezken, Apple’in kaprislerinden dolayı download süresi iki katına kadar çıkabilir.)
Bu benchmark sonuçlarına göre Arsuite Engine ile yaratılmış bir 3D sahnenin indirilme ve açılma süresi aynı boyuttaki tek bir 2D jpeg/png dosyasının indirilip açılmasından daha kısa sürüyor diyebiliriz?
Sandalye bir sahil kenarında çimler üzerine yerleştirilmiştir. Sandalyenin altına dikkatlice baktığınızda sandalyenin gölgesinin çimlere düştüğünü görebilirsiniz. Sandalyenin üzerine baktığınızda süngerin üzerindeki kanallardaki gögeleri görebilirsiniz. Sandalyeyi döndürdüğünüzde veya büyüttüğünüzde gölgenin de değiştiğini veya büyüdüğünü görebilirsiniz.
Sandalyeye yaklaşıp uzaklaşırken kameranın etkilendiği ışık ve çevresel etkiler de değişmektedir. Video da gördüğünüz üzere bu ışık değişiklikleri anında sandalye üzerine yansıtılmaktadır. Gölge ve texture renk aralığı anında bu değişikliğe cevap vermektedir.
Tasarımda 85 cm olarak belirlenen sandalyenin boyutu AR sahnede 4 metreye kadar çıkarılmıştır. Sandalyenin boyutundaki böylesine extreme değişikliklere rağmen sadalyenin formu ya da görüntü kalitesi bozulmamıştır.
Sandalyenin boyutu 5 kat büyütülmüşken, sandalyenin bir ayağı üzerindeki ağaç desenine ve desen üzerindeki oyuklara odaklanmak için sandalyeye yaklaşıldığında sandalye üzerindeki texture’un kalite seviyesi net olarak görülmektedir. Sandalye AR ile 5 kat büyütülmesine rağmen texture bozulmamıştır. Hatta sandalyenin bu ayağı yakınındaki gerçcek bir ağaç ile de karşılaştırılmıştır.
Sandalye gerçek boyutuna yani 85 cm’ye düşürülüp yanına yaklaşılarak tekrar sandalye textureleri incelenmiştir. Bu incelemede sandalyenin ayağı üzerindeki ağaç desenine ve desen üzerindeki oyuklara odaklanıldığında yine mükemmel seviyede görüntü kalitesi ve netliği elde edilmiştir. Yani texture orijinal boyutunda iken sandalyenin bir noktasına yaklaşmak suretiyle yapılan zoom’da da görsellik mükemmel ötesi durumdadır.
E hani photorealistic, yüksek görsel kalitesine sahneler için 5G lazımdı? 150K polygon + 2K texture + 4K HDRI Skybox ‘a sahip bir sahne ile bunları yapabiliyoruz. Peki 5 milyon üzeri polygon + 4K texture + 4K HDRI Skybox ile neler yapabileceğimizi hayal edin? Evet, bunu da yapabiliyoruz, hem de sadece birkaç saniye içerisinde.
Peki böylesine kaliteli bir AR, XR sahnesi yaratıp tüm dünya ile paylaşmak için ne yapmalıyız? Aslında ne yapmamalıyız?

Globalde yaygın olarak kullanılan AR, XR, VR, Metaverse tasarım ve geliştirme araçları ve API’ler genelde başka uygulamalarla birlikte çalışan plugin ya da extensionlar olarak karşımıza çıkmaktadır. Örneğin bir game engine IDE’sine ya da bir başka tasarlama aracına bir plugin eklenerek AR, XR, VR, Metaverse sahneleri yaratılmaktadır. Kendi başına çalışan az sayıda uygulama olsa de yaygın kullanıma çok uygun değildirler.
Bir başka platformda çalışan bir plugin ile tasarlanıp geliştirilen AR, XR, VR, Metaverse sahneleri doğal olarak o platform ait gereksiz code parçalarını ve varsa zayıflıklarını taşımaktadırlar.
Örneğin yukarıdaki sandalye gibi bir XR ve AR sahnesini böyle bir plugin üzerinden yaratmış olsaydık; XR ve AR için ayrı ayrı tasarım ve geliştirme yaparak export etmeliydik. (Export önemli bir keyword.)
Sandalye aynı anda WebXR ve WebAR özelliklerine sahip. Bu durumda XR sahne için bir tasarım yapmalı ve bir uygulama üretmeliydik. AR sahne için ise ayrıca bir tasarım yapmalı ve bir uygulama üretmeliydik. Yani bir AR, XR sahne için en az iki kere tasarım, geliştirme yapacaktık ve elimizde en az iki farklı uygulama olacaktı.

Her bir AR, XR, VR sahnesi için her bir sahneyi ayrı ayrı tasarlamak, geliştirmek, export almak, bulut sunucusuna yüklemek, test etmek (dev test) ve test etmesi için müşteriye göndermek (UAT) zorundayız.
Eğer yanlış bir tasarım yaptıysak ya da müşteri tasarımımızı beğenmedi ise her şeyi yeniden tasarlamak, geliştirmek, export almak, bulut sunucusuna yüklemek, test etmek ve test etmesi için tekrar müşteriye göndermek zorundayız.
Kaçınılmaz olarak bu akışı bizden istenen tüm AR, XR, VR sahneleri için gerekirse tekrar tekrar işletmek zorundayız. 5G gibi teknolojileri beklemeden bu akışı birkaç kere işletmek zorunda kalan tasarımcılar, geliştiriciler, kullanıcılar veya müşteriler bir müddet sonra AR, XR, VR, Metaverse teknolojilerinden zaten vazgeçiyorlar.
Kim, neden, bu kadar karmaşık ve uzun bir tasarım geliştirme sürecine katlansın ki? Sanki 5G sızlanması yapmadan önce yapılacak çok daha başka ve çok daha önemli işlerimiz var.

Yukarıdaki sandalyeyi baz alarak ilerlemeye devam edelim. 150K polygon 3D model + 2K texture + 4K HDRI özelliklerine sahip üç tane farklı application yaratmamız gerekmektedir. Bu da tasarım, geliştirme ve yayınlama süreçlerini inanılmaz karmaşıklaştırıken cloud server’da saklanacak ve yayınlanacak data miktarını da aşırı derecede artıracaktır. Optimizasyon eksikliği, uygulamalara gereksiz kod ekleme gibi çeşitli nedenlerle bu uygulamaların boyutu olması gerekenin birkaç katından fazla olacaktır. Çok geç kalma 5G ve yeni nesil işlemci.
Makale de buraya kadar geldiyseniz artık sizin de koyu bir 5G takipçisi olduğunuza eminiz. Bu kadar yanlış kurgulanan bir modelde göreceli olarak büyük boyutlara sahip olabilecek AR, XR, VR, Metaverse sahnelerini 5G ve yeni nesil işlemciler olmadan sağlıklı çalıştırabilmek mümkün değil. Belki de buraya kadar anlatılan tasarım ve geliştirme yöntemlerini kesinlikle kullanmamalısınız!
Buraya kadar tartıştıklarımızdan anlaşılacağı üzere bir yeni bir 3D “AR, XR, VR, Metaverse” geliştirme modeline ihtiyacımız var. Bu yeni modelin modern data işleme yöntemlerini benimsemesi, cloud-native sistemleri desteklemesi elzemdir. Bu yöntemleri destekleyecek platform mümkünse;
Arsuite’deki daha gelişmiş özelliklerle bu listeyi daha fazla uzatabiliriz. Şimdilik bu kadarla yetinelim. İsterseniz sizler yoruma kendi önerilerinizi ekleyebilirsiniz. En azından Arsuite olarak kesinlikle dikkate alacağız.
Böyle bir platformu yaratmak, yaratmaya başlamak başkalarının yeni teknolojiler yaratmasını beklemekten çok daha iyidir. Örneğin 5G için kurulması gereken GSM baz istasyonlarını düşününce beklemeniz gereken sürenin ne olacağı tahmin edilemez. Tabi ki beklemek de bir tercihtir, bazıları 3D “AR, XR, VR, Metaverse” nin yaygınlaşması için yeni teknolojileri bekleyebilirler. Ama o gün geldiğinde 7G/8G’yi beklememiz gerekiyor diyeceklerinden eminiz.
Böyle bir platform geliştirmek istediğimizde aşağıdaki sorulara cevap bulmanız gerekecektir.

Bir çok insan 3D “AR, XR, VR, Metaverse” gibi büyük datalar taşıyacak ileri teknolojilerin yaygınlaşması için gelecekte hizmete sunulacak teknolojilere ihtiyaç olduğuna inanıyor.
Daha yüksek bağlantı hızları ya da yeni nesil daha gelişmiş işlemcilere sahip olsak bile internette dolaşan veri miktarındaki bu artış hızı ile her zaman maksimum seviyede optimize edilmiş yazılım, platform ve cihazlara ihtiyacımız olacak. Hele de gelecekte internette dolaşan dataların 3D “AR, XR, VR, Metaverse” özellikleri ile daha yoğun ve daha büyük boyutlara sahip olacağı düşünülürse 5G değil 7G gelse bile ortaya çıkacak veri yükünü kaldıramayabilir.” Law of action and reaction. Sir Isaac Newton.”
Hepimizin bildiği üzere günümüzde internette dolaşan ve yüklenen veri miktarı her geçen gün katlanarak artmaktadır. Yani her geçen gün insanlar daha fazla veriyi internete yüklemektedir. Aşağıdaki linklere tıklayarak internete yüklenen veri mikarı ile ilgili globalde yapılan bazı araştırmaları inceleyebilirsiniz. Bu araştırmalara göre optimize edilmemiş sistemlerin yaratacağı problemleri hayal edin!
How Much Data Is Created Every Day? [27 Staggering Stats]
How Much Data is Created on the Internet Each Day?
Aşağıdaki makale Arsuite’nin alt şirketlerinden bir tanesi Threedfy Immersive Omniverse geliştirme takımı tarafından hazırlanmıştır. Geleneksel teknolojilerle 10.000 tane 3D AR, XR, VR özelikli sahne yaratıldığında oluşacak veri miktarına dair senaryolar tartışılmaktadır. Böylesine aşırı büyük verilerin çok yaygın ve sıradan olacağı bir gelecekte gerekli data ve data streamign optimizasyonları yapılmaz ise 5G bile yetersiz kalacaktır.
Anında 10.000 Adet NFT Nasıl Yaratılır? “An Extreme Comparison”
Arsuite ve Threedfy ana sayfalarına girerek geleceği yani photorealistic AR, XR örneklerini şimdiden test edebilirsiniz. Aşağıya sandalye linkini tekrar bırakıyoruz. Sonraki makalelerimizde yukarıdaki maddeleri tek tek açıklayacağız. Bundan sonraki ilk makalemizde Data Driven Engine konusunu tartışacağız.
The Magic depends on your perspective!..
The Arsuite Team
]]>
Microsoft 10 Aralık 2019’da Windows Mobile 10 işletim sistemine destek vermeyi kesti. O tarihten sonra bu işletim sistemini kullanan hiç bir telefon yazılım güncellemesi alamaz hale geldi. Gerçi hala Microsoft Store erişimi olduğu için bir takım yazılımları edinip kullanmak mümkün, ancak bu yazılımlar arasında artık WhatsApp, Instagram, Facebook, Twitter gibi günlük hayatta sıkça kullanılan pek […]]]>
Microsoft 10 Aralık 2019’da Windows Mobile 10 işletim sistemine destek vermeyi kesti. O tarihten sonra bu işletim sistemini kullanan hiç bir telefon yazılım güncellemesi alamaz hale geldi. Gerçi hala Microsoft Store erişimi olduğu için bir takım yazılımları edinip kullanmak mümkün, ancak bu yazılımlar arasında artık WhatsApp, Instagram, Facebook, Twitter gibi günlük hayatta sıkça kullanılan pek çok popüler yazılım yok. Buna rağmen telefon etmek, fotoğraf çekmek, İnternete girmek, telefonun 3G/4G mobil internetini paylaşıma açmak ve trafik bilgisini de içeren navigasyon olarak kullanmak mümkün. Navigasyon konusu gerçekten ilginç, çünkü Windows Mobile 10 cihazlardaki Here Maps navigasyon yazılımı en güncel haritaları indirip kullanabiliyor ve trafik bilgisini de aynen Google Maps ya da Yandex’te olduğu gibi gerçek zamanlı olarak gösterip buna göre en uygun güzergahı belirleyebiliyor. Yani yıl 2022 olmuş hala Windows Mobile 10 kullanılır mı demeyin, bu telefonları sıra dışı basit ama şık kullanıcı arayüzleri ve genellikle renkli tasarımları ile kullanmak mümkün
Gelelim bu yazının konusu olan Microsoft Lumia 532 telefonuma. Bazı Lumia telefonlar #WindowsMobile10 dış ekrana sahip kapasitif navigasyon tuşları ile gelirken, bazıları günümüzdeki pek çok Android telefondaki gibi gerektiğinde ortaya çıkan ”soft” navigasyon tuşları ile geliyor. Lumia 532’de bu tuşlar (Geri, Ana Ekran ve Arama tuşları) dış ekranda kapasitif olarak yer alıyor. Bir kaç ay önce önce arama/search tuşu, birkaç hafta sonra da ana ekran/home tuşu çalışmaz oldu. Geri/Back tuşu çalıştığı için telefonu kullanmaya devam edebildim. Ancak bir süre sonra bu tuş da çalışmaz olunca telefonu pratikte kullanma imkanım kalmadı, çünkü girdim bir uygulama ya da ekrandan çıkmanın tek yolu telefonu açıp/kapatmak olmuştu. Tanıdık güvendiğim bir telefon tamircisine götürdüm, ”ekran değişimi lazım ama bunun ekranını da bulmak çok kolay değil beni uğraştırma” deyince iş başa düştü. Bazı Lumia’lardaki ”soft” navigasyon tuşlarını bir şekilde benim Lumia 532’de de aktif etmek mümkün mü diye araştırdım. XDA Developer başta olmak üzere pek çok forumda gezdikten sonra en nihayetinde bunun nasıl yapılacağını anlatan bir yazı buldum. Temelde registery’ye sadece 2 adet değer eklemek gibi çok kolay bir şekilde yapılabildiğini öğrendim, ancak Windows Mobile 10 platformunda kullanıcının registery değerlerine erişimi mümkün değil. Bunu yapabilmek için XDA Developer kullanıcılarından birisinin bir tool geliştirdiğini öğrendim. Interops Tools isimli bu yazılımı yüklemek için telefonda developer options özellikleri açık olmalı. Bunları adım-adım yazalım:
1) Telefonun ayarlar ekranına girip developer options seçilecek

2) Interops Tool indirilecek ve kurulacak, en güncel versiyon buradan indirilebilir. Sakın Interops Tool’u Microsoft Store’dan indirmeyin, oradaki versiyon farklı ve bu iş için işlevsiz!!
3) Interops Tool’u START menüden bulup tıklayın

4) Registry Browser’ı tıklayın

5)”HKLM\SOFTWARE\Microsoft\Shell\NavigationBar” değerine gidin

6) Şu değerleri (value) ekleyin:
Registry value name: SoftwareModeEnabled
Registry value data: 1
Registry value name: IsSwipeUpToHideEnabled
Registry value data: 1

Telefonu reboot ettikten sonra açıldığında ”soft” navigasyon tuşlarının ekranın en altında, dış ekrandaki kapasitif orijinal olanın hemen üzerinde belirdiğini göreceksiniz Bu alanı parmağınızla yukarıdan aşağıda kaydırdığınızda görünmez olur #auto-hide ve tekrar aynı hareketi yaptığınızda tekrar görünür olur.


İşte bu kadar..
]]>
Swift programlama dilinde base UI elemanlarını kullanarak, tasarımda bizden istenen custom componentleri kolayca geliştirebiliriz. Örneğin aşağıdaki gibi bir Slider yapısını UISlider’dan türeterek yapmaya çalışalım. UISlider İnceleme UISlider yukarıdaki gibi bir iskelete sahiptir. Thumb -> Değer ayarlamak için sürükleme işlemi yapan araç Track -> Thumb’un üzerinde hareket ettiği, minimum ve maksimum noktaları boyunca uzanan çizgi MinimumTrackColor […]]]>
Swift programlama dilinde base UI elemanlarını kullanarak, tasarımda bizden istenen custom componentleri kolayca geliştirebiliriz.
Örneğin aşağıdaki gibi bir Slider yapısını UISlider’dan türeterek yapmaya çalışalım.

UISlider İnceleme

UISlider yukarıdaki gibi bir iskelete sahiptir.
Thumb -> Değer ayarlamak için sürükleme işlemi yapan araç
Track -> Thumb’un üzerinde hareket ettiği, minimum ve maksimum noktaları boyunca uzanan çizgi
MinimumTrackColor -> Thumb ve minimum noktasında kalan track rengi
MaximumTrackColor -> Thumb ve maksimum noktasında kalan track rengi
MinimumImage -> Minimum noktasını belirten görsel
MaximumImage -> Maksimum noktasını belirten görsel
Eğer bizden iskelette yer alan nesnelerinin özelliklerini (renk, görsel) değiştirerek elde edilebilecek bir Slider istenirse yukarıdaki özellikleri kullanarak kolayca elde edebiliriz.
Fakat şu an bizim oluşturmak istediğimiz Slider biraz daha özel bir yapı, bunu da hep birlikte nasıl oluşturacağımızı görelim.
Custom Slider Yapımı
Öncelikle UISlider’dan miras alan ‘Slider’ adında bir class oluşturalım.
import UIKit
final class Slider: UISlider {
}Ardından tint color’lar bizim işimizi görmeyeceği için görsel olarak ortadan kaldıralım.
import UIKit
final class Slider: UISlider {
override func draw(_ rect: CGRect) {
super.draw(rect)
setup()
}
private func setup() {
clear()
}
private func clear() {
tintColor = .clear
maximumTrackTintColor = .clear
backgroundColor = .clear
thumbTintColor = .clear
}
}Şimdi de Track nesnesini çizelim.
Bunu yapmak için bir layer oluşturup, Slider’ımızın sahip olduğu layer’a subLayer olarak ekleyeceğiz.
Not: Buradan sonra yapılacak tüm boyut ayarlamaları vb. işlemler tasarım ve isteğe göre değiştirilebilir.
final class Slider: UISlider {
private let baseLayer = CALayer() // Step 3
override func draw(_ rect: CGRect) {
super.draw(rect)
setup()
}
private func setup() {
clear()
createBaseLayer() // Step 3
}
private func clear() {
tintColor = .clear
maximumTrackTintColor = .clear
backgroundColor = .clear
thumbTintColor = .clear
}
// Step 3
private func createBaseLayer() {
baseLayer.borderWidth = 1
baseLayer.borderColor = UIColor.lightGray.cgColor
baseLayer.masksToBounds = true
baseLayer.backgroundColor = UIColor.white.cgColor
baseLayer.frame = .init(x: 0,
y: frame.height / 4,
width: frame.width,
height: frame.height / 2)
baseLayer.cornerRadius = baseLayer.frame.height / 2
layer.insertSublayer(baseLayer, at: 0)
}
}Nereye kadar geldik bir bakalım.
Görüldüğü üzere Track’imiz hazır. Şimdi de Thumb’u oluşturalım.
Öncelikle aşağıdaki gibi bir ThumbView oluşturalım.
// Step 4
final class ThumbView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
private func setup() {
backgroundColor = UIColor(red: 183 / 255, green: 122 / 255, blue: 231 / 255, alpha: 1)
let middleView = UIView(frame: .init(x: frame.midX - 6,
y: frame.midY - 6,
width: 12,
height: 12))
middleView.backgroundColor = .white
middleView.layer.cornerRadius = 6
addSubview(middleView)
}
}UISlider API’ı Thumb verebilmek için bizden bir view değil image istiyor. Bu nedenle oluşturacağımız ThumbView’ın snapshot’unu almak için aşağıdaki gibi bir extension yazıyoruz.
// Step 4
extension UIView {
var snapshot: UIImage {
let renderer = UIGraphicsImageRenderer(bounds: bounds)
let capturedImage = renderer.image { context in
layer.render(in: context.cgContext)
}
return capturedImage
}
}Sıra geldi Slider içerisinde thumb image’ı oluşturmaya.
private func setup() {
clear()
createBaseLayer() // Step 3
createThumbImageView() // Step 5
}// Step 5
private func createThumbImageView() {
let thumbSize = (3 * frame.height) / 4
let thumbView = ThumbView(frame: .init(x: 0,
y: 0,
width: thumbSize,
height: thumbSize))
thumbView.layer.cornerRadius = thumbSize / 2
let thumbSnapshot = thumbView.snapshot
setThumbImage(thumbSnapshot, for: .normal)
}Burada karşımıza çıkan setThumImage fonksiyonu bizden bir adet image ve o image’in hangi Slider durumunda görünmesi istediğimizi bekliyor. Yukarıdaki gibi sadece ‘.normal’ durumu için bir geliştirme yaparsak aşağıdaki videoda olduğu gibi bir görünüm elde ederiz.
Bu nedenle bütün state’ler için thumb image ayarlamasını yapıyoruz.
// Step 6 setThumbImage(thumbSnapshot, for: .normal) setThumbImage(thumbSnapshot, for: .highlighted) setThumbImage(thumbSnapshot, for: .application) setThumbImage(thumbSnapshot, for: .disabled) setThumbImage(thumbSnapshot, for: .focused) setThumbImage(thumbSnapshot, for: .reserved) setThumbImage(thumbSnapshot, for: .selected)
Görüldüğü üzere artık her state için istediğimiz thumb image’i görebiliyoruz.
Şimdi de thumb image’in solunu yani slider üzerinden seçili kısmı örneğimizdeki gibi gradient bir görünüme kavuşturalım.
Bunun için öncelikle bir gradient layer objesini class düzeyinde yaratıyoruz.
Ardından tıpkı base layer’da yaptığımız gibi özelliklerini verip, layer’a ekliyoruz.
private let baseLayer = CALayer() // Step 3 private let trackLayer = CAGradientLayer() // Step 7
private func setup() {
clear()
createBaseLayer() // Step 3
createThumbImageView() // Step 5
configureTrackLayer() // Step 7
}// Step 7
private func configureTrackLayer() {
let firstColor = UIColor(red: 210/255, green: 152/255, blue: 238/255, alpha: 1).cgColor
let secondColor = UIColor(red: 166/255, green: 20/255, blue: 217/255, alpha: 1).cgColor
trackLayer.colors = [firstColor, secondColor]
trackLayer.startPoint = .init(x: 0, y: 0.5)
trackLayer.endPoint = .init(x: 1, y: 0.5)
trackLayer.frame = .init(x: 0,
y: frame.height / 4,
width: 0,
height: frame.height / 2)
trackLayer.cornerRadius = trackLayer.frame.height / 2
layer.insertSublayer(trackLayer, at: 1)
}Şimdi de track layer’ın konum ve boyut bilgilerini slider aksiyonuna göre ayarlayalım.
Bunu yapabilmek için öncelikle kullanıcının aksiyonlarını algılayabilmemiz gerekir. Bu sebeple slider’ımıza aksiyonları tanıması için bir target ve fonksiyon ekleyeceğiz.
// Step 8
private func addUserInteractions() {
addTarget(self, action: #selector(valueChanged(_:)), for: .valueChanged)
}
@objc private func valueChanged(_ sender: Slider) {
}private func setup() {
clear()
createBaseLayer() // Step 3
createThumbImageView() // Step 5
configureTrackLayer() // Step 7
addUserInteractions() // Step 8
}“valueChanged” fonksiyonumuzun içini dolduralım.
@objc private func valueChanged(_ sender: Slider) {
// Step 9
let thumbRectA = thumbRect(forBounds: bounds,
trackRect: trackRect(forBounds: bounds),
value: value)
trackLayer.frame = .init(x: 0,
y: frame.height / 4,
width: thumbRectA.midX,
height: frame.height / 2)
}Burada öncelikle thumb image’imizin o anki konumunu öğreniyoruz. Bu bilgi ile track layer’ımızın sahip olacağı genişlik değerini elde etmiş oluyoruz.
Devamında elde edilen genişlik değeriyle beraber track layer’ın frame’ini oluşturuyoruz. Buradaki “y” ve “height” değerleri tercih ve tasarıma göre değişebilir.
Şimdi ne durumdayız bir bakalım.
Track layer’ımızın beklediğimiz gibi çizilmeye başladı ama bir sorunumuz var. Track layer bizim hareketlerimize sürekli geç tepki veriyor GİBİ! Aslında öyle değil, frame değişikliği ani olmak yerine bir transaction action altında animasyon ile gerçekleştiği için böyle göze hoş gelmeyen bir görüntü ortaya çıkıyor.
Şimdi bunu çözelim.
Geldiğimiz son noktada hedefimize ulaştık. Zaman ayırdığınız için teşekkür ederim, faydalı olması dileğiyle.
]]>
Erişim belirleyiciler sayesinde, yazdığımız kodların diğer dosya veya modüllerden erişimini kontrol edebiliriz. Bu sayede bizim yazdığımız kod parçalarının detaylarına erişimi kısıtlayıp, kullanmak isteyenlere belirli erişim araçları sunarak kullanmalarına izin verebiliriz. Class, Structure ve Enumeration’lara erişim belirleyici verebildiğimiz gibi bunlara ait özelliklere, metotlara veya init fonksiyonlarına da erişim kısıtı getirebiliriz. Swift’ta şu an en az kısıtlayıcı […]]]>
Erişim belirleyiciler sayesinde, yazdığımız kodların diğer dosya veya modüllerden erişimini kontrol edebiliriz. Bu sayede bizim yazdığımız kod parçalarının detaylarına erişimi kısıtlayıp, kullanmak isteyenlere belirli erişim araçları sunarak kullanmalarına izin verebiliriz.
Class, Structure ve Enumeration’lara erişim belirleyici verebildiğimiz gibi bunlara ait özelliklere, metotlara veya init fonksiyonlarına da erişim kısıtı getirebiliriz.
Swift’ta şu an en az kısıtlayıcı olandan başlayarak:
gibi sıralayabiliriz.
Eğer biz specific olarak yukarıdakilerden birini seçmez isek default olarak “internal” erişim kısıtılayıcısı atanmış olacaktır.
Anahtar Kelimeler
Modül –> Tek bir uygulama veya framework olarak yazılmış, diğer modüller tarafından “import” anahtar kelimesi ile kullanılabilen parçalardır.
Source File –> Modüller içerisinde kullanılan her bir Swift dosyasıdır.
Nested Type –> Bir tip içerisinde tanımlanmış tiplerdir.
Aynı modülden veya dahil edilmiş başka bir modülden herhangi bir dosyadan erişime açık olduğunu belirtir. Ayrıca erişim sağlanabilen her yerde subclass olarak kullanılabilir ve öğeleri override edilebilir.
Erişim olarak “open” ile aynı özelliklere sahiptir fakat subclass edilebilmesi ve öğelerinin override edilebilmesi için aynı modül içerisinde olması gerekmektedir.
Default olarak belirlenmiş olarak belirlenen “internal”, aynı modül içerisinden erişime izin vermektedir.
Yalnızca tanımlandığı dosyadan erişime izin verir.
Tanımlanılan “scope” için kısıt getirir ki bu en kısıtlayıcı belirteçtir.
Not: Swift 4 öncesinde bir class içerisinde tanımlanan öğe eğer private ise extension’larından erişim sağlanamıyordu.
Erişim Belirleyicisi Belirlerken Dikkat Edilmesi Gerekenler
Daha fazla kısıtlayıcı erişim belirleyiciye sahip bir varlık içerisinde daha az kısıtlayıcıya sahip bir varlık tanımlamamalısınız. Çünkü örneğin private olan bir sınıf içerisinde public bir değişken olsa bile, sınıfa erişemeden değişkene zaten erişemeyiz.
Fonksiyonlarda erişim kısıtlayıcısı, fonksiyonun parametreleri, dönüş tipi ve kendisinin sahip olduğu erişim belirleyicilerinin en kısıtlı olanı olarak belirlenir.
Enumeration’da case’ler enum’ın kendisine ait erişim belirleyicisine sahip olacaktır ve özel olarak belirlenmez. Raw value ve associated type ise en fazla enum’ın kendisi kadar izin verici olabilir.
Nested type tanımlandığı tipe bağlı olarak default erişim belirleyicisine sahip olur. “Private” veya “fileprivate” içerisinde tanımlanan tipler içerisinde tanımlandığı tipin erişim belirleyecisine sahip olur. “Public” veya “internal” içerisinde tanımlanan tipler ise default olarak “internal” erişim belirleyicisine sahip olacaktır. “Public” olmaları isteniyorsa ayrıca belirtmek gerekecektir.
Bir alt sınıf, super sınıfından daha az kısıta sahip bir erişim belirleyiciye sahip olamaz. Yani bir sınıf “private” belirleyiciye sahip ise alt sınıfları en fazla “private” kadar esnek olabilir.
Bir super sınıfın metodu, override edildiği alt sınıfta daha izin verici olabilir. Yani “public” bir üst sınıf içerisinde “fileprivate” olan bir metod, “internal” bir alt sınıfta yine “internal” bir erişim belirleyiciye sahip olabilir.
public class FirstClass {
fileprivate func someMethod() {}
}
internal class BusinessClass: FirstClass {
override internal func someMethod() {}
}Bir nesne, sınıfından daha izin verici bir erişim belirleyiciye sahip olamaz. Örneğin bir sınıf private olarak tanımlandıysa, kendisinin bir nesnesi public olamayacaktır.
private class Tax {
}
public var tax = Tax()Sabitler, değişkenler ve özelliklerin getter ve setter’larının erişim belirleyicileri, otomatik olarak kendi erişim belirleyicileri olarak belirlenmektedir. Dilersek setter’a getter’ın sahip olduğu erişim belirleyicisinden daha kısıtlayıcı bir erişim belirleyicisi verebiliriz.
struct Tax {
var income: Double
private(set) var exactTax: Double
var ratio: Double {
didSet {
exactTax = (income / 100) * ratio
}
}
}Örneğin yukarıdaki örnekte income, exactTax ve ratio default olarak Tax struct’ının erişim belirleyicisi olan “internal” olarak yaratıldı. Fakat sonrasında exactTax’ın setter’ı “private” olarak belirlendi. Böylece exactTax erişim olarak daha kısıtlı hale getirildi ve görüldüğü gibi oranın değişmesiyle beraber yeni değerine sahip oldu.
]]>
Merhaba, method dispatching serisine daha önce giriş yapmış ve static method dispatching konusuna değinmiştik. Şimdi bir diğer method dispatching yöntemi olan ve bize OOP’ı kazandıran, dynamic method dispatching konusunu ele alacağız. Static method dispatching, adından da anlaşılacağı üzere çalışacak metotların adreslerinin memory’de önceden bilindiği ve metot çağırıldı anda hangi adreste saklanan komutların işleneceğinin compile-time’da belli […]]]>
Merhaba, method dispatching serisine daha önce giriş yapmış ve static method dispatching konusuna değinmiştik. Şimdi bir diğer method dispatching yöntemi olan ve bize OOP’ı kazandıran, dynamic method dispatching konusunu ele alacağız.
Static method dispatching, adından da anlaşılacağı üzere çalışacak metotların adreslerinin memory’de önceden bilindiği ve metot çağırıldı anda hangi adreste saklanan komutların işleneceğinin compile-time’da belli olduğu dispatching yöntemiydi.
Dynamic method dispatching ise bir metot çağırıldığı anda, memory’deki hangi adreste yer alan executable-code’un çalışacağına run-time’da dinamik olarak karar verilen dispatching yöntemidir.
Class’ların sahip olduğu metotlar child class’larda override edilip, yeni yetenekler eklenebilir ya da parent class’ta yer alan metot kullanılabilir. Bu durumda gerçekten hangi metodun çalışacağının tespit edilmesi gerekmektedir.
Swift dilinde table ve message dispatching olarak ikiye ayrılmaktadırlar.
Bu yazımda table dispatch konusuna değineceğim.
Table Dispatch (Witness-Virtual Table)
Parent sınıflar için sahip oldukları metotların adreslerinin tutulduğu bir tablo oluşturulur. Ardından child sınıflar için de bu tablonun bir kopyası oluşturulur, override edilmiş metotlar için adres alanı değiştirilir, varsa yeni eklenen metotlar ve adresleri tabloya eklenir.
Bir örnek üzerinden inceleyelim.
Öncelikle “View” adında bir sınıf tanımlayalım ve iki adet metodu olsun.
class View {
func show() {}
func hide() {}
}Ardından “ScrollView” adında başka bir sınıf oluşturalım ve bir metodunu override edip yeni bir metod ekleyelim.
class ScrollView: View {
override func show() {
super.show()
addScroll()
}
func addScroll() {}
}Şimdi her iki sınıf için de oluşan tabloları inceleyelim.

Görüldüğü üzere, Parent sınıftan override edilmeden kullanılan “hide” metodunun adresi iki tablo için de aynı. override ettiğimiz “show” ve yeni eklediğimiz “addScroll” metotları için ise yeni adresleri kayıt edilmiş durumda.
Şimdi basit bir kod parçası yapalım ve run-time’da ne olduğuna bakalım.
Son haliyle kod bloğumuz aşağıdaki gibi olacaktır.
class View {
func show() {}
func hide() {}
}
class ScrollView: View {
override func show() {
super.show()
addScroll()
}
func addScroll() {}
}
let scrollView = ScrollView()
scrollView.show()Son satır özelinde işlemcimizi inceleyelim.
1) scrollView nesnesine ait tablo 0xCA0 adresinden okunur.
2) Çağırılacak olan “show” fonksiyonu için 0xCA4 adresi okunur.
3) 0xCA4 adresine zıplanır.
4) Tekrar 0xCA0 adresine dönülür.
5) “addScroll” metodu için 0xCA8 adresi okunur.
6) 0xCA8 adresine zıplanır.
Burada meydana gelen, okuma-zıplama işlemleri sebebiyle dynamic dispatching, static dispatching’den daha maliyetli ve yavaş olmaktadır. Bu sebeple mümkün olduğunca derleme anında hangi metodun çalışacağının belirlenebilmesi için static method dispatching kullanılmaya çalışılır. Örneğin hiç Child’ı oluşturulamayacak sınıfları “final” olarak tanımlamamız iyi bir deneyim olacaktır.
Swift’te sınıfların ve protokollerin ilk tanımlandığı alanda oluşturulan metotlar, spesifik keywordler kullanılmamışsa (final, static, @objc vb.) table method dispatching yöntemini kullanırlar.
Bir sonraki yazımda Message Dispatching konusuna değineceğim.
Mutlu kodlamalar
Serinin ilk yazısında method dispatching konusuna genel olarak değinmiştim. Serinin ikinci yazısında static dispatching konusundan bahsetmek istiyorum. Static dispatch kullanıldığı zaman çalışacak metodun hangi adreste olduğu compile-time’da belirleniyor, biliniyor. Bu sebeple run-time’da class’lar üzerinden metodun adresini bulmak için jump işlemleri yapmak gerekmediği için en hızlı dispatching yöntemidir. Compile-time’da karar verildiği için derleyici yapılabilecek tüm optimizasyonları […]]]>
Serinin ilk yazısında method dispatching konusuna genel olarak değinmiştim. Serinin ikinci yazısında static dispatching konusundan bahsetmek istiyorum.
Static dispatch kullanıldığı zaman çalışacak metodun hangi adreste olduğu compile-time’da belirleniyor, biliniyor. Bu sebeple run-time’da class’lar üzerinden metodun adresini bulmak için jump işlemleri yapmak gerekmediği için en hızlı dispatching yöntemidir. Compile-time’da karar verildiği için derleyici yapılabilecek tüm optimizasyonları uygulayabilmektedir. Hatta method inline hale bile getirilebilmekte ve bilinen adrese zıplama cost’undan da tasarruf edilebilmektedir.
Static dispatching’de metotların tek bir adresi olması beklendiği için override edilemezler.
Swift özelinde static methodları nasıl elde edebileceğimize değinecek olursam.
Class -> final keyword’ü ile tanımlanmış class’lar ve bir class’ın extension’ında tanımlanmış metotlar,
Protocol-> extensionda implement edilmiş metotlar,
Value type-> tüm metotlar
şeklinde bir tablo karşımıza çıkacaktır.
static keywordü kullanarak da bir metot static dispatch yapılabilir.
Protocol – Struct ikilisiyle güzel bir örnek vermek istiyorum.
protocol View {
}
extension View {
func show() {
print("protocol extension")
}
}Ardından View protocolünü sağlayan bir struct oluşturalım.
struct CardView: View { }
extension CardView {
func show() {
print("struct extension")
}
}Son olarak bir View bir de CardView tipinde sabitler oluşturalım.
let cardView = CardView() let pCardView: View = cardView cardView.show() pCardView.show()
Kodumuzu bu şekilde çalıştırdığımız zaman aşağıdaki gibi bir çıktı elde edeceğiz.
![]()
Protocol’de tanımlanan fonksiyonumuz, extension içerisinde tanımlandığı için static olarak dispatch edildi ve pCardView objesi için bu fonksiyonun adresi çağırıldı.
CardView için de aynı şekilde extension’da tanımlandığı için kendisine ait fonksiyon çağırıldı.
Şimdi kodumuzda ufak bir değişiklik yapalım ve protocol içerisindeki metodumuzu protocol tanımının içine alalım.
protocol View {
func show()
}Kodumuzu tekrar çalıştıralım.

Bu kez fonksiyonumuzu protokolün tanımlanma alanında oluşturduğumuz için dynamic dispatch oldu ve override edilerek her iki durumda da struct içerisindeki fonksiyon çağırıldı.
Serinin bir sonraki yazısında dynamic dispatch konusuna değineceğim, mutlu günler
Class, struct objesine ait bir metot çağrıldığında acaba runtime’da neler yaşanıyor? İlk olarak, neden böyle bir yazı yazmaya karar verdiğimden bahsetmek istiyorum. Apple’ın Swift diline ait her gelişmeyi bildirdiği proposal listesinden Enum cases as protocol witnesses başlıklı değişimi incelerken “witness table” adında ve daha önce duymadığım bir kavram ile karşılaştım. Bu kavramı öğrenmeden proposal’a dair […]]]>
Class, struct objesine ait bir metot çağrıldığında acaba runtime’da neler yaşanıyor?
İlk olarak, neden böyle bir yazı yazmaya karar verdiğimden bahsetmek istiyorum. Apple’ın Swift diline ait her gelişmeyi bildirdiği proposal listesinden Enum cases as protocol witnesses başlıklı değişimi incelerken “witness table” adında ve daha önce duymadığım bir kavram ile karşılaştım. Bu kavramı öğrenmeden proposal’a dair aklımda fikir oluşmayacağını anlayınca araştırmaya başladım ve method dispatching kavramı ile karşılaştım.
Bu kavramı araştırmak, (Xcode) kod yazma sürecinde kullandığım; final, @objc, private vb. keywordlerin kullanım amaçlarını, extension’da yarattığım fonksiyonları neden override edemiyor olduğumu ve dahası yazılım geliştirirken kullandığım ama çalışma mantığını tam olarak öğrenmemiş olduğum birçok konuyu anlamamı sağladı. Bunların yanında Object Oriented Programming’e çok yüzeysel yaklaştığımı, inheritence kavramının arka planı konusunda deneyimsiz olduğumu gördüm ve eksiklerimi gidermeye başladım.
Bu noktada; bir dilin gelişimini takip ederek güncel kalmanın yanında, eskiye yönelik bilgilerin temelini sonradan da olsa öğrenmek önemlidir/mümkündür diyebilirim. Bir yazılım dili ya da herhangi bir projenin gelişimini takip edebilmek için repoyu fork ederek, belirli aralıklarla repoları eşitleyip, farkları inceleyebilinir.
Öncelikle “dispatch” kelimesini anlayarak başlayalım. Dispatch, bir şeyi bir amaç uğruna bir yere gönderme anlamında kullanılır. Bilgisayar bilimlerinde, bir çağrının fonksiyona gönderilmesi, bir event’in listener’a gönderilmesi, bir process’in CPU’ya gönderilmesi gibi terimler olarak karşımıza çıkmaktadır.
Konumuz özelinde dispatch; bir nesne üzerinden nesnenin ait olduğu class veya super class’ının herhangibir fonksiyonunun çağırılma sürecinde, memory’deki hangi adrese gidilip executable-code’un çalıştırılacağına karar verme işlemidir. Executable-code’un adresinin CPU’ya verilmesi, dispatching işleminin amacıdır. Bu işlem her metot çağırımında gerçekleşir.
Metotlar yalnızca küçük kod parçaları gibi görülmemelidir. Metotlar, sınıflar arası iletişim, durum değişiklikleri, iş logicleri gibi durumları düzenlerler. Alt sınıf üst sınıftan miras aldığı metotları override ederek logicleri değiştirebilir ve bunu bir kapsül gibi gizler(Encapsulation). Bu şekilde hem benzer özellikleri tekrar tekrar yazmadığımız gibi hem de farklılıkları diğerlerinden gizleyebiliriz. CPU bir işlemi çalıştırabilmek için öncelikle onun adresine sahip olmayı bekler. Ardından bu adrese zıplayarak işlemi gerçekler. CPU’ya çalıştırması gereken metot dispatch edilerek bildirilir.
Günlük hayattan bir örnek ile beslemeye çalışalım. Bir yazılım şirketini düşünelim. Yapılması gereken bir iş ve bu işe ait ekran tasarımları mevcut. Ancak 3 farklı tasarım olduğunu hayal edelim. İşe başlayan yazılımcıya da sprint başında hangi tasarımın uygun olduğu birkaç gün içerisinde iletileceği söylenmiş olsun. Yazılımcının geliştirme sürecini “runtime” olarak düşünebiliriz. Yazılımcı geliştirme sürecinde servis fonksiyonları entegre etmiş, testleri sonucunda düzgün çalıştığını görmüştür ve sıra ön yüzü giydirmeye gelmiştir. Burada elindeki çeşitli tasarımlar da “metot” olarak düşünülebilir. Yazılımcı hangi tasarımı geliştirmesi gerektiğini ürün sahibine sorar ve cevabını alır. Bu işlemi de method dispatching olarak düşünebiliriz. Örneğimizdeki rolleri tekrar terimler ile eşleştirecek olursak, yazılımcı = CPU, tasarımlar = metotlar, hangi tasarımın kullanılacağı = metot dispatching şeklinde eşleştirebiliriz. Kararın ise tabiri caizse “yolda” verildiği için runtime olarak düşünebiliriz.
Senaryoyu biraz değiştirelim. Yazılımı yapılacak tasarım sprint başlamadan önce, ürün sahibi tarafından “budur” diye tek seçeneğe indirgenmiş olsun. Bu durumda tasarım seçimi statik hale gelmiş olur ve işe başlamadan karar verilmiştir. Bunu da compile time olarak düşünebiliriz.
Dispatching, Static(direct) ve dynamic(table) dispatching olmak üzere 2 tipe ayrılabileceği gibi Objective-C buraya Message Dispatching’i de ekler ve Swift dilinden Objective-C runtime’a geçebildiğimiz için Swift dili 3 dispatch tipini de destekler hale gelir.
Default olarak dynamic dispatch kullanır. “final” keyword’ünü kullanarak static dispatch’i kullanmak mümkündür.
default olarak direct dispatch kullanır. “virtual” keyword’ünü kullanarak dynamic dispatch’e geçmek mümkündür.
Yukarıda belirttiğimiz gibi üç dispatch tipini destekler.
Method Dispatching bir yazı dizisi olarak hayatına devam edecektir. İlerleyen makalelerde static, dinamik ve message dispatching konusuna değineceğim.
Mutlu kodlamalar
Associated Type, protocol’lerde generic yapı elde etmemizi sağlar ve protocol’e uyma sözü veren tipler tarafından tipinin belirlenmesini beklerler. Uygulamamızda kullanmak için kamera, mikrofon, fotoğraf galerisi gibi özellikler için kullanıcıdan izin isteriz. Bunun için basit bir protocol tanımlayarak uygulamasını gerçekleştirelim. [crayon-6aa47b2c0157a456872416/] Protocol’ümüz “PermissionType” adını verdiğimiz bir associatedtype’a sahip olacak şekilde yaratıldı. İçerisinde ayrıca bu tipte bir […]]]>
Associated Type, protocol’lerde generic yapı elde etmemizi sağlar ve protocol’e uyma sözü veren tipler tarafından tipinin belirlenmesini beklerler.
Uygulamamızda kullanmak için kamera, mikrofon, fotoğraf galerisi gibi özellikler için kullanıcıdan izin isteriz. Bunun için basit bir protocol tanımlayarak uygulamasını gerçekleştirelim.
protocol Permission {
associatedtype PermissionType
var status: PermissionType { get }
func request(completion: @escaping (PermissionType) -> ())
}Protocol’ümüz “PermissionType” adını verdiğimiz bir associatedtype’a sahip olacak şekilde yaratıldı. İçerisinde ayrıca bu tipte bir değişken ve çağırıldığı yere bu tipi dönen closure sahip fonksiyon bulunuyor.
Şimdi bir tip yaratarak “Permission” protocolüne uymasını isteyelim.
struct MicrophonePermission: Permission {
var status: AVAudioSession.RecordPermission {
AVAudioSession.sharedInstance().recordPermission
}
func request(completion: @escaping (AVAudioSession.RecordPermission) -> ()) {
AVAudioSession.sharedInstance().requestRecordPermission { _ in
completion(self.status)
}
}
}“MicrophonePermission” tipimiz, “Permission” protocolüne uyuyor ve associatedtype’a “AVAudioSession.RecordPermission” tipini veriyor.
struct CameraPermission: Permission {
var status: AVAuthorizationStatus {
AVCaptureDevice.authorizationStatus(for: .video)
}
func request(completion: @escaping (AVAuthorizationStatus) -> ()) {
AVCaptureDevice.requestAccess(for: .video) { (granted) in
completion(self.status)
}
}
}Yeni örneğimizde Kamera erişimi için izin istedik. Bu kez associatedtype’ımız “AVAuthorizationStatus” tipine sahip oldu ve request fonksiyonunda da bu tipi döndürmektedir.
Yaratmış olduğumuz protocol sayesinde proje genelindeki izin işlemlerinin uymasını istediğimiz bir düzen belirlemiş olduk.
Yeni örneğimizde oluşturduğumuz “TableViewCell” lerin uymasını istediğimiz bir protocol oluşturalım.
protocol Cell {
associatedtype DataType
func configure(_ type: DataType)
}“Cell” protocolü içerisinde generic bir tip tanımlıyor ve bu tipi bekleyen bir fonksiyon içeriyor.
struct CreditCard {
let cardNo: String
let cardOwner: String
let availableLimit: Double
}
class CreditCardCell: UITableViewCell, Cell {
func configure(_ type: CreditCard) {
print(type.cardNo)
}
}“CreditCardCell”, protocol’e uymak için “configure” metodunu uyguluyor ve beklediği tipe yine bizim oluşturduğumuz “CreditCard” ı bekliyor.
struct Team {
let name: String
let stadiumLocation: (latitude: Double, longitude: Double)
let stadiumName: String
}
class TeamCell: UITableViewCell, Cell {
func configure(_ type: Team) {
print(type.name)
}
}“TeamCell”, Cell protocol’üne uyabilmek için “configure” metodunda “Team” tipini bekliyor.
Bu örneğimizde de proje genelinde “TableViewCell” lerin çizilmesi için bir kural belirlendi. Projemizdeki bütün “TableViewCell” ler “DataType” alan bir configure metoduna sahip olup, UI elemanlarının değerlerini burada dolduracaktır.
]]>