ჩემი ზაფხულის საკითხავი 2015

me
ეს ორი კვირა დასასვენებელი და გასანიავებელი შვებულება მქონდა : ) როცა ინტერნეტს ვშორდები, საკითხავადაც დრო მრჩება და ეგ ჩემი საყვარელი ნაწილია ხოლმე ცურვის და თამაშის მერე. წიგნების პატარა მიმოხილვებს გაბნეულად, ხან სად ვწერ და ხან სად. გადავწყვიტე ამ შვებულების წიგნები ამ პოსტში გავაზიარო, იქნებ ვინმეს მოეწონოს რომელიმე…


Surely You’re Joking, Mr. Feynman!

ცნობილი ფიზიკოსი და ნობელის პრიზიორი, რიჩარდ ფეინმანი, ძალიან სახალისო და სათავგადასავლო ისტორიებს ყვება. ბავშვობის გამოგონებები, ატომურ ბომბზე მუშაობა, სეიფების გატეხვა, ბოროტი ხუმრობები, ნაშრომები ბიოლოგიაში, ბრაზილიის კარნავალზე მუსიკოსების კონკურსში მონაწილეობა, საკუთარი ნახატების გაყიდვა, ლექტორობა, კვლევები და ‘აჰა!’ მომენტები. როგორ მოასწრო ამდენი რამე არ ვიცი :) ) ფიზიკითაც კი დამაინტერესა.

Elon Musk: Tesla, SpaceX, and the Quest for a Fantastic Future

ოცნება ხო მოიუწვდომელი და არარეალისტურია. ჰოდა მეც ბოლო დროს ერთი ეგეთი დამჩემდა, რომ ელექტრომობილების ქარხანა მქონოდა საქართველოში. ამ წიგნმა ცოტა შეფერთხა, რადგან დამანახა როგორი არაადამიანური მუშაობა და ფინანსები სჭირდება ამ ყველაფერს, მაგრამ ჯერ ჯერობით მაინც დავიტოვებ. იქნებ როდისმე სურვილამდე დაწინაურდეს და მართლა დავიწყო მაგ სფეროში მუშაობა.

თვითონ წიგნი ძალიან დიდ მოტივაციას იძლევა ზოგადად. ბევრი ისტორიაა მოყვანილი SpaceX, Tesla-სა და SolarCity კომპანიების შექმნის და განვითარების შესახებ – ჩავარდნები, გამართლებები და სირთულეების გადალახვის ამბები. განსაკუთრებით შთამბეჭდავია SpaceX-ის რაკეტის აწყობა და გაშვება დიდი ტექნოლოგიური თუ მენეჯმენტური ნახტომებით. ელექტრომობილი ხომ საერთოდ…
სათავგადასავლო წიგნს არაფრით ჩამოუვარდება. პროგრამისტებს და ელექტრონიკებს განსაკუთრებით მოეწონებათ ჩემი აზრით, მენეჯერებსაც.

Zero to One: Notes on Startups, or How to Build the Future

ეს Paypal-ის ერთ-ერთი დამაარსებლის, Peter Thiel-ის წიგნია. ამიტომაც და თან კარგი რევიუების გამო ავირჩიე, მაგრამ შუამდეც ვერ მივედი ისე მივატოვე. ცოტა გამიცრუა მოლოდინი, შეიძლება უბრალოდ სტარტაპებზე ჩემთვის აღარაფერი იყო ახალი და იმიტომ. კიდევ რაღაცები არ მომეწონა დასათანხმებლად (მაგალითად – როცა ამბობს რომ კონკურენცია პირიქით ყველაფერს აფუჭებს). ამ თემატიკაზე ჩემს ფავორიტად ჯერჯერობით მაინც წიგნი Rework რჩება.

fahrenheit 451 Fahrenheit 451 (სპოილერებით)

ბრედბერი და კონკრეტულად ეს წიგნიც დიდი ხანია რიგში მყავდა. ახლა ვნახე, მაგრამ სიმართლე ვთქვა ცოტა ამანაც გამიცრუა იმედი. სულ დანაკლისის გრძნობა მქონდა და სამყაროს მეტი აღწერა მჭირდებოდა. ვერ დავინახე რამ ჩაანაცვლა წიგნები და რა პრობლემები ჰქონდათ იქაურებს. ასე მარტივად ხო ვერ გადავიდოდნენ სულ ვერბალურ კომუნიკაციაზე და ინფორმაციის შენახვაზე. 1984 გაცილებით რეალური იყო ჩემთვის, ვიდრე ეს.
ისე, რაც დრო გადის, სულ უფრო ვშორდები მხატვრულ ლიტერატურას და ცოტა გული მწყდება. არ ვიცი რა მომდის, პერსონაჟებზე ვბრაზდები ხოლმე :) ) ან შეიძლება რეალური ისტორიები ისეთი საინტერესოა, non-fiction-ებიდან ვეღარ გადმოვდივარ.

why-zebras-dont-get-ulcers-big Why Zebras Don’t Get Ulcers

მე, როგორც მედიცინისგან შორს მყოფ ადამიანს, ძალიან მიყვარს ისეთი სამედიცინო წიგნები, სადაც ჩვეულებრივი მოკვდავებისთვის გასაგებ ენაზე წერია რთული თემები. ეს წიგნი ერთ-ერთი დიდი ფავორიტია მაგ მხრივ. არა მხოლოდ გასაგებ, არამედ იუმორის ენით წერს საპოლსკი და ამასთან ძალიან ბევრ საჭირო რამეს აღწერს ორგანიზმის და ტვინის მუშაობის შესახებ.

creativity incCreativity, Inc.: Overcoming the Unseen Forces That Stand in the Way of True Inspiration

პიქსარი და დისნეი – ჩემთვის ორი უნიკალური, ზე კომპანიაა, სადაც ზე შემოქმედი ადამიანები ზე ფილმებს ქმნიან.
ედ კატმული პიქსარის თანადამფუძნებელი და ამჟამად პიქსარისა და დისნეის პრეზიდენტია. მან, როგორც პროგრამისტმა, დიდი წვლილი შეიტანა კომპიუტერული გრაფიკის ჩამოყალიბება-განვითარებაში და ფილმების ინდუსტრიაში შეიტანა ეს სფერო ფაქტიურად. (მაგალითად, მას მიაწერენ Z-buffer ტექნოლოგიის გამოგონებას, რომელიც დღეს ყველა კომპიუტერსა და მობილურშია.) კატმული წერს თუ რა ხდებოდა ფარდის უკან პიქსარის მულტფილმებზე მუშაობის დროს, რა სირთულეები ჰქონდათ, როგორ დაიწყო ყველაფერი და ზოგადად როგორი კულტურაა კომპანიაში, რომლის ყოველი ფილმიც შედევრია და წინაზე უკეთესი.
წიგნის ნახევარი ზედმეტია ჩემი აზრით, მაგრამ კარგი მარგალიტებია აქა-იქ გაბნეული.

ios8 fundamentals iOS 8 Programming Fundamentals with Swift

წინა პოსტებში ვახსენე რომ ბოლო პერიოდი iOS-ზე და მაგათ ახალ პროგრამირების ენაზე ვმუშაობდი. Apple-ს გამოქვეყნებული აქვს წიგნი The Swift Programming Language რომელშიც ენა საფუძვლიანად არის აღწერილი, თუმცა მაგის წაკითხვის მერე ძალიან მაკლდა best practices ნაწილი და მაინც ბევრს ვწვალობდი კოდის ნორმალურ სახემდე მისაყვანად. ზოგადად ასე დროის დაკარგვა არ მიყვარს და იმიტომ ვიწყებ ხოლმე ენის სწავლას წიგნებით. აი Matt Neuburg წიგნები სულ სხვა თემაა. ის რეალური მაგალითებით და საკუთარი გამოცდილებით ავსებს მათ. ამიტომ გაცილებით შემიმსუბუქა ბევრი რამ. ამ ენას ვინც იწყებს, მეც მის წიგნებს გირჩევდით.

programming_ios_8_deep_dive Programming iOS 8: Dive Deep into Views, View Controllers, and Frameworks

ესეც Matt Neuburg-ის წიგნია (შედარებით advanced საკითხებით) და სიღმისეულად წერია საფუძვლები. აქაც არის მაგალითები მისი საკუთარი პროგრამებიდან და ასევე ძააალიან ბევრი პრობლემის გადაწყვეტა. ჯერ ვერ დავასრულე, ათასი გვერდია, მაგრამ უკვე ვნანობ აქამდე რომ უმაგისოდ დავკარგე დრო.

The Timeless Way of Building

ეს ერთ-ერთი ყველაზე გავლენიანი წიგნი იყო ჩემთვის და მინდა მასზე დავწერო :) ძალიან უცნაური მიზეზით გადავაწყდი – პროგრამირების პატერნების თითქმის ყველა წიგნში იყო ციტატა აქედან, არადა Timeless way of building საერთოდ არ ეხება პროგრამირებას, არქიტექტურაზეა (და მარადიულობაზე).
ცნობილი არქიტექტორი, კრისტოფერ ალექსანდერი, აღწერს იდეოლოგიას, თუ როგორ უნდა აშენდეს შენობები, ბაღები, გზები, ქალაქები რომ ნაგებობებმა საუკუნეებს გაუძლოს არსით. საუბრობს არა მხოლოდ შენობებზე, არამედ ცხოვრებაზე.

ჩემდა სამარცხვინოდ უნდა ვაღიარო, სათანადოდ არ ვაფასებდი და პატივს არ ვცემდი ამ სფეროს. ალბათ იმიტომ რომ არქიტექტორებმა გამაბრაზეს. დიახაც, გამაბრაზეს. არ მომწონდა რომ არ ფიქრობდნენ ჩვენზე; რომ ნორმად გახადეს დაბალჭერიანი, ერთნაირი ბინები პატარა ოთახებით და ცოტა ფანჯრებით, პატარა სამზარეულოთი და კიდევ უფრო პატარა აბაზანით, მეზობლების ნაბიჯების ხმით, უბაღეობით და უხეებობით. ოფისები საავადმყოფოებს ან, უარეს შემთხვევაში, ციხეებს დაამსგავსეს, მიწას და სიმწვანეს მოაცილეს.

შეიძლება არ მომწონდეს არქიტექტურა, მაგრამ მეც კი ვხვდები გარემოს რამხელა გავლენა აქვს ჩვენს განწყობაზე, პროდუქტიულობაზე, ენერგიულობაზე – საბოლოო ჯამში ფაქტიურად ჩვენს საქმიანობაზე და მთელს ცხოვრებაზეც. აი ასეთი რთული მისია აკისრიათ არქიტექტორებს. რეალურად მათ უამრავი სოციალური, ეკონომიკური და ფსიქოლოგიური პრობლემის გადაწყვეტა შეუძლიათ.

კრისტოფერის წიგნში ბევრ გემრიელობას შეხვდებით ამ თემაზე. ის წერს თუ რა განასხვავებს კარგ და ცუდ ნაგებობას, კარგ და ცუდ ქალაქს, საუბრობს “თვისებაზე”, რომელსაც “სახელი არ აქვს” – რომელიც განსაზღვრავს იქნება თუ არა გარემო ერთიანი, ჯანმრთელი, ცოცხალი, თვით განვითარებადი – სადაც სიცოცხლე იქნება, სადაც ადამიანებს განვითარების და შემოქმედების სურვილი ექნებათ.

მე მოკლედ და კარგად ვერ გადმოვცემ მის იდეოლოგიას, ამიტომ საერთოდ არ შევეხები. მაგის გარდა იქ იყო უამრავი პატარა პრაქტიკული მომენტიც და რამდენიმე განსაკუთრებით ჩამრჩა:
მაგალითად, ადამიანები ისეთი ოთახებისკენ მიისწრაფიან, რომელთაც ორ მხარეს აქვს ბუნებრივი განათება. ასე სინათლე რამდენიმე მიმართულებით შემოდის და გაცილებით კომფორტულად აღიქმება.
ან, თუ ოთახები სამხრეთისკენ იხედებიან, სახლი განათებული, მზიანი და კარგი ენერგიით სავსეა. მის წინ ეზოში ყოფნა ძალიან სასიამოვნოა, ჩრდილოეთის მხარეს ბაღში კი იშვიათად გახვალთ.
ან კიდევ ძალიან უცნაურად და ცუდად მოგეჩვენებათ ბინის შესასვლელი კარი რომელიც პირდაპირ ქუჩაზეა და შესვლამდე არ ხდება სივრცის ცვლილება, ან სიმაღლით, ან განათებით, ან მანძილით…

რაც მთავარია, კრისტოფერის პატერნებში ყველაფერს თავისი დანიშნულება აქვს და რაღაც მიზანს ემსახურება. ისე იზრდება და ვითარდება ნაგებობები, როგორც ბუნება ქმნის თავის გარემოს. ერთგან ატმის ხეს იხსენებს, რომელიც აგურის კედელზე იყო აზრდილი სამხრეთის მხრიდან. მზე აგურებს ათბობდა, აგურები კი ატმებისთვის ინახავდნენ სითბოს..

მის მაგალითებში ნაგებობები ბუნებასთან ჰარმონიაში არიან, ამასთან დეტალები პრაქტიკული მიზნებიდან გამომდინარეობენ. ზუსტად ამიტომ ამბობს რომ არქიტექტორები შეიძლება ვერ გასწვდნენ ყველას ინდივიდუალურ მოთხოვნებს და ჩვენ ჩვენით შეგვიძლია საკუთარი გარემოს მოწყობა. უკეთ ვიცით როდის სად რა გვჭირდება.

ამ წიგნის მერე მოგინდებათ ოთახი შეცვალოთ, სახლი და ეზო შეცვალოთ, შეიძლება ჩემსავით ოცნებად გაგიხდეთ აშენება.

(არსებობს წიგნის მეორე უზარმაზარი ნაწილიც, რომელიც არქიტექტურილი პატერნებით არის სავსე. თუ რამეს აკეთებთ ახლა, ძალიან გირჩევდით ამ წიგნების ნახვას.)

Vineyard Farmer's Market

Vineyard Farmer’s Market by Christopher Alexander

Vineyard Farmer's Market

Vineyard Farmer’s Market by Christopher Alexander

მილიარდ დოლარიანი შეცდომა

ასეთი სახელი ჰქონდა ტონი ჰოარის პრეზენტაციას 2009 წლის კონფერენციაზე სადაც პროგრამირების ისტორიაში ცუდი გადაწყვეტილებების შესახებ იყო მოხსენებები. მე მხოლოდ შარშან ვნახე და მას შემდეგ კიდევ ბევრმა წყალმა ჩაიარა, მაგრამ პრინციპში დღესაც აქტუალურია ეს საკითხი და მე მგონი ცალსახად ეფექტური გამოსავალი ჯერ ჩამოყალიბებული არ არის.

პრეზენტაცია 1965 წელს გამოგონილი null reference-ს ეხებოდა, რომელიც მილიარდ დოლარიან შეცდომად შეაფასა მისმა შემქნელმა:

“I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.”

რეალურად, მე არ ვფიქრობ რომ თვითონ null reference-ის შექმნა იყო არასწორი, რადგან მის გარეშე ალბათ ძალიან ძნელი იქნებოდა თუნდაც OOP პროგრამირება, გაცილებით ზედმეტი ლოგიკის წერა და უარესი კომპრომისების და ბაგების მოვლა მოგვიწევდა. ამიტომ შეგვიძლია უფრო type checking სისტემებს დავაბრალოთ null-თან დაკავშირებული პრობლემები. ყოველ შემთხვევაში, ჰოარის პრეზენტაციიდანაც დაახლოებით ასეთი აზრი გამოვიტანე.

კონკრეტულად რომ ვთქვათ აი ასეთ პრობლემაზეა საუბარი (ორაკლის საიტიდან ავიღებ მაგალითს):
წარმოვიდგინოთ ჩანაწერი..

String version = computer.getSoundcard().getUSB().getVersion();

როცა ჯავაში აღვწერთ მეთოდს, მას ვუთითებთ დასაბრუნებელ ტიპს. რეალურად დასაბრუნებელი მნიშვნელობა არ არის ამ ტიპის, არამედ ერთ-ერთია სიმრავლიდან { null, ეს ტიპი }

ფაქტიურად ნებისმიერი მეთოდისგან (რომელიც ობიექტს აბრუნებს) შეიძლება null reference მივიღოთ შედეგად და სანამ ამ შედეგს გამოვიყენებთ, შემოწმება გვიწევს.
ზევით აღწერილი კოდი უსაფრთხო რომ იყოს, ასე უნდა ჩაგვეწერა:

String version = "UNKNOWN";
if(computer != null){
    Soundcard soundcard = computer.getSoundcard();
    if(soundcard != null){
        USB usb = soundcard.getUSB();
        if(usb != null){
            version = usb.getVersion();
        }
    }
}

თუმცა, როგორც წესი, უფრო ხშირად ვცდილობთ რომ ასეთი ჩანაწერი თავიდან ავირიდოთ. best practice-ების მიხედვით რეკომენდირებულია მეთოდი ისე ვწეროთ რომ მან არასდროს დააბრუნოს null, არამედ, ან რაღაცა ცარიელი ობიექტი მიიღოს შედეგად ან checked შეცდომა ისროლოს. ასე ნაწერი კოდი გაცილებით გვაზღვევს runtime-ში null pointer შეცდომებისგან.

მხოლოდ რეკომენდაციების იმედზე რომ არ ვიყოთ, ჯავას მერვე ვერსიაში შემოვიდა Optional ტიპი და ასევე @NonNull @Nullable ანოტაციები და ეს რამე რუმეები საშუალებას გვაძლევს მეტად ინფორმატიული იყოს ჩვენი კოდი და ცოტა კომპილაციის დროსაც მოგვეხმაროს. თუ ვიცით რომ რომელიმე ობიექტი შეიძლება null გახდეს, შეგვიძლია ის Optional კლასის საშუალებით შევინახოთ. და მერე გამოყენების დროს გავითვალისწინოთ ეს საშიშროება.

ჯავაში ასე გამოვიდოდა getSoundcard მეთოდის სიგნატურა:

Optional<Soundcard> getSoundcard()

მერე გამოყენებისას უნდა დავწეროთ

Optional<Soundcard> optional = getSoundcard()
if (optional.isPresent()) {
    Soundcard soundcard = optional.get();
    …..
}

ან სხვა უფრო მოსახერხებელი მეთოდების გამოყენება შეიძლება – orElse, ifElse, ifPresent.. ა.შ.

ზოგ ენაში შემოიღეს მოკლე ჩანაწერიც, მაგალითად Swift-ში შეგხვდებოდათ ასეთი რამ:

var version = computer?.soundcard?.USB?.version

ამ ჯაჭვში ერთ ერთი მაინც თუ დააბრუნებს null-ს, მომდევნო getter-ების გამოძახება აღარ გაგრძელდება და მთელი შედეგი null გამოვა.

Groove ენაში არის ელვისის ოპერატორიც :D რომელიც ასე გამოიყურება ?:

String version = computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";

და მაგითი default მნიშვნელობა შეგვიძლია შემოვიტანოთ null-ის შემთხვევაში.

ბოლო რამდენიმე თვეა რაც Swift-ზე წერას ვცდილობ. ჯერჯერობით ენა არ არის სრულად ჩამოყალიბებული და ხშირად იცვლება. თუმცა ეს კონცეპტი ალბათ არსად წასვლას არ აპირებს. თავიდან ძალიან გამიჭირდა იმასთან შეგუება, რომ ენა გაიძულებს ცვლადის გამოცხადებისთანავე განსაზღვრო optional იქნება ის თუ არა. თუ კი, მაშინ ყველგან სადაც ამ ცვლადის გამოყენებას შეეცდებით, მისი null-ზე შემოწმება და მნიშვნელობის ე.წ. unwrap მოგიწევთ optional ტიპის ცვლადისგან. კოდი არ დაკომპილირდება სხვა შემთხვევაში.

ამ პოსტში ელდარი უნდა დავთაგო : )) ერთხელ მასთან ვიწუწუნე ამ თემაზე და იმ დღეს დამაფიქრა, შემაცვლევინა აზრი. მერე წავედი და გემრიელად დავარეფაქტორე კოდი. არც ისეთი ცუდი ყოფილა ეს optional ტიპი. რაც დრო გადის, ვხვდები, რომ კარგ საქმეს მიკეთებს და მაიძულებს არ გავახალტურო რაღაცები. ასე რომ ვნახოთ.. იქნებ ჯავაშიც გაგვილამაზონ სინტაქსი თორემ დაიკარგება კაცი ამდენ boilerplate კოდში.

საერთო კოდი ბრაუზერსა და node.js აპლკაციაში

წინა პოსტებში ვახსენე რომ ჯავასკრიპტზე მომიწია ანიმაციის ლოგიკის წერა. იგივე კოდი (მათ შორის გეომეტრიაც) ბექშიც მჭირდებოდა, ამიტომ ვიფიქრე – რატომ გადავწერო.. ბექს node.js-ით გავაკეთებ და იგივე კოდს გამოვიყენებ. შესაბამისად თავსებადობის ამოცანა გამიჩნდა.

ცხადია, პირველ რიგში საერთო ბიბლიოთეკებიდან უნდა გამომეყო ბრაუზერთან დაკავშირებული კოდი (DOM-ის მანიპულაცია, ვორკერების ურთიერთობა, ა.შ.). მეორე რიგში node.js-ს ცოტა განსხვავებული მეთოდი აქვს სკრიპტების იმპორტისთვის. თუ ბრაუზერში <script> ტეგს ვიყენებთ, node.js-ში მოდულები უნდა გავაკეთოთ და require მეთოდით ჩავტვირთოთ.

მაგალითად, მარტივი მოდული ასე გამოიყურება (ფაილის სახელია Square.js):

exports.Square = function (side){
	this.side = side;
	this.getArea = function(){
		return side * side;
	}
}

module.exports ან პირდაპირ exports მეთოდს ვიყენებთ იმისთვის რომ ობიექტები გარედან ხელმისაწვდომი გავხადოთ. ამ ფაილში აღწერილი სხვა დანარჩენი ფუნქციები და ცვლადები private იქნება გარე სამყაროსთვის.

მოდულის გამოყენების მაგალითი სხვა ფაილში:

var module = require('./Square');
var square = new module.Square(10);
console.log(square.getArea());

Square.js ფაილი ბრაუზერისთვის თავსებადი რომ გავხადოთ, exports მეთოდს რამე უნდა მოვუხერხოთ.
მაგალითად, შეიძლება შემოწმების ჩამატება:

var Square = function (side){
	this.side = side;
	this.getArea = function(){
		return side * side;
	}
}

if (typeof exports !== 'undefined') {
	exports.Square = Square;
}

აქ კიდევ ერთი მომენტია. როგორც ზევით აღვნიშნეთ, node.js-ში exports-ის გარეთ რაც რჩება, ხელმისაწვდომი არ არის გარედან. ბრაუზერის შემთხვევაში კი Square გლობალური ცვლადი გამოდის. სწორი იქნებოდა, რომ მისი წვდომაც შეგვეზღუდა. მაგალითად ასე:

(function(exports){
	var Square = function (side){
		this.side = side;
		this.getArea = function(){
			return side * side;
		}
	}

	if (typeof exports !== 'undefined') {
		exports.Square = Square;
	}	
})(typeof exports !== 'undefined' ? exports : this['module'] = {});

 

RequireJS + node

არის კიდევ ერთი გზა. ყოველთვის მინდოდა Require.js ბიბლიოთეკის დატესტვა. როგორც აღმოჩნდა მაგას ადაპტერიც აქვს nodejs და მისნაირებისთვის. ასე რომ, ავდექი და Require-ზე გადავაწყე პროექტი. შედეგად ერთნაირი ფორმატით შემიძლია ვწერო მოდულები ფრონტისთვისაც და ბექსითვისაც. თვითონ ბიბლიოთეკაც საკმაოდ მომეწონა. ძალიან მარტივად გადაეწყო ჩემი კოდი და პირველივე გაშვებაზე იმუშავა რაც არ უნდა უცნაური იყოს.

ზევით აღწერილი მოდულის მაგალითი Require.js-ით:

define(function(){
	return function Square(side){
		this.side = side;
		this.getArea = function(){
			return side * side;
		}
	}
});

მოდულის გამოყენების მაგალითი:

requirejs(['Square'], function(Square) {
    var square = new Square(10);
	console.log(square.getArea());
});

JavaScript animation / game loop (ნაწილი 2)

ამ პოსტის წინა ნაწილში requestAnimationFrame მეთოდზე ვისაუბრე, რომლის საშუალებით ბრაუზერის რენდერინგს შეგვიძლია ჩვენი ქოლბექი მივაბათ და შესაბამისად მაგ დროს განვაახლოთ ანიმაციის ან თამაშის მდგომარეობა.

მინდა აღვნიშნო, რომ ამ მეთოდში ჯობია მხოლოდ გადახატვის ლოგიკა იყოს, ხოლო ანიმაციის ან თამაშის ლოგიკის (მდგომარეობების გამოთვლა, ა.შ.) ადგილი იქ ცალსახად არ არის. ამას ბევრი მიზეზი აქვს: ბრაუზერი გვერდის რენდერის დროს სხვადასხვა ფაქტორს ითვალისწინებს – მაგალითად ტაბი აქტიურია თუ არა, ლეპტოპის აკუმულატორი რა დონეზეა, მონიტორი რა სიხშირით ახლდება, ა.შ. შესაბამისად შეიძლება ჩვენი ქოლბექების გამოძახების რაოდენობა შეამციროს ან გაზარდოს დროის კონკრეტულ პერიოდში.

აქედან გამომდინარე, უმჯობესია რომ ანიმაციის ან თამაშის მდგომარეობები ცალკე გამოითვალოს / დაგენერირდეს და requestAnimationFrame-ის ქოლბექში მხოლოდ მათი რენდერის კოდი ჩაიწეროს.

ცალკე გენერაციაც ბევრნაირად შეიძლება. რადგან ეგ მნიშვნელოვნად განსაზღვრავს ჩვენი ანიმაციის წარმადობას, ბევრი ვიფიქრე როგორ გამეკეთებინა და ახლაც არ ვარ დარწუნებული ჩემი კოდის სისწორეში. სხვის მიდგომებს მოვიყვან მაგალითად:

1. შეიძლება setInterval და setTimeout მეთოდებით დაგენერირდეს მდგომარეობები, ხოლო requestAnimationFrame-ის ქოლბექმა აარჩიოს იქიდან შესაბამისი მდგომარეობა და ის დაარენდეროს.

2. პირველი პუნქტის ანალოგიურად მდგომარეობები დროის რაღაც ინტერვალში დაგენერირდეს, თუმცა ეს ლოგიკა ცალკე ნაკადში – მუდმივად გაშვებულ web worker-ში იყოს გატანილი, რომ მთავარი ნაკადი ძალიან არ დაიტვირთოს (ჩემი აზრით ეს უკეთესია). requestAnimationFrame-მა კი worker-დან მიღებული მდგომარეობებიდან შეარჩიოს დროის შესაბამისად და დაარენდეროს გარემო.

3. ეს მეორე პუნქტის მსგავსია, თუმცა setInterval-ის ნაცვლად ინიციატორი requestAnimationFrame-ის ქოლბექი იყოს. მის გამოძახებაში დამატებით იყოს worker-თან შეტყობინების გაგზავნა, რომ ვორკერმა მომდევნო X რაოდენობის მდგომარეობა დააგენერიროს. ასეთ შემთხვევაში, თუ ბრაუზერი არ არენდერებს არაფერს, ჩვენი ნაკადი ტყუილად არ იქნება მუდმივად გაშვებული თავისი მძიმე კალკულაციებით.

ჩემს შემთხვევაში საქმე უფრო ანიმაციასთან მაქვს და არა real-time თამაშთან. მდგომარეობები შემიძლია წინასწარვე გამოვთვალო, ამიტომ ასეთი გზა ავირჩიე: worker-ს ვუშვებ რომელიც მთლიადანვე აგენერირებს ყველა მდგომარეობას და თითოეულ მათგანს უკან აბრუნებს მთავარ ნაკადთან. requestAnimationFrame-ის ქოლბექი ტაიმსტემპს უყურებს და მაგის შესაბამისად გავლილ მდგომარეობებს არენდერებს.

ამდენი მდგომარეობების გენერაცია, აქეთ იქით გზავნა და შენახვა დიდად არ მომწონს, რადგან აზრზე არ ვარ ობიექტების რაოდენობის ზრდასთან ერთად რა მოხდება, თუმცა ჯერ ჯერობით უკეთესი გზა არ ვიცი.