Godot: يمكن أن تنتج بعض استخدامات "class_name" أخطاء دورية بشكل غير متوقع

تم إنشاؤها على ٢٦ أغسطس ٢٠١٨  ·  69تعليقات  ·  مصدر: godotengine/godot

Windows 10 64 بت - Godot 3.1 alpha

تحرير - مشكلة مصقولة للتركيز على الأخطاء الدورية.

يمكن أن ينتج عن استخدامات معينة لـ class_name أخطاء دورية في المواقف التي لا توجد فيها مراجع دورية ، وفي الواقع في بعض الأحيان لا توجد مراجع أخرى خارج المرجع المعطى.

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

لقد استعصت علي إعادة إنشائه في مشروع نموذجي.

godot master_2018-08-27_00-47-02

bug 3.2 confirmed high priority gdscript

التعليق الأكثر فائدة

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

ال 69 كومينتر

ستعمل إذا أعطيت البرنامج النصي الأساسي class_name واستخدمته في سطر الامتداد.
أتلقى أيضًا الخطأ عند استخدام أسماء الملفات في البداية (https://github.com/godotengine/godot/blob/master/modules/gdscript/gdscript_parser.cpp#L4947) ، ولكنه يختفي أيضًا ولا يأتي مرة أخرى بعد أن عملت مرة واحدة (كما في ، بعد استخدام الحل المذكور)

@ PetePete1984 رائع ، شكرًا بيت. هذه هي الطريقة التي يعتزم استخدامها بعد ذلك؟

أثناء التحقق من ذلك واختباره ، كنت أبحث في طريقة get_class() ، وأتساءل عما إذا كان يجب إرجاع Node2D؟ الجزء is CustomClass يعود _true_ ، لكن is_class("CustomClass") من ناحية أخرى هو _false_.

CCreduzvnenwillnationsdev

لن أقول إنه سلوك مقصود ، لا سيما مع وجود رسالة خطأ تشير إلى شوائب دورية حيث لا يوجد أي منها.
get_class() و is_class() محيران بالنسبة لي بشكل عام ، لا يمكنني التعليق على ذلك حقًا. قد يحل المصدر هذا اللغز على المدى الطويل ، ولكن حتى الآن is كان كافياً بالنسبة لي.

vnen هل هذا شيء يحتاج إلى رسالة خطأ أوضح؟

@ PetePete1984 نعم ، لقد كان is شيئًا رائعًا الآن في 3.1. على الرغم من أنني واجهت موقفًا كنت أرغب فيه في استخدام match مثل match custom_thing.get_class() والمقارنة مع عدة سلاسل. لكن لا شيء مهم ، مجرد سهولة القراءة وأقل شيء في الكتابة.

avencherus قد تتمكن من الابتعاد عن:

match custom_thing.get_script():
    <typename>: stuff # script classes
    <typename>: stuff
    _: match custom_thing.get_class():
        "Node": stuff # engine classes

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

willnationsdev لست متأكدًا تمامًا من get_script() ، بالنسبة لي على الأقل ، فإنه يُرجع كائن GDScript [GDScript:1057] .

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

avencherus فإن "أسماء الفئات" لفئات البرنامج النصي هي متغيرات عامة تشير إلى البرنامج النصي. وبالتالي...

class_name CustomType
match get_script():
    CustomType:
        print("I am a CustomType!") # should print

willnationsdev أوه أنيق ، أرى الآن. لم أكن أتوقع أن يعمل class_name بهذه الطريقة ، أو أن يكون النوع المخصص متاحًا لنمط المطابقة. شكرا لتقاسم هذه النصيحة ويل.

vnen نعم ، بعض التجاعيد الإضافية للقصة. اسمحوا لي أن أرى كيف يمكنني التعبير عنها بشكل جيد.

أولاً ، يعمل حل Pete ، عندما يتم إعطاء فئة أساسية class_name يبدو كل شيء جيدًا. ما لاحظته هو أن العودة إلى الفئة الأساسية وسحب class_name CustomBase التي أضفتها ، فإن النصف يعمل. لم يعد يظهر في قائمة العقد عند إضافة العقد ، ولكن is سيعمل ، ولا توجد أخطاء غريبة.

ثم لتأكيد ذلك ، ذهبت لإعادة إنشاء خطوات إنشاء base2.gd -> custom2.gd برنامج نصي ممتد. ثم داخل custom.gd استخدم class_name CustomClass2 ، لكن لا يوجد تسمية للفئة في الفئة الأساسية.

ظهرت مشكلة أخرى. احتوت قائمة العقد على القائمة الأولى ، ولكنها مدرجة برمز يشير إلى "خطأ"

godot master_2018-08-27_20-01-26

لذلك قمت بتعديل الفئة الأساسية الأولى بحيث استخدم كلاهما class_name . لكن حصلت على نتائج غريبة مرة أخرى.

لا يظهر كل شيء في قائمة العقد ، ثم الكلمة الرئيسية is عادت فقط إلى true لإحدى العقد. على الرغم من أنه في لقطة الشاشة هذه ، يمكنك رؤية قائمة العقدة تتعرف على CustomClass2 ، ولكن في الكود الموجود خلفها ، يُرجع is CustomClass2 خطأ.

godot master_2018-08-27_20-05-11

يبدو أن الكثير من الأشياء يتم تبديلها أو باقية وراء الكواليس. من الصعب التنبؤ بما قد تفعله بمعرفي المحدودة.

امل ان يساعد. X)

تحرير تجاهل هذا التعليق. لم أدرك أن class_name لم يتم تنفيذه في 3.0.6 ، هذه المشكلة تشير إلى 3.1 بناء على أي حال.

يبدو أن class_name قد كسر في 3.0.6. سأصدر قضية منفصلة ، ولكن:

image

لا تعد فئات البرنامج النصي bfishman ميزة في الإصدار 3.0.x. هذا هو السبب في أنها لا تعمل.

لقد حاولت للتو ما يلي وعملت كل نسخة. ظهرت جميع فئات البرامج النصية في CreateDialog ، وتم تجميع البرامج النصية بشكل جيد ، وتم تشغيل المشهد بنجاح ، وما إلى ذلك.

مع تسلسل هرمي للمشهد مثل هذا:

  • العقدة (base.gd)

    • عقدة (مشتقة. gd)

النصي:

# res://base.gd
extends Node
class_name BaseNode
func _ready():
    print("base")

# res://derived.gd
extends BaseNode
extends "base.gd" # I tried both of these 'extends' lines and they each worked
class_name DerivedNode # I tried with and without this line
func _ready():
    print("derived")

في كل مرة أجري فيها الاختبار ، كان يطبع

base
derived
base

...كما ينبغى.

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

willnationsdev شكرا للنظر في ، سأحاول ذلك. هل هذه الملفات من مجلد AppData / Roaming؟ سأمضي قدمًا وأزيل كل شيء الآن. إذا كان الأمر كذلك ، هل تتساءل عما إذا كان هناك شيء أكثر تحديدًا يجب حذفه؟

avencherus لست متأكدًا تمامًا. أتذكر فقط @ karroffel الذي ذكر شيئًا عنه عندما أضفت بعض الإصلاحات إلى عناصر رمز فئة البرنامج النصي مسبقًا.

تم الاختبار على https://github.com/godotengine/godot/commit/1093c0ff51b980634dffdd9618eaa53061da6419
لا أرى أي خطأ ولكنه لا يظهر العقدة في مربع حوار "إنشاء عقدة جديدة".

أتلقى أيضًا الخطأ الموضح في المنشور الأصلي (Windows x64 Godot 3.1 alpha):

image

ومع ذلك ، فإنه يحدث في سياق مختلف. لدي 3 نصوص برمجية لكل منها class_name ، وكل منها يمتد إلى Node2D. لا يحدث الخطأ إلا إذا أشار إليه أحد البرامج النصية باستخدام عامل التشغيل is . على سبيل المثال if some_var is Incomer . الشيء الغريب هو أنه إذا كان نفس البرنامج النصي يشير إلى class_name الآخر ، فلا توجد مشكلة. وإذا كان النص الآخر يشير إلى class_name المعنية ، فلا مشكلة أيضًا.

إذن هناك ClassA و ClassB و ClassC. إذا كانت ClassC تشير إلى ClassA مع عامل التشغيل is ، فسيحدث خطأ في وقت التحميل. إذا كانت ClassC تشير إلى ClassB ، فلا يوجد خطأ. إذا كان ClassB يشير إلى ClassA ، فلا يوجد خطأ.

لا توجد أي من النصوص في نفس المشهد ، وجميع العقد هي أشقاء (لا توجد علاقة مع سلف).

AlexHolly نفس الوضع معي الآن أيضًا. يبدو أن الخطأ قد انتهى ، ولكن نعم ، لن تظهر الفئات في نافذة إضافة عقدة عند عدم وجود نص برمجي أساسي يستخدم أيضًا class_name .

هذا في alpha 3.1 c320d93

مثال صغير باستخدام "هو". يمكن أن يحدث نفس الشيء إذا استخدمت "كـ".
هذا ما ذكره Oranjoose أيضًا.
دورة. zip

لا توجد أي من النصوص في نفس المشهد ، وجميع العقد هي أشقاء (لا توجد علاقة مع سلف).

هذا لا علاقة له بالعقد في المشهد. الدورات تحدث في البرنامج النصي نفسه.

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

لم أتمكن من إعادة إنتاج الخطأ في 451e5fd أيضًا. لم تظهر العقدة في نافذة الإنشاء حتى.

أستطيع أن أؤكد أن هذا الإصدار غير موجود في 0dbe014 (أحدث نسخة رئيسية قمت بسحبها). ربما يمكننا إغلاق هذه المشكلة.

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

willnationsdev شكرا لك. X) لقد أصطدمت بمشكلات مختلفة مع class_name ، لكن لم أتمكن من إعادة إنشاء هذه المشكلة. لقد كان من الصعب للغاية إعادة إنشائها ، لكنني توقفت عن استخدامها منذ ذلك الحين.

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

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

تضمين التغريدة حسنًا ، آمل أن تتمكن في النهاية من تحديد الظروف التي يحدث فيها ذلك. بدون السياق ، لا يمكننا إصلاحه. وجه ضاحك

لقد لاحظت بعض الأخطاء المرجعية الدورية التي حدثت في عملي في godot-next حيث تمكنت من استخدام الكتابة الثابتة لأقول أنني كنت أعيد نفس النوع مثل اسم فئة البرنامج النصي ، ولكن إذا حاولت بالفعل الإشارة إلى اسم الفصل من البرنامج النصي (لإنشاء مثيل لإعادته لاحقًا في الوظيفة) ، فلن يعمل لأن البرنامج النصي سيشير إلى نفسه وبالتالي يحتاج إلى تحميل نفسه بشكل متكرر إلى ما لا نهاية.

كان الحل الذي وجدته هو استخدام load(get_script().resource_path).new() . أعلم أن هذا شيء ممتع للغاية ، لكنه سمح للمحلل بإنشاء البيانات بأمان والمضي في عملية التجميع بأمان ، والسماح بتسجيل اسم النوع رسميًا ، ثم الرجوع إلى النوع في RUNTIME فقط بمجرد تهيئته بالكامل.

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

ملخص سريع لبعض المشكلات (سأقوم بنشرها في وقت ما في الأسابيع القادمة):

  1. سأحصل على هذه الأخطاء الدورية عند إجراء obj is MyClass ولم يكن هناك اتصال أو مرجع آخر بينهما. على الرغم من أنني لا أعرف ما إذا كانت تقوم بمسح شجرة المشهد وتحسب أطفالها كمراجع دورية.
  2. لقد واجهت أيضًا الإزعاج الذي وصفته. أتمنى ألا يكون الأمر كذلك ، لأنه يعمل بشكل جيد مع أسماء الفئات المضمنة / الأصلية في نفس أنواع المواقف. لذلك يمكنك كتابة مجموعة كاملة من التعليمات البرمجية مع وضع هذا الهدف في الاعتبار ، معتقدًا أن كل شيء على ما يرام ، حتى تبدأ في إضافة أنواعك المخصصة ، وعليك اللجوء إلى طريقة الاختراق / الالتفاف / الأقدم ، ثم قيمة ذلك إن لم يكن لتجنب أسماء المسارات المطولة؟
  3. لقد حصلت على هذه الأشياء خالية من الأخطاء في المحرر وأقوم بتنفيذها بشكل نظيف أثناء التشغيل التجريبي ، ولكن بعد ذلك استمر في حدوث أخطاء وإخفاقات في اللعبة التي تم تصديرها. مثال أدناه (على الرغم من أنه لا علاقة له بهذه المشكلة على الأرجح) هو استخدام class_name لم يتمكن من العثور على أيقوناته في الإصدار ، ولكن لا توجد مشكلات في التشغيل والاختبارات من المحرر.

gtc_2018-10-12_13-21-35

بشكل عام ، كانت تجربتي مع class_name مواجهة يومية تقريبًا مع الكثير من الأخطاء التي لا يمكن التنبؤ بها ويصعب تفسيرها ويصعب إعادة إنتاجها. يضيع الكثير من الوقت في الرقص حوله ومحاولة حلها.

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

ربما في 4.0. X)

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

كما قلت من قبل ، من السهل جدًا إنشاء دورات بـ class_name ، خاصة عند استخدام is و as . إنها أقل سهولة مع المسارات ، لكن قد تصطدم بمشاكل مماثلة أيضًا. تكمن المشكلة في أن GDScript لم يتم ربطه مطلقًا بالعمل بهذا الشكل ، لذا فهو يعتمد كثيرًا على تحميل الموارد. لدي بعض الأفكار لإصلاح هذا (على وجه الخصوص تجاهل تحميل الموارد والقيام بتحليل ضحل للتبعيات مباشرة) ، لكن هذا يتطلب تغيير هيكلي للمحلل.

من المحتمل أن يتم حلها بشكل صحيح في الإصدارات التالية ، لأنه ليس الوقت المناسب للتلاعب بهذا. class_name "ميزة أقل" في الوقت الحالي. لا يزال بإمكانك استخدامه في بعض الحالات ، ولكن ليس على نطاق واسع كما تتوقع.

تضمين التغريدة مرحبا بعودتك. X)

شكرا على الرد والجدول الزمني.

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

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

أحد الأشياء الرئيسية التي سأفتقدها هو القدرة على الاعتماد على التلميحات عند دمج فئة مخصصة مع تلميحات الكتابة الجديدة. var thing : NewThing

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

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

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

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

لقد رأيت ذلك يحدث أحيانًا حيث تحدث الأخطاء في السطر الموجود أعلى أو أسفل السبب.

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

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

تحرير: لا يهم ، بطريقة ما قمت للتو بحل التضمين الدوري ببساطة من خلال عدم القيام بذلك ...
يتم الكتابة فوق الفصول العامة في project.godot على أي حال عند تشغيل المحرر.

vnen أو avencherus سيكون من الجيد تحديث OP مع وصف واضح لما يدور حوله هذا الخطأ في النهاية ، لأنه خلاف ذلك مناقشة مطولة للقراءة قبل الحصول على فكرة جيدة عنها.

@ akien-mga لست متأكدًا من حالتها بعد الآن ، أو ما الذي أكتب عنه على وجه التحديد.

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

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

في لمحة في هذه القضايا الأخرى ، يبدو كما لو أن الحديث يتعلق بالتغييرات المطلوبة في GDScript. مع التنقيحات تهدف إلى 3.2. إذا كانت هذه هي الخطة ، فلن تكون تحت المرحلة 3.1 بعد الآن.

ربما يكون من الجيد إغلاق هذا ، ما لم يكن vnen يستخدمه لمسك الدفاتر ، أو إذا كنت تفضل استخدامه للإشارة إلى المشكلات المكررة القادمة عند استقرار 3.1.0.

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

حسنًا ، لا ينبغي إغلاق هذا ، لا ، فالكم الهائل من التقارير المكررة يُظهر بالتأكيد أن هناك شيئًا ما يجب إصلاحه :)

واجهت رسالة الخطأ التالية التي تمثل مشكلة بالنسبة لي لتحديث مشروع من 3.0 إلى 3.1. عمل الكود التالي سابقًا:

extends Node2D
export(String, FILE, "*.gd") var _class_name = "res://Test.gd"
onready var SomeClass = load(_class_name)

func foo():
    for c in get_children() :
        if c is SomeClass : 
            do_stuff()

عندما أقوم بتغيير الرمز إلى:

extends Node2D
class_name SomeClass

func foo():
    for c in get_children() :
        if c is SomeClass : 
            pass

أحصل على الخطأ التالية:

خطأ في التحليل: غير مسموح باستخدام اسم واحد في ملف فئة (إنشاء مرجع دوري)

هذا أمر محبط بالنسبة لي لأن عقد الأطفال التي أبحث عنها كلها ترث من هذه الفئة ويتم خلطها مع عقد أطفال أخرى لا تفعل ذلك. هي القدرة على كتابة التحقق من مثيلات أخرى من فئة البرنامج النصي المقصود منها عدم العمل بهذه الطريقة وهل هناك طريقة أخرى للقيام بذلك.

Diaspater أعتقد أن كل ما عليك فعله هو تغيير if c is SomeClass إلى if c is get_script() . ينفذ كلا الخيارين فحص وقت التشغيل ، لكن الإصدار SomeClass يتطلب منك تحميل البرنامج النصي مرة أخرى في وقت المحرر (مما ينتج عنه مرجع دوري) بينما لا تحاول طريقة get_script() القيام بأي شيء في وقت التحرير.

willnationsdev أفهم أن هذا حل صالح (أو حل بديل لمشكلتي كما أدركت بعد كتابة تعليقي الأصلي أن الطريقة الأولى لا تزال تعمل. ومع ذلك ، فإنني أفضل إذا كان من الممكن دعم الطريقة الثانية بشكل صحيح. لقد اكتشفت أيضًا أن هذا يعمل:

DummySomeClass.gd
extends Node2D
class_name DummySomeClass

func foo():
    pass


SomeClass.gd
extends DummySomeClass
class_name SomeClass

func foo():
    for c in get_children() : 
        if c is DummySomeClass: 
            pass

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

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

قد يكون هذا سؤالًا ساذجًا ولكن لا ينبغي أن نتخلص من هذا التقييد غير الدوري.
أعني لغات أخرى مثل Java و C # و C ++ وما إلى ذلك ... يمكنها التعامل مع الأنواع دون مشاكل ...

harraps سيتم القيام به (كما قلت عدة مرات في الموضوع) ، لكنه يتطلب بعض التغييرات الأساسية في كيفية توصيل GDScript. لن أتطرق إلى هذا الآن لأننا على وشك الإصدار ومن المحتمل أن يؤدي هذا التغيير إلى كسر التوافق.

في حالة مواجهة أي شخص آخر لهذا الخطأ ، فقد وجدت مثيلًا آخر لخطأ متعلق بـ "مرجع دوري" ، ولكنه يختلف عن الأخطاء الأخرى المدرجة هنا.

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

extends Reference
class_name MyClass

static func make() -> MyClass:
    # can't even use get_script() for static funcs, but that's a separate issue
    var c = load("res://my_class.gd").new()
    return c

ثم تحصل على هذا الخطأ:

ERROR: SelfList<class GDScriptFunction>::List::~List: Condition ' _first != 0 ' is true.
   At: .......\godot\core/self_list.h:111
ERROR: SelfList<class GDScript>::List::~List: Condition ' _first != 0 ' is true.
   At: .......\godot\core/self_list.h:111
WARNING: ObjectDB::cleanup: ObjectDB Instances still exist!
     At: core\object.cpp:2093
Leaked instance: GDScript:17060 - Resource name:  Path: res://my_class.gd
Leaked instance: GDScriptNativeClass:1058
ERROR: ResourceCache::clear: Resources Still in use at Exit!
   At: core\resource.cpp:425

إعادة النشر من # 944 ،

أواجه أيضًا تبعيات GDscript دورية بانتظام. في ما يلي بعض حالات الاستخدام حيث أجبر حاليًا على العودة إلى GDscript غير المصنف:

  1. تستخدم الأحرف الخاصة بي ActorController التي تعمل بمختلف Move s (مثل الحالات في آلة الحالة). يقوم ActorController بإعادة توجيه _physics_process() ومثل ذلك إلى Move . بالعكس ، يصل النقل إلى ActorController للتبديل إلى Move أو الوصول إلى خصائص (مثل ارتفاع القفزة وسرعة الجري وما إلى ذلك)

  2. نفس الموقف مع MoveRepository - مخازن المستودع قابلة لإعادة الاستخدام Move s ، ومع ذلك فإن Move s يحتاج أيضًا إلى الوصول إلى المستودع إذا كان يريد جلب Move لتحديده في ActorController

actor-framework

هذه ليست مشكلة في C # أو C ++ ، لكن GDscript (مع الكتابة الثابتة الاختيارية) تتطلب مني الرجوع إلى المتغيرات (الكتابة الديناميكية) أو إنشاء المراوغات غير الضرورية باستخدام الأحداث وما شابه.

أواجه هذه المشكلة أيضًا. لدي إعداد مماثل ولكنه أبسط.
الفئة TurnManager لها متغير من النوع Actor وكل Actor له مرجع مكتوب إلى TurnManager
أنا لا أستخدم حتى is لقد أعلنت حرفياً عن المتغيرات وهو ما يكفي لإثارة هذا الخطأ.
استخدام الإصدار المستقر الجديد 3.1 على Linux 64 بت.

image

فقط ركض في هذا. يبدو ذات صلة.

image

غريب جدا حقا.

image

أنا أيضًا يبدو أنني أواجه هذا. كنت أتساءل عما إذا كان ذلك بسبب انفصال النصوص في الغالب عن الأشياء؟ لدي فئة سمة أساسية ، والتي تمد العقدة ، و PrimaryAttribute و SecondaryAttribute لتوسيعها ، ثم مثل 12 عقد PrimaryAttribute وعقدة SecondaryAttribute. لا يبدو أن المحرر يعجبه رغم ذلك؟ على الرغم من أن اللعبة تسير بشكل جيد عندما ألعبها.

من الجدير بالملاحظة ، أنني قمت بتبديل مسارات الموارد الخاصة بـ class_names ، وقد أدى ذلك إلى عمل الأشياء بشكل جيد لمدة 5 دقائق تقريبًا قبل أن يعودوا لإعطائي أخطاء بدون سبب. : /

همم. يبدو أن الأخطاء تتعلق بترتيب تحميل الأشياء في نافذة المحرر؟ يمكنني حملهم على الذهاب بعيدًا عن طريق إغلاق الملفات وإعادة فتحها بالترتيب الذي يرثون به. لذلك ، ربما يكون هناك نوع من المتاعب حوله لا يعلن أشياء في بعض الملفات. : /

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

@ Angular-Angel لقد لاحظت أن إعادة تشغيل Godot تحل الأخطاء. إنه لأمر مخيب للآمال أنه لا يمكنني استخدام الكتابة الثابتة في Godot مع فئات / أنواع مخصصة ولكن دون ظهور أخطاء غريبة.

لقد كان إغلاق / إعادة فتح المشروع كافيًا بالنسبة لي. Shift + Ctrl + Q (انتقل إلى قائمة المشروع) ، وأكد المطالبة ، ثم انقر نقرًا مزدوجًا فوق المشروع مرة أخرى. لا يزال محبطًا بعض الشيء ، لكنك تعتاد عليه (حتى يتم إصلاحه).

آسف ، لكنني محبط قليلاً أيضًا ، ولم أكن أعرف عن هذا الحل منذ أن علقتم يا رفاق ، لقد توقفت عن كتابة الكود الخاص بي لفترة من الوقت ، لكنني ما زلت أفتقده كثيرًا.

متفق عليه. أصبحت هذه عادة أساسية جدًا بالنسبة لي وللآخرين. من المحتمل أن نرى ما إذا كان حل إعادة التشغيل كافيًا في الوقت الحالي. (سيكون بدء Godot سريعًا رائعًا) في 16 مايو 2019 الساعة 8:27 صباحًا ، كتب Ricardo Alcantara [email protected] : آسف ، لكنني محبط قليلاً أيضًا ، ولم أكن أعرف عن هذا الحل منذ أن علقتكم يا رفاق ، توقفت عن كتابة الكود الخاص بي أثناء التنقل ، لكني ما زلت أفتقده كثيرًا.

- أنت تتلقى هذا لأنك علّقت. قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على GitHub ، أو كتم صوت سلسلة المحادثات.

Godot 3.1.1 (ليس أحادي اللون)
Stack.zip

الحد الأدنى من المثال استنساخه

https://cdn.discordapp.com/attachments/477544613511692358/584811385838632977/unknown.png

_please_ شخص ما يصلح هذا.

image

التحميل يعمل بشكل جيد ، التحميل المسبق لا يعمل

لاحظ أنه يوجد في الواقع خطأ غير معلوم في البرنامج النصي في StackList.gd. على وجه التحديد ، خطأ نحوي في إعلان مفتاح القاموس. ومع ذلك يتم اكتشافه فقط بمجرد تغيير القاموس إلى ثابت.

أردت فقط تدوين ملاحظة بأنني أصابت خطأ class_name اليوم أيضًا.

لقد عدت إلى استخدام object.has_method ("الاسم") بدلاً من اختبار ما إذا كان الكائن هو className

لقد كنت أضرب هذا كثيرًا في 3.1.1 ، وأقفز عبر الأطواق لتجنبه.
على أمل أن يتم إصلاحه في 3.2!

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

أحاول حاليًا إصلاح هذا في JavaryGames ، الحل جاري بالفعل. لست متأكدًا مما إذا كان سيتم تحويله إلى 3.2 نظرًا لأنه تغيير كبير (كان عليه إعادة الأسلاك إلى حد ما حول كيفية عمل GDScript داخليًا) ونحن على وشك الإصدار ، ولكن ربما يمكننا الاندماج في 3.2.1 أو شيء من هذا القبيل. بالتأكيد سيتم إصلاحه في 4.0.

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

vnen هل هناك فرع مع إصلاح لهذا الخطأ ، والذي يمكننا

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

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

vnen هل هناك فرع مع إصلاح لهذا الخطأ ، والذي يمكننا

نعم ، لدي في مفترقتي العامة: https://github.com/vnen/godot/commits/gdscript-no-ycles

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

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

https://github.com/godotengine/godot/issues/38265 يبدو أنه تقرير مكرر عن هذا مع بعض تفاصيل الاستنساخ.

متى سيأتي هذا الإصلاح في السطر الرئيسي؟
إنه أمر مزعج للغاية لأنني أستخدم نصوص حفظ الكتابة وأعمل في كثير من الأحيان في هذه المشكلة.
اليوم أواجه حالة لا يمكن حلها.

extends Resource
class_name WfcSlotHistory

func _init(slot:WfcSlot):
    pass
extends Resource
class_name WfcSlot

function saveHistory():
   var history:WfcSlotHistory = WfcSlotHistory.new(self)
   ...

res: //assets/wfc/WfcSlotHistory.gd : 5 - خطأ في التحليل: لا يمكن تحميل الفئة "WfcSlot" بالكامل (خطأ في البرنامج النصي أو التبعية الدورية).
وحدات / gdscript / gdscript. cpp: 576 - فشل الأسلوب. العودة: ERR_PARSE_ERROR

MikeSchulze في هذه الحالة ، أشعر أنها مشكلة تصميم جزئيًا: ربما لا يجب أن يعرف WfcSlot عن WfcSlotHistory . من المحتمل أن يكون الإجراء save على الأخير.

(هذا السلوك / الخطأ _ هو مزعج ، مع ذلك ، لا تفهمني بشكل خاطئ.)

@ Jeto143 شكرًا
نأمل أن يتم حل هذا الخطأ

مرحبًا أيها المطورين عندما يتم حل هذا الخطأ الطويل ... أخيرًا؟

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

لدي فصل مثل هذا (مثال simpe)
""
يمتد الموارد
class_name ClassA

_init (valueA: int، valueB: int):
مطبوعات (القيمة أ ، القيمة ب)

دالة ثابتة لـ (القيمة: int) -> ClassA:
إرجاع ClassA.new (قيمة ، قيمة)
""

""
var o: ClassA = ClassA.new (1،2) # يعمل بشكل جيد

var o2: ClassA = ClassA.of (2) # ينتج الخطأ

""

نتج عن استخدام func الثابت هذا الخطأ.
"خطأ في المحلل اللغوي: استخدام الاسم الخاص في ملف الفئة غير مسموح به (إنشاء مرجع دوري)"

لذلك يمنعني هذا من كتابة فصل دراسي لاستخدام عدة منشئات حيث يكون السلوك القياسي في اللغات الحديثة.

أنا أستخدم حلًا بديلًا حاليًا مثل هذا
""
دالة ثابتة لـ (القيمة: int) -> ClassA:
var clazz = load ("res: //../../ClassA.gd")
إرجاع clazz.new (قيمة ، قيمة)
""

تحياتي الحارة
مايك

مرحبًا أيها المطورين عندما يتم حل هذا الخطأ الطويل ... أخيرًا؟

سيتم حلها في 4.0 كجزء من إعادة كتابة GDScript.

هل سيعمل هذا مع الوظائف الثابتة أيضًا عند إصلاحها؟

class_name Cls

static func f():
    print(Cls)

vnen لذلك نحن في الإصدار 3.2.X ، هل يمكننا توقع الإصلاح في أي وقت قريب؟

@ Ploppy3 ترجع هذه الإصلاحات إلى التغييرات الهائلة التي تأتي مع إعادة كتابة GDScript ومن المحتمل ألا يكون من الممكن انتقاؤها بعناية. سيكون عليك الترقية إلى 4.0 إذا كنت ترغب في الحصول على هذه الإصلاحات.

لدي هذه المشكلة أيضًا ، إليك نصي النصي.

class_name Entity extends Area2D

export var resource : Resource

onready var sprite   = get_node("sprite")
onready var collider = get_node("collider")

func _process(delta: float) -> void:
    if sprite   == null: sprite   = get_node("sprite")
    if collider == null: collider = get_node("collider")
    if resource is EntityConfig:
        sprite.frame = wrapf(sprite.frame+resource.gfx_speed, resource.gfx_start, resource.gfx_start+resource.gfx_count)
class_name EntityConfig extends Resource

export var gfx_image   := ""
export var gfx_start   := 0
export var gfx_speed   := 1.0
export var gfx_count   := 0
export var gfx_xoffset := 0.0
export var gfx_yoffset := 0.0
export var gfx_xsize   := 16.0
export var gfx_ysize   := 16.0
export var hit_xoffset := 0.0
export var hit_yoffset := 0.0
export var hit_xsize   := 16.0
export var hit_ysize   := 16.0

func new()->Area2D:
    var entity = Entity.new()
    entity.sprite            = Content.load_texture(gfx_image)
    if entity.sprite != null:
        entity.sprite.frame      = gfx_start
        entity.sprite.position.x = gfx_xoffset
        entity.sprite.position.y = gfx_yoffset
        entity.sprite.hframes    = entity.sprite.texture.get_width () / gfx_xsize
        entity.sprite.vframes    = entity.sprite.texture.get_height() / gfx_ysize

    entity.collider.position.x      = hit_xoffset
    entity.collider.position.y      = hit_yoffset
    entity.collider.shape.extents.x = hit_xsize / 2
    entity.collider.shape.extents.y = hit_ysize / 2
    return entity

لقد اكتشفت هذه المشكلة للتو أثناء عملي في مشروع مجموعة التخرج في Godot 3.2.3. بالنسبة إلى عمليات نداء التصادم ، لدينا شيء مثل هذا:

extends Area2D

func _on_Throwable_body_entered(body: Node) -> void:
    if body is Player:
        if body.pick_up():
            queue_free()

لذلك نريد التحقق من if body is Player قبل استدعاء الأساليب الخاصة باللاعبين. المشكلة هي أن Player قد يكون متاحًا أو غير متوفر ، حتى لو كان في النطاق العالمي ، سواء تم الإعلان عنه عبر class_name أو preload -ed. يحدث هذا حتى إذا لم يقم Player بتحميل البرنامج النصي مسبقًا لإحداث تبعية دائرية واضحة.

نحن نعمل حاليًا على حل هذا الأمر من خلال التأكد من أن Player هو الشيء الوحيد في قناع التصادم Area2D وعدم فحص أي شيء في الكود على الإطلاق. في البداية كنا نتحقق من if body.name == "player" .

يسعدني معرفة أنه يجري العمل عليها ، حتى لو استغرق الأمر وقتًا طويلاً ، وآمل أن يسير كل شيء على ما يرام.

واجهت مشكلة تبعية مماثلة عندما منعني ذلك من تنفيذ نموذج Builder باستخدام طريقة ثابتة:

class_name MyClass

static func build() -> MyClass:
  var new_instance  = MyClass.new()
  ...
  return new_instance

الحل الموصوف هنا لتحميل فئة من مسار الملف المصدر جيد ولكنه يتطلب عدم تغيير شجرة الملف دون تغيير كود المصدر.

أستخدم هذه الحيلة للحصول على مسار ملف المصدر الحالي حتى في الطريقة الثابتة (حيث لا يتوفر get_script ()):

static func build() :
    var new_instance = load(GodotExt.current_script_path()).new()
    ...
    return new_instance

مع

class_name GodotExt

static func current_script_path():
    return get_stack()[1].source    <- return usable script path

يبدو أن هذه الحيلة للحصول على الفصل الحالي تعمل من أي مكان.
إنه خام ويمكن استخدامه لتجنب مشكلة التبعية الدورية المماثلة التي تنتظر إصلاح التبعية العالمية.

مرحبا AliBouarab خدعة لطيفة

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات