Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions text/0000-إكمال-دوال-UICore-في-المترجم.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
- **عنوان المقترح:** إكمال دوال UICore (corui) الستّ في مترجم LLVM بتكافؤ كامل مع المفسّر
- **النطاق:** لغة `text/` (نواة الواجهة `features/graphics` + جسر المترجم)
- **تاريخ البدء:** 2026-07-02
- **رقم الـ RFC:** (يُترك فارغاً حتى الدمج)
- **الحالة:** مقترَح (PR مفتوح)
- **Issue التتبُّع:** (يُترك فارغاً حتى القبول)

# ملخّص

إكمال الدوال الستّ المتبقّية من نواة الواجهة UICore في **مترجم LLVM** (`sad-build`) لتبلغ التكافؤ الكامل مع المفسّر (`sad-run`): `توليد_ويب`، `انتقل_بتحريك_كامل`، `تحديث_حالة`، `عين_الحالة`، `عنوان_النافذة`، `أغلق_النافذة`. بذلك يصير المترجم مكافئًا للمفسّر في **كامل كتالوج UICore**. المنطق كلّه في مكتبة الرسومات (`features/graphics`)؛ المحرّكان جسرٌ رفيع لا أكثر.

# الدافع (Motivation)

كان المفسّر يدعم الدوال الستّ بينما المترجم لا (فجوة تكافؤ S/L). الأخطر: عمليّات النافذة (عنوان/إغلاق) لم يكن لها نظيرٌ مكتبيّ مشترك — المفسّر يلمس نافذته مباشرةً، ولا سبيل للمترجم للوصول إلى نافذته المحلّيّة في `sad_app_run`. أيضًا `توليد_ويب` (تحويل شجرة العنصر إلى HTML) كان حكرًا على المفسّر رغم أنّ منطقه (`HtmlCodegen`) يعيش في المكتبة سلفًا.

# الشرح التوجيهي (Guide-level explanation)

الدوال الستّ تعمل الآن في المحرّكين بمخرَجٍ متطابق:

- `توليد_ويب(عنصر, عنوان؟)` ⇒ نصّ HTML كامل (يقبل عنصرًا أو دالّة بناء).
- `انتقل_بتحريك_كامل(صفحة, دخول, خروج, مدة؟)` ⇒ تنقّل + انتقال دخول بصريّ.
- `تحديث_حالة()` / `عين_الحالة(دالّة_تحديث؟)` ⇒ إعادة رسم (والأخيرة تستدعي دالّة التحديث أوّلًا).
- `عنوان_النافذة(نص)` / `أغلق_النافذة()` ⇒ التحكّم بالنافذة الحيّة.

# الشرح المرجعي (Reference-level explanation)

- **مصدر الحقيقة (`language-truth/`):** لا تغيير — الدوال الستّ مُعرَّفة سلفًا في `builtins` (تصنيف UICore)؛ لا توسيع SoT (يلتزم قاعدة «الأدوات لا توسّع SoT»؛ توسيع أخطاء المترجم قرارٌ لغويّ مأذون).
- **المكتبة (`features/graphics`):**
- **متحكّم نافذة جديد** `sad::ui::WindowController` (`core/include/sad_ui/window_control.h` + `core/src/window_control.cpp`): singleton مُسرَّب (never-destroyed) نظير `nav()`. نموذج **مؤجَّل**: العمليّة (عنوان/إغلاق) تُكتَب إليه، وحلقة `DesktopWindow::run()` المشتركة تستهلكها كلّ إطار (poll بعد `processEvents`) فتطبّقها على النافذة الفعليّة. لا يعتمد على أنواع المحرّكات ولا على SDL ⇒ سلوكٌ موحَّد بالبناء. تُصفَّر عند إنهاء كلّ تشغيل نافذة.
- `nav().markDirty()` لإعادة الرسم دون تغيير المكدّس.
- `توليد_ويب` يستهلك `sad::ui::web::HtmlCodegen` القائم (لا منطق جديد).
- **المفسّر:** `UIBridge::setWindowTitle/closeWindow` أُعيد توجيههما إلى `windowController()` بدل لمس `activeWindow_` مباشرةً ⇒ **مصدر حقيقة واحد** للمحرّكين (تغيّر السلوك من فوريّ إلى الإطار التالي، بلا انحدار وظيفيّ). تُصفَّر عند الخروج و Hot Restart.
- **المترجم:** جسورٌ C ABI (`sad_generate_web`، `sad_navigate_exit_transition(_builder)`، `sad_update_state`، `sad_set_window_title`، `sad_close_window`) في `runtime/sad_ui_runtime.cpp`، وتوصيل **9 مواقع** (opcode enum، خريطة الأسماء، الخفض، التصريح + المُمرِّر، الـemit، switch، حماية CSE) نظير شريحتَي الثيم والتنقّل. `عين_الحالة` يستدعي دالّة التحديث **تزامنيًّا** عبر ثانك الإغلاق القائم `void(i64 __env)` (يتجاوز كسر التقاط ردّ النداء لأنّ النداء تزامنيّ لا مُخزَّن). `توليد_ويب` يُرجع `String` (نصّ heap مملوك للمستدعي، نظير `sad_readline`). أسماء الرسائل مشتقّة من `Bn::UICore::*` والمتوقَّع من `sirTypeToString` — بلا نصوص حرفيّة.
- **التوافق الخلفي:** إضافيّ بالكامل؛ لا تغيير في السلوك القائم للمفسّر عدا تأجيل تطبيق عنوان/إغلاق النافذة إطارًا واحدًا (غير محسوس).

# السلبيات (Drawbacks)

- تباعدات S/L ضيّقة موثَّقة على مدخلاتٍ خاطئة/سوء استخدام (المفسّر يُجهِض، المترجم يُشخّص-ويكمل — النمط القائم للـfrontend): `توليد_ويب` على جذرٍ فارغ يُرجع نصًّا فارغًا؛ `عين_الحالة` لا يستدعي **كائنًا قابلًا للاستدعاء** (Function فقط، لأنّ ثانك الإغلاق يفترض تخطيط إغلاق).
- انتقال الخروج (`exitType`) في `انتقل_بتحريك_كامل` تحسينٌ بصريّ حيّ غير مُستهلَك بعدُ في حلقة نافذة المترجم (نظير `انتقل_بتحريك`)؛ أثر المكدّس (العمق/الصفحة الحاليّة) مطابقٌ بالبناء.

# المبرّرات والبدائل (Rationale and alternatives)

- **متحكّم نافذة مكتبيّ موحَّد** بدل جسرٍ لكلّ محرّك: يجعل المكتبة مصدر الحقيقة الوحيد ويمنع تباعد المحرّكين بالبناء (نظير `nav()`/الثيم). البديل (جسر مباشر لكلّ محرّك) يكرّر المنطق ويُخاطِر بالتباعد.
- **النموذج المؤجَّل (poll)** بدل نداءٍ فوريّ: يتفادى مشكلات ملكيّة/عمر مؤشّر النافذة عبر المحرّكين، ويوحّد المسار (نظير `nav.dirty`).

# أعمال سابقة (Prior art)

Flutter (`runApp`/`setState`/`Navigator` منطقها في الإطار المشترك، الغلاف رفيع)، والويب (`toString`/render إلى DOM). النموذج الموحَّد: منطق الحالة/النافذة/التوليد في طبقةٍ واحدة يجسر إليها الواجهات.

# أسئلة غير محسومة (Unresolved questions)

- دعم **الكائن القابل للاستدعاء** في `عين_الحالة` (يحتاج مسار `buildCallableObjectInvoke` بدل ثانك الإغلاق) — شريحة لاحقة.
- استهلاك انتقال الخروج على الصفحة القديمة في حلقة نافذة المترجم — تحسينٌ بصريّ لاحق.
- توحيد رسائل خطأ المدخل الباطل (إجهاض مقابل تشخيص-وإكمال) بين المحرّكين — قرارٌ عامّ خارج نطاق هذا المقترح.
Loading