أقدم إليكم ترجمة تقرير آخر من HaxeUp Sessions 2019 Linz ، وأعتقد أنه مكمل جيد للتقرير السابق ، لأنه يواصل موضوع التغييرات في Haxe التي حدثت في عام 2019 ، وكذلك القليل من الحديث عن مستقبله.
القليل عن مؤلف التقرير: اوريل بيلي التقى Haxe ، والمشاركة في العديد من الاختناقات ، ويستمر في المشاركة فيها (على سبيل المثال ، هذه هي لعبته من لعبة Ludum Dare 45 الأخيرة ).

تقوم أوريل حاليًا بإكمال الدراسات في جامعة إمبريال كوليدج في لندن ، مما يعني وجود تدريب داخلي إلزامي. كانت فترة التدريب الأولى التي قام بها في مكتب بعيد ، حيث استغرق الطريق الكثير من الوقت. لذلك ، أعرب عن أمله في أن تكون الممارسة القادمة ممكنة من بعد.

لقد حدث أن مؤسسة Haxe لفترة طويلة لم تتمكن من العثور على موظف لشغل منصب مطور برامج التحويل البرمجي. قرر Aurel تجربة حظه وأرسل خطابًا يطلب فيه العمل عن بُعد. لقد كان محظوظًا - تم قبوله في تدريب لمدة ستة أشهر مع فرصة للعمل من لندن.

عند إعداد الجهاز ، تم الاتفاق على مجموعة المهام التي سيشارك فيها Aurel (على الرغم من أنه لم يتم تحقيق كل شيء في النهاية).

ماذا فعل؟
أولاً ، الوثائق ، التي كانت في حالة حزينة: تم توضيح جميع التغييرات في بناء الجملة والميزات الجديدة للغة والمترجم ، وأُكملت أقسام على السلاسل والحرفية والثوابت.

تمت ترجمة جميع الوثائق من LaTeX إلى تخفيض السعر !

ثانياً ، تم إحضار تنسيق رمز المكتبة القياسية إلى نمط واحد (نظرًا لأن الأشخاص المختلفين ذوي الأنماط المختلفة لتصميم الأكواد عملوا عليه لأكثر من 10 سنوات). وهكذا ، في مستودع المترجم Haxe ، احتل Aurel المركز السابع في عدد أسطر الكود المضافة :)

ثالثًا ، عملت Aurel أيضًا على المكتبة والمترجم القياسي:
على سبيل المثال ، تحتوي حاوية Map
على طريقة clear()
جديدة تزيل جميع القيم المخزنة. تم ذلك في المقام الأول لتوفير الراحة للعمل مع الحاويات التي تم إنشاؤها كمتغيرات final
(أي ، لا يمكن تعيين قيمة جديدة لها ، ولكن يمكن تعديلها):

بالنسبة للكائنات من النوع Date
، ظهرت طرق للعمل مع التواريخ بتنسيق UTC (التوقيت العالمي). أظهر العمل عليهم مدى صعوبة تطبيق واجهة برمجة تطبيقات واحدة تعمل بالتساوي على جميع اللغات / الأنظمة الأساسية الإحدى عشر التي تدعمها Haxe.

في المحول البرمجي القديم ، تم تعريف التعريفات وعلامات التعريف على OCaml ، لكن الآن تم وصفها بتنسيق JSON ، والذي يجب أن يسهل تحليلها بواسطة الأدوات المساعدة الخارجية (على سبيل المثال ، لإنشاء الوثائق تلقائيًا):

قد تلاحظ أيضًا أنه في المشروعات الكبيرة ، يبدأ خادم الترجمة في استخدام الكثير من الذاكرة.

لحل هذه المشكلة ، طور Simon Kraevsky و Aurel التنسيق الثنائي hxb ، والذي يستخدم لتسلسل AST المكتوب. الآن يمكن لخادم التحويل البرمجي تحميل الوحدة النمطية في الذاكرة ، والعمل معها حتى تكون هناك حاجة إليها ، ثم تفريغها من الذاكرة إلى ملف بتنسيق hxb وتحرير الذاكرة المشغولة.

تتوفر مواصفات تنسيق hxb في مستودع تخزين منفصل ، وتطبيقها الحالي في المترجم (مع المتسلسل / deserializer) يكمن في فرع Haxe منفصل . لم يتم الانتهاء من العمل على هذه الميزة ، وربما ستظهر في Haxe 4.1.

كان التركيز الرابع والرابع لعمل Aurel أثناء فترة التدريب هو إنشاء واجهة برمجة تطبيقات للنظام غير المتزامن الجديد - asys.

ترجع الحاجة إلى إنشائها إلى أن واجهة برمجة التطبيقات الحالية لا توفر طرقًا سهلة لأداء عمليات النظام بشكل غير متزامن. على سبيل المثال ، للعمل مع الملفات بشكل غير متزامن ، ستضطر إلى إنشاء سلسلة رسائل منفصلة يتم فيها تنفيذ العمليات المطلوبة والتحكم يدويًا في حالتها. بالإضافة إلى ذلك ، لا تحتوي واجهة برمجة التطبيقات الحالية على جميع وظائف العمل مع مآخذ توصيل UDP ، الموجودة في المكتبات القياسية بلغات أخرى ، ولا يوجد دعم لمآخذ IPC.

عند إنشاء واجهة برمجة تطبيقات جديدة وتطبيقها ، تثور أسئلة كثيرة:
كيفية تصميم API؟ ربما يجدر بك أخذ نموذج حالي كمثال؟ بعد كل شيء ، نحن لا نريد خلق كل شيء من الصفر ، لأن سيستغرق الأمر مزيدًا من الوقت وقد لا يكون حسب ذوق بقية الفريق ويتسبب في الكثير من النقاش.
وكما ذكرنا سابقًا ، فإن المشكلة الفعلية لـ Haxe هي تطبيق واجهة برمجة تطبيقات واحدة لجميع الأنظمة الأساسية المدعومة.

تم اختيار API Node.js. كعينة. إنه مدروس جيدًا ، ويدعم وظائف النظام الضرورية وهو مناسب تمامًا لإنشاء تطبيقات الخادم.

ولكن في الوقت نفسه ، تعد واجهة برمجة تطبيقات Node.js بمثابة واجهة برمجة تطبيقات Javascript بدون كتابة قوية. على سبيل المثال ، يمكن أن تأخذ الوظائف من وحدة fs
للعمل مع نظام الملفات مسارات إما سلاسل أو كائنات مثل Buffer
وحتى URL
. وهذا ليس جيدًا بالنسبة إلى Haxe.

Node.js ، بدوره ، يستخدم مكتبة libuv المكتوبة بلغة C. العمل مع API libuv من Haxe مباشرة لن يكون مناسبًا جدًا: على سبيل المثال ، لإعادة تسمية الملف بشكل غير متزامن ، ستحتاج إلى إنشاء كائنات مثل uv_loop_t
(بنية للإدارة) حلقة الحدث في libuv) و uv_fs_t
(بنية لوصف طلب لنظام الملفات):

نتيجة لذلك ، تم دمج Node.js و libuv APIs كما يلي (باستخدام مترجم الماكرو eval وطريقة rename
كمثال):
- لقد أخذوا طريقة API من Node.js ، وقاموا بتحويلها إلى Haxe ، في محاولة لتوحيد أنواع الوسائط والتخلص من الوسائط التي لا لزوم لها لـ Haxe. على سبيل المثال ، تعد وسائط المسار (من النوع
FilePath
) مجرد ملخصات عبر السلاسل:

- ثم أنشأ روابط OCaml لهذه الطريقة:

- OCaml و C المرتبطان (باستخدام CFFI - C Foreign Function Interface):

- وأخيراً كتب C-binders لاستدعاء وظائف libuv C من OCaml:

وبالمثل ، تم إجراؤه من أجل HashLink و Neko (في الوقت الحالي ، يتم تطبيق واجهة برمجة تطبيقات asys فقط لهذه المنصات الثلاثة). كما قد تخمين ، استغرق الأمر الكثير من العمل.
عرض Aurel بعض التطبيقات الصغيرة التي توضح كيفية عمل API asys.
المثال الأول هو عرض توضيحي لقراءة محتويات ملف بشكل غير متزامن. حتى الآن ، تستدعي الشفرة بشكل صريح أساليب تهيئة libuv ( hl.Uv.init()
) وبدء دورة التطبيق ( hl.Uv.run()
) ، نظرًا لحقيقة أن العمل على واجهة برمجة التطبيقات لم يكتمل (ولكن في المستقبل سيتم إضافتها تلقائيًا):

نتيجة الكود الظاهر:

نرى أن نتائج أساليب AsyncFileSystem.readFile()
تسمى تُعرض في وحدة التحكم بعد تتبع "بعد المكالمة" ، والذي يتم استدعاؤه في الكود بعد محاولة قراءة محتويات الملفات.
المثال الثاني هو عرض لعملية غير متزامنة مع عناوين DNS و IP.

في واجهة برمجة التطبيقات (API) الجديدة ، سيكون من الأسهل بكثير تحديد اسم المضيف ، وكذلك طرق المساعدة للعمل مع عناوين IP.

المثال الثالث هو خادم صدى TCP بسيط ، والذي يتطلب ثلاثة سطور فقط من الكود لإنشاء:

والمثال الرابع هو مثال على تبادل المعلومات بين العمليات:
makeFrame()
الأسلوب makeFrame()
الثابت في هذا المثال صور png منفصلة:

وفي الطريقة main
، نبدأ عملية ffmpeg ، حيث makeFrame()
الإطارات التي تم إنشاؤها في makeFrame()
:

والإخراج سيكون ملف فيديو:

والمثال الخامس هو UDP دفق الفيديو. هنا ، كما في المثال السابق ، بدأت عملية ffmpeg ، لكن هذه المرة تقوم بتشغيل الفيديو وإخراج بياناته إلى دفق الإخراج القياسي. يتم أيضًا إنشاء مأخذ توصيل UDP من شأنه أن يترجم البيانات من عملية ffmpeg.

وأخيراً ، نقوم بتقسيم البيانات الواردة من ffmpeg إلى "أجزاء" أصغر وترجمتها إلى المنفذ المحدد:

ونتيجة لذلك ، حصلنا على دفق فيديو فعال:

تلخيص ما سبق ، يتضمن API asys الجديد:
- طرق للعمل مع نظام الملفات ، بما في ذلك الوظائف الجديدة التي لم تكن موجودة في المكتبة القياسية (على سبيل المثال ، لتغيير الأذونات) ، وكذلك الإصدارات غير المتزامنة من جميع الوظائف المتاحة في المكتبة القياسية القديمة
- دعم التشغيل غير المتزامن مع مآخذ TCP / UDP / IPC
- طرق للعمل مع DNS (حتى الآن طريقتان:
lookup
reverse
) - وكذلك أساليب العمل غير المتزامن مع العمليات.

لم يكتمل العمل بعد في واجهة برمجة تطبيقات asys ؛ فهناك حاليًا بعض المشكلات في أداة تجميع مجمعي البيانات المهملة عند العمل مع مكتبة libuv. لم يتم تضمين طلب السحب مع التغييرات المطابقة في فرع Haxe الرئيسي ، والتعليقات عليه ترحب بآراء حول أسماء الطرق الجديدة وتوقيعاتها والمستندات.
كما ذكرنا سابقًا ، يتم تطبيق دعم asys API فقط من أجل HashLink و Eval و Neko (في شكل ثلاثة طلبات سحب منفصلة). لقد صاغ Aurel بالفعل خطة حول كيفية إضافة دعم لواجهة برمجة التطبيقات الجديدة لـ C ++ و Lua. سيتطلب تنفيذ المنصات الأخرى إجراء بحوث إضافية.

من الممكن أن تصبح واجهة برمجة تطبيقات asys متاحة في Haxe 4.1 (ولكن فقط في بعض الأنظمة الأساسية).
تحدث Aurel أيضًا عن مشروعه الجانبي - المكتبة العامة (التي ترتبط مع ذلك بعمله في مؤسسة Haxe).

هدف Ammer هو أتمتة إنشاء مجلدات لمكتبات C بحيث يمكن استخدامها في كل من HashLink و HXCPP (في أكتوبر 2018 ، عيّن Lars Duse رسومًا لحل هذه المشكلة).
لماذا كانت هذه المهمة ذات صلة؟ الحقيقة هي أنه على الرغم من أن عملية إنشاء المجلدات لـ HashLink و HXCPP متشابهة ، فلكل نظام أساسي سيكون عليك كتابة كود الغراء الخاص بك.
فعل Aurel نفس الشيء تقريبًا عندما قام بدمج مكتبة libuv في Haxe - بالنسبة لإيفال ونيكو و HashLink كان عليه أن يكتب نفس الكود الذي يختلف فقط في التفاصيل (مكالمات الوظائف والاختلافات في عمل FFI ، إلخ):

يلزم القيام بعمل مماثل على جانب Haxe حتى يمكن استدعاء الوظائف الأصلية منه:

وفكرة ammer هي أخذ إصدار Haxe من واجهة برمجة التطبيقات ، وليس تشويشًا بمعلومات زائدة عن الحاجة ، وجعل هذا الرمز يعمل بطريقة ما مع جميع الأنظمة الأساسية:

ما المطلوب الآن لاستخدام مكتبات C الخارجية:
- إنشاء مواصفات Haxe للمكتبة ، والتي تعد في الأساس خارجية للمكتبة المستخدمة
- اكتب كود التطبيق
- ترجمة المشروع عن طريق تحديد مسارات لرأس الملفات وملفات مكتبة C
- ...
- ربح

تحت الغطاء ، يقوم عامر بما يلي:
- يطابق أنواع حسب النظام الأساسي الهدف
- يولد تلقائيا رمز جيم لاستدعاء وظائف الأصلي
- ينشئ ملف تعريف يُستخدم لإنشاء ملفات hdll و ndll

يدعم عامر حاليا:
- وظائف بسيطة
- define'y من ملفات الرأس (في رمز Hax ، يمكن الوصول إليها باعتبارها الثوابت)
- مؤشرات
الدعم المخطط:
- عمليات الاسترجاعات (لا تزال ناقصة)
- والهياكل (ضرورية للغاية للعمل مع C-API)

الآن يعمل ammer مع C ++ و HashLink و Eval. وأوريل متأكد من أنه قادر على إضافة دعم لأنظمة النظام الأخرى.

لإثبات قدرات ammer ، أظهر Aurel تطبيقًا صغيرًا يقوم بتشغيل مترجم Lua:

المجلدات المستخدمة فيه هي كما يلي:

كما ترون ، تم تعليق بعض الطرق ، لأن يستخدمون عمليات الاسترجاعات ، التي لم يتحقق دعمها بعد ، ولكن يأمل أوريل أن يتمكن من إصلاح ذلك قريبًا.

لذلك ما عامر يمكن استخدامها ل:
- تضمين الجهاز الظاهري لوا
- إنشاء تطبيقات على SDL
- أتمتة العمل مع libuv أمر ممكن (كما هو موضح سابقًا ، الآن يتطلب الأمر الكثير من التعليمات البرمجية المكتوبة بخط اليد للعمل مع libuv)
- وبطبيعة الحال ، سوف يسهل ذلك إلى حد كبير استخدام العديد من مكتبات C الأخرى المفيدة (مثل OpenAL و Dear-imgui ، إلخ.)

على الرغم من انتهاء فترة تدريب Aurel في مؤسسة Haxe ، إلا أنه يخطط لمواصلة العمل مع Haxe لم يكتمل تعليمه الجامعي بعد ولا يزال يتعين عليه كتابة عمله النهائي. تعرف Aurel بالفعل ما الذي سيتم تخصيصه لـه - تحسين عمل أداة تجميع البيانات المهملة في HashLink. حسنا ، سيكون من المثير للاهتمام!