
Microsoft Build 2019 Türkiye Etkinliği
Selamlar,
Geçtiğimiz 18 haziran günü Microsoft Türkiye’de Build 2019′ un Türkiye ayağını gerçekleştirdik. Çok değerli konuşmacı ve katılımcı dostlarımızla çok faydalı bir etkinlik olduğunu düşünüyorum. Birçok konuya değindiğimiz bu etkinlikte ben de WebAssembly ve Blazor hakkında bilgiler paylaştım.
Bir önceki yazımda WebAssembly ile alakalı yazımı bulabilirsiniz. Bunun üzerine bu yazımda da sizlere Blazor bahsetmek istiyorum.
WebAssembly’yi .Net dünyasında kullanmak için henüz official pre-relase halinde bulunan Blazor a başvuracağız. Blazor ile Visual Studio da 3 farklı şekilde geliştirme yapmak mümkün. Bunların detayından aşağıda bahsedip örnekler göstereceğim.
- Client-Side Blazor
- Asp.Net Core Hosted Blazor
- Server-Side Blazor
Client-Side Blazor
Bir önceki yazımda bahsettiğim gibi high-level dillerde yazılan kodun wasm a dönüşüp, browser içerisinde javascript sandbox ı içerisinde çalıştırılabilmesi mümkün. Hatta bu zaten WebAssembly nin en güçlü özelliklerinden biri.
Blazor için bu senaryo aşağıdaki şekilde gerçekleşiyor.
yazdığımız C#/Razor dosyaları compile olup .dll haline geliyor. daha sonra bu .dll dosyalarımız mono.wasm runtime ın da çalışabilir hale geliyor. mono.wasm da, javascript runtime üzerinde çalışıyor. Yani özetle şuan bir .dll dosyamız wasm olarak browserda çalışmak için mono ya biraz muhtaç. Ama bunlar arka planda olan şeyler, kullanırken mono vs uğraşmıyorsunuz. Ama yine de bu mono dan itibaren başlayan xamarin in gücünü ve arka planındaki güzelliği de bilmek açısından değerli 🙂
Projemizde bir mvc projesinde kullandığımız .cshtml sayfalarına benzer olarak, Client-side Blazor da .razor uzantılı dosyaları kullanıyoruz. Bu dosyalar derlendiğinde elde ettiğmiz dll, mono-runtime ile browser içerisinde javascript runtime ın da çalışabilir bir wasm a dönüşüyor.
Tamamen javascript kadar güvenli olduğundan tekrar söz etmek istiyorum, çünkü aşağıdaki resme baktığımızda bir .net web developer ın çok da alışık olmadığı bir takım dosyaların browser tarafına yüklendiğini göreceğiz. Bir çok yazılımcının aklına, browsera a yüklenen .net dll lerini gördüğünde güvenlik ile alakalı sıkıntılar yaratıp yaratmayacağı geliyor. Ama dediğimiz gibi herşey en sonunda javascript kendisinin çalıştığı, sandbox environment ında çalıştığı için en az javascript kadar güvenli.
Yukarıda ki resme baktığınızda, C# kodumuzun browser içerisinde wasm olarak çalışması için ne kadar fazla dll in de browser a yüklendiğini görüyoruz.
Mono.Security.dll, Mono.WebAssembly.Interop.dll, mono.wasm, solutionname..dll, System.dll, System.Core.dll gibi hem mono hem de .net e bağlı birçok dll in browser a yükleniyor. Bu sayede yazdığımız C# kodları, client side tarafında çalıır hale geliyorlar.
Peki direk filmin sonunu göstermiş olduk ama biraz daha başa sararak herşeye daha detaylıca bakalım.
Öncelikle ister Blazor ile ister diğer pre-release olan tüm yeni feature ları denemek için neler yapacağımıza bir bakalım.
Blazor .net core 3.0 ile beraber sadece Server-Side desteği ile official olarak gelecek. Client-Side ve Core Hosted taraflarının release olmasına biraz daha vari ama denemekten hatta basit projeleri bu yöntemler ile de yapmaktan çekinmenize hiçbir sebep yok.
Yeni .net core feature larını denemek için aşağıdaki yöntemleri izlemenizi tavsiye ederim.
- Öncelikle şuradan Visual Studio 2019 Preview ı download edin. Yeni featureları mevcut stabil VS 2019 da da aktif edebilirsiniz ama, preview ı indirip tüm yeni-henüz release olmamış özellikleri buradan daha hızlı update ler ile takip etmenizde fayda var.
- Sonrasında şuradan son güncel .net-core 3.0 sdk sını indirmeniz gerekiyor.
Bu adımlar aslında birçok feature ı deneminiz için yeterli ama Blazor için iki adımımız daha var.
- Buradan Asp.Net Core Blazor template ini download edip kurmanız gerekiyor. Oldukça basit bir işlem, bir VSIX dosyası (Visual Studio Extension) kurmaktan farklı değil
- Son olarak da, aşağıdaki komutu çalıştırmanı yeterli olacaktır.
- dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.0.0-preview6.19307.2
Yukarıdaki tüm adımları tamamladığımızda, Visual Studio 2019 Preview ı açtığımızda, File-> New Project seçip yeni bir Asp.Net Core Project seçtiğimizde karçımıza aşağıdaki gibi bir ekran çıkacak. Yeni gelen, ve gelecek olan tüm proje template lerini burada görebilirsiniz.
yukarıdaki 4 adımı da tamamladığımızda tüm yeni Blazor template leri karçımıza çıkıyor.
Blazor dışında, gRPC service, Worker Service (eski IHostedServices veya Background Services ın yeni hali) gibi yeni templateleri de denemenizde fayda var. Bunlar ile ilgili de en kısa sürede yazmayı planlıyorum.
Şimdilik Blazor a geri dönelim. Seçeneklerden Blazor (Client-Side) seçip Create e bastığımızda karşımıza aşağıdaki gibi bir solution açılacak.
Yukarıda gördüğünüz gibi, Asp.Net Core projelerinde olduğu gibi bir Startup.cs, ve Program.cs dosyalarımız mevcut. Değişik gelecek ilk şey, .razor uzantılı dosyalar.Bunlar aslında klasik MVC projelerindeki .cshtml lerden çok da farklı değil. Gerisi tamamen bildiğiniz bir ASp.Net Core proje yapısı.
App.razor dosyasının içerisine baktğımızda aşağıdaki gibi tek bir satır kod görüyoruz.
Burada bir Router tanımlı. Assembly olarak da sadece projedeki Program.cs dosyasının bulunduğu assembly gösterilmiş. Sayfalar arasındaki geçişler sırasında postback olmadan geçişler olduğunu göreceksiniz. Bu router ın tanımlandığı yer.
Router AppAssembly="typeof(Program).Assembly"
Program.cs dosyasının içerisi de aşağıdaki gibi. Normal bir Asp.Net Core projesi geliştirmesinde bulunduysanız, burada WebHostBuilder yada, HostBuilder kullanıldığını görmüşsünüzdür. Burada fark olarak kullandığımız HostBuilder, BlazorWebAssemblyHost oluyor. Use Startup yerine de yine Blazor için olan, UseBlazorStartup extension metodunu görüyoruz.
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => BlazorWebAssemblyHost.CreateDefaultBuilder() .UseBlazorStartup(); }
Yukarıda ki Program.cs tarafında kullanılmasını söylediğimiz Blazor Startup dosyasıda aşağıdaki gibi. Yine klasik bir core projesinden çok farklı değil. Sadece app ismindeki component imiz, builder a ekleniyor. App.Razor tarafında ki routing tarafının eklendiği ksım. Bir çok hali hazırda yazılmış komponentler mevcut, sizler kendi component lerinizi yazabilirsiniz. Bunlara başka bir yazıda detaylıca değineceğim.
public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IComponentsApplicationBuilder app) { app.AddComponent("app"); } }
Projede ki en temel kısımları gördükten sonra, .razor dosyalarının içlerine bir bakalım. Örneğin sol taraftaki Navigasyon menüsü için, proje içerisinde NavMenu.razor adında bir dosya mevcut. Bunun içeriği aşağıdaki gibi.
… @functions { bool collapseNavMenu = true; string NavMenuCssClass => collapseNavMenu ? “collapse” : null; void ToggleNavMenu() { collapseNavMenu = !collapseNavMenu; } }
Yukarıdaki gibi normal bir html içerisine, tıpkı cshtml deik gibi C# kodlarımızıda ekleyebilyoruz. Burada ekstra olarak farklı olan şey sayfanın en sonunda function section ı içerisinde yazmış olduğumuz C# kodları. İşte bunlar tam olarak javascript metodları yazar gibi C# metodlarını yazığ sayfa içerisinde kullanacağımız kısım. Counter.razor dosyasına bakarken daha dikkatli inceleyeceğiz.
sayfaların en üst tarafında route ları belirtiyoruz. Örneğin aşağıda Index.razor ı görüyoruz, ekstra bir root a sahip olmadığından direkt olarak “/” ile işaretlenmiş durumda. bu route u verirken sadece başına @page yazmamız gerekiyor.
@page "/" <h1>Hello, world!</h1> Welcome to your new app. <SurveyPrompt Title="How is Blazor working for you?" />
Sayfalar içerisinde başka sayfaları (componentleri – .razor dosyalarını) çağırmak da çok basit. yukarıda gördüğünü gibi Index içerisinde SurveyPrompt dosyası ayrı bir html tag i gibi veriliyor sadece bu kadar. Eğer komponentler içerisine parametre geçmek de istiyorsa bunu da yukarıdaki Title attribute u ile yağtığımız gibi, componenti tanımlarken ki Property adını yazıp verebiliyoruz atamak istediğimiz değeri.
Örneğin SurveyPromt.razor dosyasının alt tarafında yazılan function sekmesi şöyle;
@functions {
// Demonstrates how a parent component can supply parameters
[Parameter] string Title { get; set; }
}
Başında [Parameter] attribute ile işaretlenmiş bir Property mevcut. Bu parametreyide aynı isimle başka bir component içerisinden çağırırıken yukarı da index sayfasında yaptığımız gibi, bir html element ine attribute atarmış gibi tanımlıyoruz bu kadar.
Aşağıda bir de counter dosyasına bakalım. basit bir IncrementCount metodu tanımlanmış, currentCOunt değerini bir arttırıyor. Bu metodu html elementine atamak da sadece başına bir @ işareti koyup adını yazmak kadar basit. herşey normal cshtml dosyalarında razor engine kullanırken ki syntax gibi aslında. ama yapabildiklerimiz çok çok daha fazla =)
@page "/counter" <h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" onclick="@IncrementCount">Click me</button> @functions { int currentCount = 0; void IncrementCount() { currentCount++; } }
Bu projeyi çalışıtırığp çıktısına baktığımızda da en üstte gösterdiğim gibi bir çok dll in browser tarafına yüklendiğini görüyoruz. Mono runtime ı sayesinde de dll lerimiz javascript runtime ında çalışabilen wasm a dönüşüyor. Benim gibi javascript i çok seven biri değilseniz, WebAssembly ve Blazor ın yeri sizde de bambaşka olacaktır. =)
Bir sonraki yazımda Server-Side ve Core-Hosted seçeneklerini inceleyeceğiz.
Bir sonraki yazımda görüşmek üzere.
WebAssembly ve Microsoft Asp.Net Core Blazor
Selamlar,
Bu yazımda sizlere Mono, Docker vb çılgınlık seviyesinde bir yenilikten bahsetmek istiyorum;
WebAssembly
Tarihi çok da eskilere gitmemekle beraber öncesinde bir grubun poc olarak başlattığı fakat sonradan çarşının karışabileceği belli olduğundan birçok dünya devininde geliştirilmesine yatırımlar yaptığı bir teknoloji haline geldi webassembly.
Geçmişi tam olarak şöyle;
2017 yılında işe Apple, Google, Mozilla, Facebook ve benzeri devlerin de devreye girmesiyle hayalin gerçeğe dönüşmesi işi başladı.
Ne olduğunu tek bir cümlede anlatmak zor, ama özetle şu;
- Modern browserlar üzerinde hiçbir plugin e gerek kalmadan (Flash, Silverlight vb.) çalışacak olan, client side (– server side desteği ile de, ki .NetCore 3.0 içerisinde bu şekilde gelecek malesef, signalr destekli olarak. -) web yazılımına yeni özellikler ve performans katmayı amaçlayan yeni bir binary kod tipi.
Kendi sitelerinde söyledikleri de tam olarak şu aslında;
- Binary formata sahip, stack-based bir virtual machine. High-Level dillerin (C#, Java vb.) kendisine compile edilebilmesi ve client ve server uygulamaları için web üzerinden deploy edilmesi ile asıl farkı yaratıyor.
Bu tek cümle yetersiz kaldığı kadar güçsüz de kalıyor. Az daha örneklersek şöyle oluyor;
- High-Level bir dilde yadığınız kodu, .wasm a compile edip (bu kısma aşağıda web assembly yi nasıl yazarız kısmında değineceğim) web e deploy ederek, client side kodu gibi kullanabiliyorsunuz.
Aslında nasıl node.js ile front-end yazan arkadaşlarımız bir anda backendci ve fullstack oluverdilerse, bu sayede backend ci arkadaşlar da artık javascript yazmadan frontend ci olabilecekler (html + css hariç :)).
Peki o zaman ilk soru şu; Hangi browserlarda çalışır?
Bunun için şu adresten herhangi bir t anında hangi browserlarda çalışabilir olduğunu kontrol edebilirsiniz.
WebAssembly i anlamak için aslında önce javascript in nasıl çalıştığını anlamak gerekiyor. Modern browserlarda server-client arası işleyiş aşağıdakine benzer şekilde oluyor.
Html ve css ile browserların design tooları web sitenizi gösteriyor. Kullanıcı ile bu sayfalar arasında etkileşim oluşturabilmek için javascript kodları yazıyoruz. Browser http üzerinden server e istek gönderdiğinde, browser ın websitemizi göstermesi için gerekli olan tüm dosyalar server dan browser a iletiliyor yukarıda ki resimde de görebileceğiniz üzere.
Javascript bildiğiniz üzere tüm client-side tarafta(node.js ile beraber server tarafında da) işlemlerimizi yapmak için kullandığımız bir dil. Interpreted (yorumlanan) bir dil javascript, bir derlenme sürecinden geçip hedef makina nın doğrudan anlayıp çalıştırabileceği bir kod a dönüşmüyor önceden, yani ilgili cihaz da ilgili runtime da bir intertpreter(yorumlayıcı) ile yorumlanıp sonrasında runtime ın anlayıp execute edebileceği bir hale geliyor.
Tüm browserlarda (desktop, mobil vs) javascript çalıştırmak için aşağıdaki gibi bir Javascript Runtime a sahip. Bu sandbox olarak browser için de bulunan runtime da javascript kodları çalışırken bir yandan da browser tarafında bazı api lara ulaşma hakkı oluyor. Herşeye ulaşma imkanı yok, aksi halde bu ciddi güvenlik sorunları doğururdu. Aşağıdaki resimde özetle Javascript in bir browser üzerinde javascript runtime ile çalışıp browser üzerinde ulaşabildiği api ları görüyoruz.
Buraya kadar bu günlere geldik, yazılan tüm web projeleri client-side gereksinimlerini javascript ve yukarıdaki model ile çözebildi. Halen de çözebilir, gelecek zaman için javascript adına kötü haberler yok tabii ki.
Ama bu resme artık şöyle bir arkadaş eklendi;
Javascript ile aynı güvenlik prensiplerine sahip, aynı javascript runtime ı içerisinde çalışan ama interpreted olmayan, doğrudan runtime ın anlayıp çalıştırabileceği yeni bir binary kod tipi olan ve üstelik başka high-level dillerden kendisine compile edilebilir olan “WASM (WebAssembly)” oyuna resmi olarak dahil oldu.
WebAssembly kodunun tipi aşağıdaki gibi birşey;
Sol tarafta bildiğiniz javascript, high-level yani insanların okuyup anlayabileceği kolayca yazabileceği bir dil, sağ tarafta ise bir wasm (web assembly) kodu görüyoruz. Ve önceden söylediğim gibi ikisi de aynı runtime içerisinde çalışarak, aynı güvenlik sistemleri içerisinde hem browser tarafında hemde node.js gibi teknolojilerle server tarafında çalışabilir halde.
WebAssembly nin gelecek planları içerisinde kendi runtime ın da çalıştırabilmek javascript runtime ına bağlı kalmamak gibi bir hedefi de var. Browser larda yine javascript runtime kullanılacak fakat, örneğin bir android cihaz da browser a gerek kalmadan doğrudan kendi runtime içerisinde çalıştırılabilmesi gibi bir hedef de söz konusu.
Wasm’ı tahmin edebilebileceğiniz gibi doğrudan yazmak biraz zor gibi duruyor 🙂 ama isteyen yazabilir, diğer farklı yazım olanaklarına bakmadan önce hızlıca “neden wasm kullanmalıyım?” sorusunu bir düşünelim.
Cevabını aşağıdaki gibi listeyelebiliriz.
- Interpreted bir dil olmayıp, doğrudan runtime tarafından execute edilebilecek olmasından dolayı neredeyse native hız da çalışabilecek bir kod tipi olması.
- Diğer High-Level kodların(C#, Java, Python, C/C++ ..) WebAssembly(wasm) a derlenebilir olması.
- Browserlar tarafından doğrudan desteklenir olması, kullanmak için hiçbir plugin e gerek olmaması.
- Javascript Runtime Sandbox ı içerisinde çalıştığı için, javascript yazarken ki güvenliğin birebir aynısına sahip olması.
- Javascript kodu ile beraber çalışabilir olması. Javascript tarafından webassembly modüllerini çağırıp parametreler geçebiliriz, aynı şekilde wasm modülleri tarafından da javascript fonksiyonları çağırabiliriz.
İki büyük yanlış anlaşılmayı da gidermek adına burada da söylemem de fayda var.
- WebAssembly javascript yerine gelmedi. Aksine onu tamamlayıcı, onunla beraber çalışabilir bir dil. Javascript hayatına olduğu gibi devam edecek tabii ki.
- WebAssembly ile yazmak demek artık server side ihtiyacı yok demek değil asla.Bunun yerine şunu söylersek doğru olur, önceleri javascript ile client side tarafında yapamayacağımız yoğun hesaplama işlemleri içeren bir sistemi artık server side a ihtiyaç duymadan client-side tarafta yapabiliriz. Örneklersek;
- Video/Audio Editing, Streaming, Calling
- Game
- Virtual/Augmented Reality
- AI (Image Recognition vs..)
WebAssembly nin performansı sayesinde yukarıdaki örneklerden oyun a örnek olarak aşağıdaki oyuna bir göz atabilirsiniz.
https://www.funkykarts.rocks/demo.html
Bu oyun yerçekimini simülasyonu hesaplamalarını tamamen client-side tarafında webassembly ile yapan bir oyun.
Diğer yapılanlar için buraya bakabilirsiniz.
WebAssembly Yazmanın Yolları
WebAssembly ile kod geliştirmek için farklı yöntemler mevcut. Bunların neler olduğuna bakalım.
WAT Formatında Kod
Doğrudan wasm formatında kod yazmak çok gerçekçi ve mümkün olmadığından, bununla eş düzeyde wat formatında, insanın okuyup yazmasına çok daha müsait formatta wat kodumuzu yazıp wasm a derleyebiliriz.
İşleyiş şu şekilde oluyor.
Sol tarafta gördüğünüz gibi WAT formatında kodunuzu yazıp The WebAssembly Binary Toolkit ile runtime ın anlayabileceği WASM formatına dönüştürebilirsiniz.Bu dönüşüm işlemleri için hali hazırda başka tool larda yazılmakta fakat şu an en popülerlerinden birisi bu.
Peki bunu gerçekten deneyelim.
https://webassembly.studio/ sitesine giderek, yeni bir proje oluşurup bunu web ortamında build edip javascript içerisinde çağırıp sonuçları gözlemleyebilirsiniz.
webassembly.studio sitesine gittiğinizde karşınıza bir popup da istediğiniz proje tipini soran bir popup çıkacak.Burada bir çok highlevel dilin yanında Empty Wat Project seçerek, wat formatında kodunuzu yazabilirsiniz.
Empty Wat Project seçtiğinizde karşınıza aşağıdaki gibi bir solution yapısı çıkıyor. src altında main.html, main.js ve main.wat dosyaları olduğunu görüyoruz. Burada .wat dosyasında wat formatında kodumuzu yazıp, Build&Run diyerek sonuçları aynı ekran üzerinde gözlemlememiz mümkün.
Aşağıdaki $add fonksiyonu basitce iki adet sayıyı ekleyip geri dönen bir function. Burada kod yazmak istediğiniz de inetllisense bile mevcut. sytnax a alışmak biraz vakit alıcak olsa da, doğrudan wasm yazmayla zorluk derecesi kıyaslanamaz bile 🙂
Aşağıda ise, javascript doyasından bir wasm modülünün nasıl çağırıldığını görüyoruz. Bu da aslında WebAssembly yazmanın bir başka yolu diyebiliriz. Modülü instantiate ettikten sonra ilgili fonksiyonu export ederek kullanabiliriz.
main.html tarafında ise bildiğimizi dışında hiçbirşey yok. aşağıdaki gibi basit bir html koduna sadece main.js eklenmiş.
Build&Run diyerek bu kodları çalıştırdığımızda çıktı aşağıdaki gibi ekranın sağ alt köşesinde gözüküyor.
Ek olarak bir de solution tarafında bir output folder ı görüyoruz.Burada wat kodumuzun dönüşmüş olduğu wasm kodunun nasıl olduğuna bakmak için, main.wasm doyasına sağ tıklayarak alttaki seçeneklerden View as Binary yi seçersek, ekran da bize yazdığımız wat kodumuzun wasm a çevrilmiş halini gösterecektir.
Microsoft Blazor Tool Chain
Higl-level bir kodun wasm a derlenerek js runtime da çalışabildiğini söylemiştim, ki zaten bu javascripte göre en büyük artılarından bir tanesi webassembly nin.
Bir çok dil için farklı Tool lar mevcut. Biz bir C# / Razor kodumuzun nasıl webassembly e dönüştüğü kısmına bakacağız.
Aşağıdaki resimde ana fikri görüyoruz. Detaylarına değineceğim.
Burada anlatılan aslında şu;
- Yazdığımız C# kodu normal hayatta olduğu gibi bir .dll dosyasına dönüştürülür.
- Bu .dll dosyası, wasm formatına dönüştürülerek mono.wasm runtime u üzerinde çalışır.
- mono da, aslında js runtime u üzerinde çalışır.
Yani aslında yazdığımız kod .dll e dönüştükten sonra, mono sayesinde, ilgili formata dönüştürülüp mono runtime üzerinde çalışır. yani kodumuz direk js runtime üzerinde değil, mono runtime ında çalışır, mono runtime ı da js runtime üzerinde çalışabildiğinden, en nihayetinde yazdığımız C# kodu, mono sayesinde javascript runtime üzerinde wasm tipinde çalışan bir kod haline gelir.
Sadece bu bile Mono yu yani Xamarin i(mono project i başlatan ekip sonuçta, hatta başlatan kişi 🙂 ) çok fazla sevmek için bile tek başına yetebilecek bir sebep.
Blazor ın Client-side ve server side tarafında çalışma şekilleri farklı. Bunların detaylarına bir sonraki yazımda gireceğim. Asp.Net Core 3.0 ile beraber ne şekilde kullanabiliyor olacağız, bunları inceleyeceğiz.
WebAssembly tarafına ufak bir girişten ve Blazor için C#/Razor kodunun browser da çalışır hale gelmesi akışını sadece akış olarak inceledikten sonra, bir sonraki yazımda sizlere Visual Studio üzerinde Blazor ile neler yapabiliyoruz bunları da göstermek istiyorum.
Bir sonraki yazımda görüşmek üzere.

UrhoSharp ve Xamarin Workbook
Herkese Merhaba,
Bir önceki yazımızda Urhosharp’ın ne olduğundan ve bu kütüphaneyi kullanmak için bilmemiz gereken temel terimlerden bahsetmiştik. Bu yazımızda da bu terimleri kullanarak, Xamarin Workbook ile bir kaç örnek yapacağız. Örnekleri Workbook ile yapmayı seçmemin sebebi, hem Xamarin Workbook u biraz tanıtmak ve ne kadar kullanışlı olduğunu göstermek, hem de kod tarafında yaptığımız en küçük değişiklikleri anında görmek, telefona deploy etmenin verdiği zaman kaybından kurtulmak.
Tamamen ücretsiz ve çok kullanışlı olan Xamarin Workbook’u hem windows hem de Mac için buradan indirebilirsiniz. Örnekleri inceleyebilir ve geri bildirimlerde bulunabilirsiniz.
Xamarin Workbook’u bilgisayarımıza indirip kurduğumuzda yandaki şekilde gördüğümüz gibi bir ikonla karşımıza çıkıyor.Bu ikona tıklayarak Workbook u açıyoruz.
Workbook u ilk açtığımızda karşımıza bir template seçim ekranı geliyor. Burada Android, iOS, WPF, Console (.Net Framework veya .Net Core )seçimi yaparak workbook u hazırlıyoruz. Ben bu örneğimizde Console (.Net Framework) seçerek ilerliyeceğim.
Artık seçimlerimizi yapıp boş bir Workbook açmış olduk. Bu ekranda yapabileceklerimizden biraz bahsedip, örneğe giriş yapacağım.
Sol tarafta, workbook’u oluşturduğumuz ismin altında iki adet tab mevcut. Biri NuGet packages, diğeri kodlarımızı ve notlarımızı yazacağımız workbook’umuz. Tıpkı Visual Studio dan alışık olduğumuz gibi istediğimiz Nuget Package ı projemize ekleyip, projemizde kullanabiliyoruz. Hemen orta bölümde ise, workbook’umuzun kendisi mevcut, boş bir Executable cell ile gelmiş halde duruyor. Workbook’a iki farklı satır(cell) ekleyebiliriz. Bunlardan biri Executable C# Cell bir diğeri de Documentation Cell. Her bir hücrenin en alt sağ tarafında, 3 buton mevcut. Bu butonları kullanarak, ilgili hücreyi silebilir, yeni bir dökümantasyon yada C# executable cell ekleyebiliriz. eklediğimiz hücre eğer çalıştırılabilir C# hücresi ise, hemen sol alt tarafında bir play butonu görüyor olacağız. Bu butona bastığımızda, o hücre çalışacak ve bize o blokta ki çıktıyı (genellikle aynı hücre içerisinde en son satırda yazdığımız kodun çıktısı) hemen hücrenin altında bize gösterecek.
Workbook ile çalışırken dikkat etmemiz gereken önemli bir konu var. yukarıda bahsettiğim gibi, her bir executable cell çalıştığında, çıktıyı bize alt tarafında gösterecek, yani her bir hücrenin geriye birşey dönmesi gerekli. Normalde, Visual Studio kullanarak bir UrhoSharp örneği yapmaya kalkışsak, kendi Application objemizi, Urho.Application sınıfında türetip, gerisini bu application sınıfına bırakırdık. Bu miras aldığımız Application objesi, bizim kendi application objemiz içerisindeki “Run” methodunu tetikleyip, uygulamamızı başlatır, ve biz bir şekilde uygulamayı kapatmadığımız sürece de durdurmazdı. “Run” methodu da blocker bir method olduğundan, Workbook’ta kullanıma uygun değil malesef. Ama tam olarak bu workbook’ta kullanımımıza sunulmuş bir nesne var. SimpleApplication nesnesi bizim için, bazı initialization işlemlerinden sonra, bize bir application nesnesi dönüyor ve bunun üzerinden işlemlerimizi yapmaya devam edebiliyoruz.Bununla da kalmıyor, bizim için bir Camera, Light ve bir RootNode u üretmiş olarak kullanımımıza sunuyor.
Bir diğer dikkat etmemiz gereken konu ise, Workbook içerisindeki her bir executable cell tekrar tekrar çalışabilir olduğundan, uygulamamızda yapacağımız bazı işlemlerin, öncesinde tersini yapmamız gerekecek. Örneğin, Scene’imize bir node eklemeden önce o node u sileceğiz, veya bir event tanımladığımızda onun öncesinde de biraz reflection kullanıp kaldırmamız gerkecek. Bu tarz küçük handikapların dışında, workbook ile çalışmaya başladığınızda, özellikle yeni bir şeyi öğrenme konusunda ne kadar işe yarar olduğunuz göreceksiniz.
Artık örneğimize geçebiliriz. Nuget Packages‘a sağ tıklayıp, “Add Pacakge…” butonuna basarak karşımıza gelen ekrandaki Search kısmına UrhoSharp yazıyoruz ve UrhoSharp1.5.22 paketini çift tıklayarak yada alt taraftaki Add Package butonuna basarak Workbook’umuza ekliyoruz.
Bu paketi projemize eklediğimizde, ilk executable cell imizde #r “Urho” şeklinde ilgili kütüphanenin referansının workbook a eklendiğini göreceğiz. Bir Executable daha açıp, workbook’ta kullanacağımız namespace’leri ekliyoruz. Bu örneğimizde sadece Urho namespace’i yeterli olacak. Ctrl + Enter ‘a basarak veya hücrenin altındaki play butonuna basarak ilgili hücreyi çalıştırabiliriz. Workbook bizim için yeni bir executable cell oluşturacaktır. kod yazarken bir sonraki satıra geçmek için Shift + Enter’a basabiliriz.
Namespace’imizi ekledikten sonra. Bahsettiğimiz SimpleApplication sınıfının static Show metodunu kullanarak kendimize, belirttiğimiz boyutlarda bir 3D canvas açıyoruz. bundan sonraki her işlemimizi bu canvas üzerinde göreceğiz. Static Show metodu bizden bir application options nesnesi bekliyor. Yeni ApplicationOptions oluşturup, canvasımıza istediğimiz width ve height ı verip canvas ı oluşturuyoruz.
Bu örneğimizdeki amacımız ekrana sadece basit bir çizgi çizmek =) Bunu yaparken bir önceki yazımızda bahsettiğimiz terimlerin nasıl kullanıldığını göreceğiz. Sonraki örneklerimiz daha komplike olacağından, bu terimleri kullanmaya alışmamızda fayda var.
Öncelikle, boş uzayda bir çizgi çizmek için ihtiyacım olan iki noktayı tanımlayacağım. Sonrasında bu noktaları VertexBuffer nesnesinde birleştirip, devamında Geometry, Model, Material, StaticModel, Component ve Node sınıflarını kullanarak, bu çizgimizi canvas’ta göstereceğiz.
VertexBuffer.PositionNormal[] vertices = { new VertexBuffer.PositionNormal{ Position = new Vector3(0,0,0) }, new VertexBuffer.PositionNormal{ Position = new Vector3(2,0,0) } };
Yukarıdaki şekilde bir Vertex dizisi oluşturduk. Hatırlayalım; Vertex oluştururken, bunu VertexBuffer sınıfında tanımlanmış public structure’ ları kullanarak yapıyoruz demiştik. Sadece Position özelliklerini tanımlayıp bir Vertices(birden çok vertex e verilen ad) oluşturdum. Bu Executable Cell i çalıştırdığımda, workbook bana hücrenin çıktısını yani iki elemanlı VertexBuffer.PositionNormal dizisini aşağıda gösteriyor.
Sırada VertexBuffer nesnemizi oluşturmak var.Aşağıdaki şekilde bir VertexBuffer objesi oluşturyorum. SetSize ve SetData metodları ile değerlerimi set ediyorum.
var vertexBuffer = new VertexBuffer(Application.CurrentContext, false){ Shadowed = true }; vertexBuffer.SetSize((uint)vertices.Length, ElementMask.Position | ElementMask.Normal, false); vertexBuffer.SetData(vertices);
Şimdi bu vertexbuffer’ ın ne şekilde birleşeceklerini söyleyeceğim nesenemi yani Geometry’ imi tanımlıyorum.
var geometry = new Geometry(); geometry.SetVertexBuffer(0, vertexBuffer); geometry.SetDrawRange(PrimitiveType.LineList, 0, 0, 0, (uint)vertices.Length, true);
Sırada Model sınıfımı tanımlamak var. oluşturduğumuz geometry nesnelerini Model nesnesi ile bir araya getirebiliyorduk. BoundingBox propertysine set ettiğimiz değerlerin bu örnek için bir önemi yok, o yüzden biri orijinde diğeri (1,1,1) noktalarında iki Vector3 tanımladım.
var model = new Model(); model.NumGeometries = 1; model.SetGeometry(0, 0, geometry); model.BoundingBox = new BoundingBox(new Vector3(0,0,0), new Vector3(1,1,1));
Oluşturmuş olduğum bu Model objemin görselliği ile alakalı değerleri Material nesnesi ile set ediyoruz. Bu örnekte basitçe, bir desen kullanmadan sadece bir mavi renkten oluşan Material oluşturuyorum.
var material = Material.FromColor(Color.Blue);
Sonunda ekranda göstermek istediğim modelimi oluşturmuş oldum. Bunu Simple Application’ın benim için oluşturduğu RootNode’a yeni bir node ekleyerek, ekranda gösterme kısmınıda yapıp, artık bu mavi çizgimi oluşturduğum canvas’ta görmek istiyorum. Workbook’ta her bir executable cell, tekrar tekrar çalışabileceği için, oluşturacağım node’u önce RootNode’dan kaldırıyorum ki duplicate node’larım olmasın.
app.RootNode.RemoveChild(app.RootNode.GetChild("lineNode")); var lineNode = app.RootNode.CreateChild("lineNode"); var line = lineNode.CreateComponent(); line.Model = model; line.SetMaterial(material);
Veee sonunda canvas’ımızda da şekilde ki gibi bir mavi çizgi görüyoruz.
Bir sonraki yazımızda, biraz daha kod ağırlıklı bir örnek yapacağız. O zamana kadar bu temel terimleri anlamakta ve en temel anlamda kullanmakta fayda olacaktır.
Bu örnekte yapmış olduğum workbook dosyasını şuradan indirebilirsiniz.
Bir sonraki yazıda görüşmek üzere…

UrhoSharp’a Giriş
Herkese Merhaba,
Bu yazımda 29 Eylül 2017 Cuma akşamı Yiğit Özaksüt ve Cihan Yakar ile gerçekleştirdiğimiz Xamarin Istanbul Development Meetup etkinliğinde anlattığım UrhoSharp’tan bahsedeceğim.
Meetup’taki sunumumu şuradan indirebilirsiniz.
Şimdi UrhoSharp konusuna gelelim. UrhoSharp, Urho3D adıyla hayata geçmiş ve başarılı bir 3D grafik ve oyun motoru olan Cross-Platform çalışabilen ve C++ API’a sahip projenin, tam olarak Xamarin ve diğer Microsoft ortamlarında çalışabilecek C# / .NET wrappers ile yeniden yazılmış halidir.
3D konusuna daha önceden hiç bulaşmamış olanlar için öncelikle UrhoSharp’ı kullanırken fazlaca kullanacağımız birkaç terimden bahsetmek istiyorum.
- Vertex / Vertices
- VertexBuffer
- Geometry
- Model
- Material
- StaticModel
- Node
- Light
- Camera
- Scene
Bunların neler olduğundan bahsedelim. Boş uzaydaki tek bir noktayı düşünün, bu noktayı UrhoSharp’ta tanımlamak için kullandığımız nesne Vertex ama kendisini tam olarak bu isim ile değil de VertexBuffer nesnesi içine tanımlanmış public structure’lar olarak göreceğiz. Birazdan detaya ineceğim ama öncesinde, boş uzaydaki bu noktanın (yani Vertex in) sahip olduğu özelliklerden bahsetmek istiyorum. Hepinizin tahmin edeceği üzere olmazsa olmaz ilk özellik bu Vertex‘in uzaydaki koordinatı (Position). Bu özelliği UrhoSharp içerisinde yine bolca kullanacak olduğumuz Vector3 nesnesi ile belirtiyoruz. Bu Vector3 nesnesi bizden x, y ve z koordinatlarını isteyen constructure’a sahiptir. Mesela basit bir Vector3 nesnesini şu şekilde tanımlayabilirsiniz:
var coordinate = new Vector3(0,0,0);
(Bu kod ile 3D uzayda, tam orijinde duran, x, y ve z değerleri 0 olan bir Vector3 tanımlamış olduk)
Vertex‘ in önemli 3 diğer özelliği daha vardır:
- Normal: Vertex’in bulunduğu yüzeye dik olan vektördür. Bu özellik öncelikle bize ışık ile etkileşime girme konusunda çok fayda sağlayacak.
- Color: Vertex in sahip olacağı renk.
- Texture: Vertex in bulunduğu yüzeyi kaplayacak olan dokunun, bu vertex için olan 2 boyutlu koordinatıdır. Vector2 ile tanımlıyor olacağız.
Boş uzayda tanımadığımız bu noktaları, bir araya getirmek için kullanacağımız nesnemiz ise VertexBuffer olacaktır. Yukarıda söylediğim gibi Vertex UrhoSharp’ta programatik olarak birşeyler çizebilmemiz için gerekli olan en küçük parça ama onu bu isimle görmeyeceğiz demiştim. İşte ilgili özellikleri ile bu vertex’i, VertexBuffer altındaki public structure’lar ile şu şekilde tanımlayabilirsiniz:
var VertexBuffer.PositionNormal = new VertexBuffer.PositionNormal {…}
var VertexBuffer.PositionNormalColor = new VertexBuffer.PositionNormalColor {…}
var VertexBuffer.PositionNormalColorTextcoord = new VertexBuffer.PositionNormalColorTextcoord {…}
Position özelliği dışında, diğer özelliklerini boş geçerek bir Vertex tanımlaması yapabilirsiniz. Bir de çokça duyacağınız Vertices adından bahsedeyim. Bu aslında birden fazla Vertex için duyacağınız isimdir yani bir üçgen oluşturmak için 3 adet Vertex tanımladınız diyelim, bu arkadaşları hep beraber çağırmak için Vertices adını kullanacaksınız, bilginiz olsun.
Peki, devam edelim. Noktaları oluşturdunuz ve VertexBuffer içinde bunları topladınız, bu noktaların ne şekilde birleşeceklerini nasıl söylüyoruz?
Geometry: Bu sınıfı aynı ismiyle UrhoSharp’ta yine çokça kullanmanız gerekecek. Geometry, bir veya birden fazla VertexBuffer nesnesinin ne şekilde birleşeceklerini ve nasıl yorumlanacaklarını söylemek için kullanacağımız bir nesnedir.
Vertices hazır, VertexBuffer’lar hazır, Geometry ‘er hazır. Tüm bunlardan sonra bu Geometry nesnelerini bir araya getirip bir görsel tanımlama işine bizi yaklaştıran önemli sınıflardan biri ise Model sınıfı olacak. Model sınıfı ile bir veya birden çok geometry objesini bir araya getirip bir model yaratmış olacağız. Bunu projemize önceden tanımlanmış haliyle, “.mdl” uzantılı dosya olarak ekleyebiliriz ya da programatik olarak bunu başarabiliriz.
Material: Oluşturduğumuz bu model nesnesinin, 3 boyutlu görselliği ile alakalı bileşenlerini Material nesnesi ile tanımlıyoruz. İstersek sadece bir renk verebiliriz (ki bu durumda Vertex’i tanımlarken verdiğimiz Color değerlerini ezmiş oluruz, ama ezmemenin de yolları var tabii.) istersek de bir bitmap vb şekilde yüzeyi kaplayacak olduğumuz dokuyu verebiliriz.
Bu Model ve Material nesnelerini biraraya getirip, nihai bir görsellik sağlamak için kullancağımız sınıf ise StaticModel component’i olacaktır. Hazır Component demişken, hemen ondan da kısaca bahsedelim. Component nesnesi ile artık hali hazırda olan modelimizi hayata geçirebiliyoruz. Hayata geçirmekten kastım, öylece duran modellerimize, eklediğimiz Component’ler sayesinde, ses yaymalarını, fizik kurallarından etkilenmelerini ve birbirleri ile etkileşime geçmeleri gibi birçok özelliği vermek.
Peki artık modellerimiz hazır, belli componentler ile belli özellikler de aldılar peki bunları ekranda nasıl gösteriyor olacağız?
Son 3 önemli terimden bahsetmek istiyorum,
- Camera: 3D ekranımızda Camera nesnesi kendi görüş alanında kalan herşeyi bize gösteriyor olacak. Camera objesininde tabii ki, uzayda bir Position‘ı ışık yayma şekli ve bir görüş alanı olacaktır. Bu görüş alanını FOV (Field Of View) dediğimiz özelliği ile belirteceğiz. (Default hali 45 derecedir.)
- Light: UrhoSharp’ ta 3 tip ışık var. Bu ışıkları sahnemizi aydınlatmak ve tüm objelerimizin ne şekilde görüneceğini belirlemek için kullanıyoruz. Tam burada şunu söylemek isterim ki 3D Grafikte Curve (eğri) yüzey diye bir tanım yoktur aslında. Eğim olarak gördüğümüz şey, ışığın geliş şekli ve o yüzeyi oluşturan Vertices’in Normal vektörleri ile yaptıkları açıların etkileşiminden başka bir şey değildir.
- Directional: Belli bir yönden gelen ve o doğrultuda ilerleyen sonsuz ışındır. Güneş ışını gibi düşünebilirsiniz.
- Point: Belli bir noktadan gelen ve tüm doğrultularda yayılan ışındır. Bir ampulün yaydığı ışın olarak düşünebilirsiniz.
- Spot: Belli bir noktadan gelen ve belli bir doğrultuda görülecek ışındır. El feneri gibi düşünebilirsiniz.
- Scene: Tüm modellerimiz ve kamera ile ışık sayesinde oluşturduğumuz sahneyi temsil etmektedir.
Bu kadar fazla terimden bahsettikten sonra örnek yapmadan olmayacaktır tabii ki. Bir sonraki yazımda, tüm anlattıklarımı içeren, güzel örnekler ile karşınızda olacağım. O zamana kadar, bu terimleri sindirmenizi, UrhoSharp ile ilgili bulduğunuz yazıları okumanızı öneririm. Birkaç yardımcı link vermek isterim:
- Xamarin.com da buradaki linkten başlayarak ilgili tüm UrhoSharp yazılarını okumanızı öneririm. UrhoSharp’ı Xamarin.Forms ile kullanabileceğimiz gibi, tabii ki Xamarin.iOS yada Xamarin.Android ile de kullanabiliriz. Hatta Xamarin dışındaki diğer Microsoft yazılım platformalarında da rahatça kullanabilirsiniz. En nihayetinde başarılı bir C++ API ile yazılmış kütüphanenin C# ve .NET wrapper ile devşirilmiş halini kullanıyorsunuz.
- Bu temelleri anlamadan biraz sert kaçar ama, geçenlerde Charles Petzold abimizin yaptığı webiner ı izlemenin de ilerideki aşamalarda faydası olacaktır. Kendisi kod ile mobiusstrip yaptı, izlemeye kesinlikle değer.