فــُـصّـِــلـــَــــت

مُحاكات مُحِثّ الويندوز -ج2-

المستوى: متقدم

هذا الجزء الثاني من مشروع محاكات مُحِث الويندوز، إذا لم تقرأ الجزء الأوّل فعليك بذلك قبل المباشرة في هذا الجزء، ذلك لأن الجزء الأوّل يتضمّن تقديمات وتوضيحات حول المشروع والمصطلحات المستخدمة وطريقة العمل التي سنسير عليها.

محاكات محث الويندوز -ج1-

تذكير


قمنا بتقسيم المشروع إلى أربع دورات، أنجزنا اثنتان في الجزء الأوّل من التدوين، وفي هذا الجزء سنحاول إتمام المشروع بإنجاز الدورتان الباقيتان. نبدأ إذًا من حيث انتهينا.. الدورة الثالثة.

الدورة الثالثة


هدفنا في هذه الدورة جعل ملف الخرج مؤقتا، وذلك لاستخدامه كصَوْنٍ للخرج، إذ تضع فيه البرامج مخرجاتها ليقرأها المحث، ثم نتخلّص منه بعد ذلك، ونعرض محتواه على شاشة المحث.

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

في الوصول المتزامن، عندما نستدعي دالة الكتابة في ملف، فإنّ دالة الكتابة لا تعود إلا بعد الإنتهاء من الكتابة، بمعنى أنّ سيل التنفيذ يتوقّف في انتظار أن تتم عملية الكتابة أو أن تحبط أو تفشل، والأمر سيان بالنسبة لدالة القراءة، إذ يتوقف التنفيذ انتظارًا لتمام عملية القراءة أو أن تحبط أو تفشل. لذلك فإنّه لا يمكن القراءة والكتابة في ملفّ معيّن في نفس الوقت وهذا ما نحتاجه في مشروعنا، قراءة ما تمت كتابته في الحين، فكيف السبيل إلى ذلك؟

ما سنفعله هو أنّنا سنقرأ من الملفّ قيد الكتابة بشكل متواصل طالما لا يزال الإجراء في طور التنفيذ، لكن المشكل هنا هو أنّ القراءة ما دامت متزامنة، فإنّها لن تترك المجال للكتابة، ذلك لأنّ عملية القراءة متواصلة وما إن نفرغ من عملية قراءة حتى ندخل في أخرى، لدى فإنه لتجاوز هذا المشكل فنحن لن نقوم بالقراءة من الملف إلّا بعد أن نتأكد بأنّه تمت كتابة شيء فيه، أنظر الكود:

أمر_آخر(نص اسم، نص معطيات)
    نص اسم_كامل = رد_اسم_كامل(اسم)
    لو ليس نظام_ملفات.هو_موجود(اسم_كامل)
        ملف_خرج.زد_نص("ما أدخلته ليس أمرًا صالحًا للتنفيذ")
    أما لو نظام_ملفات.هو_مجلد(اسم_كامل)
        ملف_خرج.زد_نص("قد أدخلت عنوان مجلد، لا يمكن تنفيذه")
    وإلا
        إج_حالي = إجراء جديد(اسم_كامل، {عدد}عدم، ملف_خرج.رد_مقبض()، ملف_خرج.رد_مقبض())
        إج_حالي.نفذ(معطيات)
        طالما إج_حالي.هو_حي()
            لو ملف_خرج.رد_حجم() > 0
                عرض_ملف()
            تم
        تم
    تم
تم
قبل تنفيذ الأمر فنحن نقوم ببعض الفحوصات للتأكد من أنّ العنوان المطلوب تنفيذه هو عنوان موجود، وبأنّه فعلا ملف لا مجلد، نقوم بعد ذلك بإنشاء الإجراء وإعطائه مقابض الدخل والخرج الأساسية، ثم تنفيذه، وطالما هو قيد التنفيذ، فنحن نقيس حجمه، فإذا صار أكبر من صفر، فحينها نعلم أنه قد تمت كتابة شيء في الملف، نقوم عندئذ بالقراءة لكن على الشكل التالي:

عرض_ملف()
    ملف_خرج.زحف(ملف.من_أوله، 0)
    نص ن = ملف_خرج.إقرأ_الكل()
    ملف_خرج.بتر(0)
    جدول<نص> جص = ن.شق(حرف.رس)
    لأجل عدد ع=0، ع<جص.طول، ع++
        لو ع = 0
            سطور.خذ(سطور.طول-1، سطر_حالي() + جص.صف(ع))
        وإلا
            سطر_جديد(جص.صف(ع))
        تم
        ن_محث.حدّث()
    تم
تم
بدأنا بالزحف إلى بداية الملف، ذلك لأنه بعد الكتابة فإن مؤشر الملف يكون عند نهايته، فإذا قرأنا من النهاية فنحن لن نجد ما نقرأه وستعود دالة القراءة دون نتيجة، نقرأ بعد ذلك كلّ محتوى الملف، ثم نقوم بتصفير حجمه، أي أننا نقوم بمحو محتواه وإرجاع حجمه إلى صفر، وهذا أمر مهم لأنه إن لم نفعل فنحن دائما سنجد حجم الملف أكبر من صفر وسنكرر قراءة ما تمّت قراءته سابقا. نقسّم بعد ذلك النصّ الذي قرأناه حسب السطور ليسهل تخزينه في صون الخرج وعرضه على الشاشة.

بهذا نكون قد انتهينا من الدورة الثالثة، أعلم أنّ الشرح كان سريعا ومقتضبا لكن هذا ضروري لكي لا أجعل الموضوع طويلا ومملا، إذا كانت لديكم أسئلة فالأجوبة تجدونها إمّا في المصدر الكامل للمشروع وهو في المرفقات أسفله، أو عبر طرحها في التعليقات.

نُكمِلُ قريبًا مع الدورة الرابعة.


ليست هناك تعليقات:

إرسال تعليق