घटक इकाई प्रणाली - अद्यतन और कॉल आदेश


10

हर फ्रेम को अपडेट करने में सक्षम होने के लिए घटकों को प्राप्त करने के लिए (और इस कार्यक्षमता को उन घटकों से बाहर करने की आवश्यकता नहीं है) जिन्हें मुझे अपडेटकंपोनेंट घटक बनाने का विचार मिला। अन्य घटक जैसे MovableComponent(जो वेग रखता है) IUpdatableअमूर्त वर्ग से विरासत में मिला होगा । यह MovableComponentएक Update(gametime dt)विधि को लागू करने के लिए मजबूर करता है और दूसरा RegisterWithUpdater()जो UpdateComponentएक संकेतक देता है MovableComponent। कई घटक ऐसा कर सकते थे और फिर UpdateComponentअपने सभी Update(gametime dt)तरीकों को कॉल कर सकते थे बिना इस बात की परवाह किए कि वे कौन हैं या क्या हैं।

मेरे प्रश्न हैं:

  1. क्या यह ऐसा कुछ भी प्रतीत होता है जो सामान्य है या किसी के द्वारा उपयोग किया जाता है? मुझे इस विषय पर कुछ नहीं मिल रहा है।
  2. मैं भौतिकी जैसे घटकों के लिए एक आदेश कैसे बना सकता हूं फिर स्थिति बदल सकती है? क्या यह भी आवश्यक है?
  3. यह सुनिश्चित करने के अन्य तरीके क्या हैं कि हर फ्रेम को प्रोसेस करने वाले घटकों को वास्तव में संसाधित किया जाना चाहिए?

EDIT
मुझे लगता है कि मैं इस बात पर ध्यान दूंगा कि कैसे इकाई प्रबंधक को उन प्रकारों की एक सूची दी जाए जो अद्यतन करने योग्य हैं। फिर उस प्रकार के सभी घटक प्रति इकाई (जो मेरे सिस्टम में अभी भी अनुक्रमित हैं) को प्रबंधित करने के बजाय अपडेट कर सकते हैं।

फिर भी। मेरे प्रश्न मेरे लिए मान्य हैं। मुझे नहीं पता कि यह तर्कपूर्ण / सामान्य है, या अन्य क्या करते हैं।

इसके अलावा, Insomniac के लोग कमाल के हैं! / संपादित करें

पिछले उदाहरण के लिए उबला हुआ कोड:

class IUpdatable
{
public:
    virtual void Update(float dt) = 0;
protected:
    virtual void RegisterAsUpdatable() = 0;
};

class Component
{
    ...
};

class MovableComponent: public Component, public IUpdatable
{
public:
    ...
    virtual void Update(float dt);
private:
    ...
    virtual void RegisterWithUpdater();
};

class UpdateComponent: public Component
{
public:
    ...
    void UpdateAll();
    void RegisterUpdatable(Component* component);
    void RemoveUpdatable(Component* component);
private:
    ...
    std::set<Component*> updatables_;
};

क्या आपके पास एक घटक के लिए एक उदाहरण है जो अद्यतन करने योग्य नहीं है? जो बहुत बेकार लगता है। घटक में वर्चुअल फ़ंक्शन के रूप में अद्यतन फ़ंक्शन रखें। फिर बस इकाई में सभी घटकों को अपडेट करें, "UpdateComponent" के लिए कोई ज़रूरत नहीं है
Maik Semder

कुछ घटक डेटा धारकों की तरह अधिक हैं। स्थिति की तरह। कई वस्तुओं में एक स्थिति हो सकती है, लेकिन अगर वे स्थिर हैं, जो बहुसंख्यक हो सकते हैं, तो उन सभी अतिरिक्त आभासी कॉल का निर्माण हो सकता है। या कहें एक HealthComponent। इसके लिए हर फ्रेम में कुछ भी करने की जरूरत नहीं है, बस जरूरत पड़ने पर इसे संशोधित करें। हो सकता है कि ओवरहेड उतना बुरा न हो, लेकिन मेरा UpdateComponent EVERY घटक में अपडेट () नहीं करने का प्रयास था।
ptpaterson

5
एक घटक जो केवल डेटा रखता है और समय के साथ इसे बदलने के लिए कोई कार्यक्षमता नहीं है, यह एक घटक नहीं है। घटक में कुछ कार्यात्मक होना चाहिए जो समय के साथ बदलता है, इसलिए एक अद्यतन फ़ंक्शन की आवश्यकता होती है। यदि आपके घटक को अपडेट फ़ंक्शन की आवश्यकता नहीं है, तो आपको पता है कि यह एक घटक नहीं है और आपको डिज़ाइन को पुनर्विचार करना चाहिए। स्वास्थ्य घटक में एक अद्यतन कार्य समझ में आता है, उदाहरण के लिए आप चाहते हैं कि आपका एनपीसी कुछ समय के लिए क्षति से ठीक हो जाए।
माईक सेमर

@ माईक मेरी बात यह नहीं थी कि ऐसे घटक हैं जो कभी नहीं बदलेंगे / कभी नहीं बदल सकते। मैं सहमत हूं कि यह मूर्खतापूर्ण है। उन्हें हर फ्रेम को अपडेट करने की जरूरत नहीं है, बल्कि जरूरत पड़ने पर अपनी जानकारी बदलने के लिए सूचित किया जाना चाहिए। समय के साथ स्वास्थ्य के उदाहरण में, एक स्वास्थ्य बोनस घटक होगा जिसे अपडेट नहीं है। मुझे नहीं लगता कि दोनों को मिलाने का कोई कारण है।
पिपेटर्सन

मैं यह भी नोट करना चाहता हूं कि मैंने जो कोड पोस्ट किया है उसमें केवल अपडेटकॉम कॉन्सेप्ट को समझाने की जरूरत है। यह घटकों के बीच संचार के अन्य सभी प्रकार को बाहर करता है।
पिपेटर्सन

जवाबों:


16

एक घटक प्रणाली के प्राथमिक लाभों में से एक कैशिंग पैटर्न का लाभ उठाने की क्षमता है - अच्छा आईकैश और भविष्यवाणी, क्योंकि आप एक ही कोड को बार-बार चलाते हैं, अच्छा dcache क्योंकि आप सजातीय पूल में वस्तुओं को आवंटित कर सकते हैं और क्योंकि vtables, यदि किसी भी, गर्म रहो।

जिस तरह से आपने अपने घटकों को संरचित किया है, यह लाभ पूरी तरह से गायब हो जाता है, और वास्तव में एक विरासत आधारित प्रणाली की तुलना में प्रदर्शन दायित्व बन सकता है, क्योंकि आप vtables के साथ कहीं अधिक आभासी कॉल और अधिक ऑब्जेक्ट बना रहे हैं।

आपको जो करना चाहिए, वह प्रति प्रकार पूल का भंडारण कर रहा है, और अद्यतन करने के लिए प्रत्येक प्रकार को स्वतंत्र रूप से पुनरावृत्त कर रहा है।

क्या यह ऐसा कुछ भी प्रतीत होता है जो सामान्य है या किसी के द्वारा उपयोग किया जाता है? मुझे इस विषय पर कुछ नहीं मिल रहा है।

बड़े खेलों में यह आम नहीं है क्योंकि यह फायदेमंद नहीं है। यह बहुत सारे खेलों में आम है, लेकिन यह तकनीकी रूप से दिलचस्प नहीं है, इसलिए कोई भी इसके बारे में नहीं लिखता है।

मैं भौतिकी जैसे घटकों के लिए एक आदेश कैसे बना सकता हूं फिर स्थिति बदल सकती है? क्या यह भी आवश्यक है?

C ++ जैसी भाषाओं में कोड निष्पादन के लिए एक प्राकृतिक तरीका है: उस क्रम में स्टेटमेंट टाइप करें।

for (PhysicsComponent *c : physics_components)
    c->update(dt);
for (PositionComponent *c : position_components)
    c->update(dt);

वास्तव में, इसका कोई मतलब नहीं है क्योंकि कोई भी मजबूत भौतिकी प्रणाली उस तरह से संरचित नहीं है - आप किसी एक भौतिकी वस्तु को अपडेट नहीं कर सकते। इसके बजाय, कोड अधिक दिखेगा:

physics_step();
for (PositionComponent *c : position_components)
    c->update(dt);
// Updates the position data from the physics data.

धन्यवाद। मैंने इस पूरी परियोजना की शुरुआत डेटा ओरिएंटेड (डेटा द्वारा संचालित नहीं) को ध्यान में रखते हुए की, कैश मिस और इस तरह की घटनाओं को रोका। लेकिन एक बार जब मैंने कोडिंग शुरू की तो मैंने बस कुछ ऐसा बनाने का फैसला किया जो डॉट कॉम पर काम करता हो। यह मुझे मुझ पर कठिन बना दिया है। और गंभीर के लिए, वह अनिद्रा लेख बहुत अच्छा था!
ptpaterson

@Joe +1 बहुत अच्छे उत्तर के लिए। हालांकि मैं जानना चाहता हूं कि आईकैश और डीसीए क्या हैं। धन्यवाद
रे डे

निर्देश कैश और डेटा कैश। कंप्यूटर वास्तुकला पर कोई भी परिचयात्मक पाठ उन्हें कवर करना चाहिए।

@ptpaterson: ध्यान दें कि Insomniac प्रस्तुति में एक छोटी सी गलती है - घटक वर्ग में इसका रोस्टर इंडेक्स होना चाहिए, या आपको सूचकांकों को रोस्टर करने के लिए पूल सूचक की एक अलग मैपिंग की आवश्यकता होगी।

3

जो आप बात कर रहे हैं वह उचित और काफी सामान्य है, मुझे लगता है। यह आपको कुछ और जानकारी दे सकता है।


मुझे लगता है कि मैं कुछ हफ़्ते पहले उस लेख पर आया था। मैं एक घटक आधारित निकाय प्रणाली के कुछ बहुत ही सरल संस्करणों को एक साथ कोड करने में सक्षम रहा हूं, प्रत्येक अलग-अलग चीजों को आजमाता हूं। सभी लेखों और उदाहरणों को एक साथ लाने की कोशिश कर रहा हूं, जो मैं चाहता हूं और करने में सक्षम हूं। धन्यवाद!
ptpaterson

0

मुझे ये दृष्टिकोण पसंद हैं:

संक्षेप में: घटकों के भीतर अद्यतन व्यवहार रखने से बचें। घटक व्यवहार नहीं हैं। व्यवहार (अपडेट सहित) कुछ एकल-उदाहरण सबसिस्टम में लागू किया जा सकता है। यह दृष्टिकोण कई घटकों के लिए समान व्यवहार को बैचने में मदद कर सकता है (शायद घटक डेटा पर समानांतर_समर्थन या SIMD निर्देशों का उपयोग करके)।

IUpditable विचार और अद्यतन (gametime dt) विधि थोड़ी बहुत प्रतिबंधात्मक है और अतिरिक्त अवसादों का परिचय देती है। यह ठीक हो सकता है यदि आप सबसिस्टम दृष्टिकोण का उपयोग नहीं कर रहे हैं, लेकिन यदि आप उनका उपयोग करते हैं, तो IUpdatable पदानुक्रम का एक अनावश्यक स्तर है। सब के बाद, मूविंगसिस्टम को पता होना चाहिए कि यह सभी संस्थाओं के लिए सीधे स्थान और / या वेग के घटकों को अपडेट करना चाहिए, जिसमें ये घटक हैं, इसलिए कुछ मध्यवर्ती IUpdatable घटक की आवश्यकता नहीं है।

लेकिन आप स्थान और / या वेग घटकों के बावजूद कुछ संस्थाओं को अपडेट करने के लिए अद्यतन करने के लिए एक तंत्र के रूप में अद्यतन योग्य घटक का उपयोग कर सकते हैं। अपडेट करने योग्य घटक में एक बूल ध्वज हो सकता है जिसे सेट किया जा सकता है falseऔर यह हर अद्यतन-योग्य उप-प्रणाली को संकेत देगा कि वर्तमान में इस विशेष इकाई को अपडेट नहीं किया जाना चाहिए (हालांकि इस तरह के संदर्भ में, फ़्रीज़ेबल घटक के लिए अधिक उपयुक्त नाम लगता है)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.