উপাদান-ভিত্তিক নকশা: হ্যান্ডলিং অবজেক্ট ইন্টারঅ্যাকশন


9

আমি নিশ্চিত নই যে উপাদানগুলি কীভাবে কোনও উপাদান ভিত্তিক ডিজাইনে অন্য বস্তুর সাথে জিনিস করে।

বলুন আমার একটা Objক্লাস আছে। আমি করি:

Obj obj;
obj.add(new Position());
obj.add(new Physics());

তখন আমি কীভাবে অন্য একটি বস্তু থাকতে পারি কেবলমাত্র বলটি সরিয়ে না রেখে those পদার্থবিজ্ঞানের প্রয়োগ করতে পারি। আমি বাস্তবায়নের বিশদটি খুঁজছি না বরং অবজেক্টে কীভাবে বস্তুগুলি যোগাযোগ করে। একটি সত্তা ভিত্তিক নকশায়, আপনার সবেমাত্র থাকতে পারে:

obj1.emitForceOn(obj2,5.0,0.0,0.0);

কোনও উপাদান চালিত নকশায় এবং বেসিক জিনিসগুলি কীভাবে করা যায় সে সম্পর্কে আরও ভাল উপলব্ধি পেতে যে কোনও নিবন্ধ বা ব্যাখ্যা সত্যই সহায়ক হবে।

উত্তর:


10

এটি সাধারণত বার্তা ব্যবহার করে করা হয়। আপনি এখানে বা সেখানকার মতো এই সাইটে অন্যান্য প্রশ্নের মধ্যে প্রচুর বিশদ জানতে পারেন ।

আপনার নির্দিষ্ট উদাহরণটির উত্তর দেওয়ার জন্য, যাওয়ার একটি উপায় হল একটি ছোট Messageশ্রেণীর সংজ্ঞা দেওয়া যা আপনার জিনিসগুলি প্রক্রিয়া করতে পারে, যেমন:

struct Message
{
    Message(const Objt& sender, const std::string& msg)
        : m_sender(&sender)
        , m_msg(msg) {}
    const Obj* m_sender;
    std::string m_msg;
};

void Obj::Process(const Message& msg)
{
    for (int i=0; i<m_components.size(); ++i)
    {
        // let components do some stuff with msg
        m_components[i].Process(msg);
    }
}

এই Objউপাদানটি সম্পর্কিত উপাদানগুলির সাথে আপনি শ্রেণিক ইন্টারফেসটিকে "দূষিত" করছেন না । কিছু উপাদান বার্তাটি প্রক্রিয়া করার জন্য চয়ন করতে পারে, কিছু এটি এড়িয়ে যেতে পারে।

আপনি অন্য কোনও অবজেক্ট থেকে সরাসরি এই পদ্ধতিটি কল করে শুরু করতে পারেন:

Message msg(obj1, "EmitForce(5.0,0.0,0.0)");
obj2.ProcessMessage(msg);

এই ক্ষেত্রে, obj2এর Physicsবার্তা বাছাই, এবং যাই হোক না কেন প্রক্রিয়াকরণের এটা করতে প্রয়োজন হবে। হয়ে গেলে এটি হয়:

  • স্বকে একটি "সেটপজিশন" বার্তা প্রেরণ করুন, যে Positionউপাদানটি বেছে নেবে;
  • বা Positionপরিবর্তনের জন্য সরাসরি উপাদানটি অ্যাক্সেস করুন (খাঁটি উপাদান-ভিত্তিক নকশার জন্য বেশ ভুল, আপনি প্রতিটি বস্তুর একটি Positionউপাদান অনুমান করতে পারবেন না , তবে Positionউপাদানটি প্রয়োজনীয় হতে পারে Physics)।

পরবর্তী উপাদানগুলির আপডেটে বার্তাটির প্রকৃত প্রসেসিংয়ে বিলম্ব করা সাধারণত একটি ভাল ধারণা । এটির তাত্ক্ষণিক প্রক্রিয়াটি অর্থ অন্য বস্তুর অন্যান্য উপাদানগুলিতে বার্তা প্রেরণ করতে পারে, সুতরাং কেবলমাত্র একটি বার্তা প্রেরণে দ্রুত বোঝা যায় একটি অযৌক্তিক স্প্যাগেটি স্ট্যাক।

আপনাকে সম্ভবত পরে আরও উন্নত সিস্টেমে যেতে হবে: অ্যাসিনক্রোনাস বার্তা সারি, অবজেক্টের গোষ্ঠীতে বার্তা প্রেরণ, প্রতি-উপাদান নিবন্ধকরণ / বার্তা থেকে নিবন্ধনকরণ ইত্যাদি etc.

Messageউপরে দেখানো কিন্তু রানটাইম এ প্রক্রিয়া স্ট্রিং সত্যিই দক্ষ নয় বর্গ একটি সহজ স্ট্রিং এর জন্য একটি জেনেরিক ধারক হতে পারে না। আপনি জেনেরিক মানের একটি ধারক যেতে পারেন: স্ট্রিংস, পূর্ণসংখ্যার, ভাসমান ... একটি নাম সহ বা আরও ভাল, একটি আইডি সহ বিভিন্ন ধরণের বার্তাগুলি আলাদা করতে। অথবা আপনি নির্দিষ্ট প্রয়োজনগুলির সাথে ফিট করার জন্য একটি বেস ক্লাসও অর্জন করতে পারেন। আপনার ক্ষেত্রে, আপনি এমন কোনও কল্পনা করতে পারেন EmitForceMessageযা থেকে উদ্ভূত হয়েছে Messageএবং কাঙ্ক্ষিত বল ভেক্টর যুক্ত করেছে - তবে আপনি যদি এটি করেন তবে আরটিটিআইয়ের রানটাইম ব্যয় থেকে সাবধান থাকুন ।


3
আমি সরাসরি অ্যাক্সেস করার উপাদানগুলির "অ শুদ্ধতা" সম্পর্কে চিন্তা করব না। উপাদানগুলি একাডেমিয়ার নয়, ক্রিয়ামূলক এবং নকশার প্রয়োজনগুলি পরিবেশন করতে ব্যবহৃত হয়। আপনি কোনও উপাদান উপস্থিত রয়েছে তা পরীক্ষা করতে চান (উদাহরণস্বরূপ, চেক রিটার্ন মানটি কন্টেন্ট কল পাওয়ার জন্য নাল নয়)।
শান মিডলডিচ

আপনি সর্বশেষে যেমনটি বলেছিলেন, আরটিটিআই ব্যবহার করে আমি এটি সবসময়ই ভেবেছিলাম তবে এত বেশি লোক
আরটিটিআই

@ সানমিডলিচ নিশ্চিত, আমি এটি এইভাবে করব, কেবল এটি উল্লেখ করে এটি স্পষ্ট করে তুলতে যে একই সত্তার অন্যান্য উপাদানগুলিতে অ্যাক্সেস করার সময় আপনি কী করছেন তা সর্বদা আপনার ডাবল-চেক করা উচিত।
লরেন্ট কুইভিডউ

@Milo কম্পাইলার প্রয়োগ RTTI এবং তার dynamic_cast পারবেন একটি বোতলের হয়ে, কিন্তু আমি এখন জন্য যে সম্পর্কে চিন্তা woudln't। এটি এখনও কোনও সমস্যা হয়ে থাকলে পরে এটিকে অপ্টিমাইজ করতে পারেন। সিআরসি-ভিত্তিক শ্রেণি শনাক্তকারীরা কবজির মতো কাজ করে।
লরেন্ট কুইভিডউ

<template <typename T> uint32_t class_id () {স্থির uint32_t v; রিটার্ন (uint32_t) & v; । ´ - আরটিটিআইয়ের দরকার নেই।
arul

3

আপনি যা দেখায় তার মতো সমস্যার সমাধান করার জন্য আমি যা করেছি তা হ'ল কিছু নির্দিষ্ট উপাদান হ্যান্ডলার যুক্ত করা এবং একরকম ইভেন্ট রেজোলিউশন সিস্টেম যুক্ত করা।

সুতরাং, আপনার "পদার্থবিজ্ঞান" অবজেক্টের ক্ষেত্রে, যখন এটি আরম্ভ করা হয় তখন এটি নিজেকে পদার্থবিজ্ঞানের অ্যাজেজেটসির একটি কেন্দ্রীয় পরিচালক হিসাবে যুক্ত করে। গেম লুপে, এই ধরণের পরিচালকদের নিজস্ব আপডেট ধাপ থাকে, সুতরাং এই পদার্থবিজ্ঞাতা আপডেট করা হলে এটি সমস্ত পদার্থবিজ্ঞানের ইন্টারঅ্যাকশন গণনা করে এবং ইভেন্টের কাতারে যুক্ত করে।

আপনার সমস্ত ইভেন্ট তৈরি করার পরে, আপনি কীভাবে ঘটেছে তা যাচাই করে নিখরচায় আপনার ইভেন্টের সারিটি সমাধান করতে পারেন এবং আপনার পদক্ষেপে কথায় কথায় কথায় কথায় কথায় কথায় কথায় একটি ঘটনা ঘটানো উচিত, যাতে আপনি আপনার emitForceOn পদ্ধতিতে কল করেন।

এই পদ্ধতির পেশাদাররা:

  • ধারণা অনুসারে, অনুসরণ করা সত্যই সহজ।
  • কোয়াড্রেস ব্যবহার করা বা আপনার যা প্রয়োজন তা নির্দিষ্ট সুনির্দিষ্টকরণের জন্য আপনাকে জায়গা দেয়।
  • এটি সত্যই "প্লাগ এবং প্লে" হচ্ছে। পদার্থবিজ্ঞানের সাথে অবজেক্টগুলি নন-ফিজিক্স অবজেক্টের সাথে ইন্টারঅ্যাক্ট করে না কারণ তারা ম্যানেজারের জন্য বিদ্যমান না।

কনস:

  • আপনি অনেকগুলি রেফারেন্স ঘুরে দেখছেন, সুতরাং আপনি যদি সাবধান না হন (আপনার উপাদান থেকে উপাদান উপাদান, পরিচালক থেকে উপাদান, ইভেন্ট থেকে অংশগ্রহণকারী ইত্যাদি) সঠিকভাবে সবকিছু পরিষ্কার করতে কিছুটা অগোছালো হয়ে উঠতে পারে )।
  • আপনি যেভাবে প্রতিটি বিষয় সমাধান করেন সে বিষয়ে আপনাকে বিশেষ চিন্তা করতে হবে। আমি অনুমান করি এটি আপনার ক্ষেত্রে নয়, তবে আমি একাধিক অসীম লুপের মুখোমুখি হয়েছি যেখানে একটি ইভেন্ট অন্য ইভেন্ট তৈরি করেছে এবং আমি কেবল এটি ইভেন্টের সারিতে সরাসরি যুক্ত করছি।

আশা করি এটা কাজে লাগবে.

PS: যদি কারও কাছে এটি সমাধান করার জন্য আরও ক্লিনার / আরও ভাল উপায় থাকে তবে আমি এটি শুনতে চাই।


1
obj->Message( "Physics.EmitForce 0.0 1.1 2.2" );
// and some variations such as...
obj->Message( "Physics.EmitForce", "0.0 1.1 2.2" );
obj->Message( "Physics", "EmitForce", "0.0 1.1 2.2" );

এই নকশাটি লক্ষ্য করার জন্য কয়েকটি বিষয়:

  • উপাদানটির নাম হ'ল প্রথম প্যারামিটার - এটি বার্তায় খুব বেশি কোডের কাজ এড়ানো এড়ানো - কোনও বার্তা কোন উপাদানগুলির দ্বারা ট্রিগার করতে পারে তা আমরা জানতে পারি না - এবং আমরা সব% 90% ব্যর্থতার সাথে একটি বার্তা চিবানো চাই না we রেট যা প্রচুর অপ্রয়োজনীয় শাখায় রূপান্তরিত হয় এবং strcmp এর mp
  • বার্তার নাম দ্বিতীয় প্যারামিটার।
  • প্রথম ডট (# 1 এবং # 2 এ) প্রয়োজন হয় না, এটি কেবল পড়া সহজ করার জন্য (লোকেরা কম্পিউটার নয়)।
  • এটি sscanf, iostream, আপনি-নামটি সামঞ্জস্যপূর্ণ। এমন কোনও সিনট্যাকটিক চিনি যা বার্তার প্রক্রিয়াকরণকে সহজ করতে কিছুই করে না।
  • একটি স্ট্রিং প্যারামিটার: নেটিভ টাইপগুলি পাস করা মেমরির প্রয়োজনীয়তার তুলনায় সস্তা নয় কারণ আপনাকে তুলনামূলকভাবে অজানা টাইপের প্যারামিটারগুলির একটি অজানা সংখ্যা সমর্থন করতে হবে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.