আমি কীভাবে এক টুকরো কোডের চালানোর বিষয়টি নিশ্চিত করব?


18

আমার কিছু কোড রয়েছে যা আমি কেবল একবার চালাতে চাই, যদিও সেই কোডটি ট্রিগার করে এমন পরিস্থিতিতে একাধিকবার ঘটতে পারে।

উদাহরণস্বরূপ, যখন ব্যবহারকারী মাউস ক্লিক করে, আমি জিনিসটি ক্লিক করতে চাই:

void Update() {
    if(mousebuttonpressed) {
        ClickTheThing(); // I only want this to happen on the first click,
                         // then never again.
    }
}

যাইহোক, এই কোডটি সহ, আমি যতবার মাউসকে ক্লিক করব তখন জিনিসটি ক্লিক করা হবে। আমি কীভাবে এটি একবারে ঘটতে পারি?


7
আমি আসলে এই ধরণের মজাদার খুঁজে পাই কারণ আমার মনে হয় না এটি "গেম-সুনির্দিষ্ট প্রোগ্রামিং ইস্যুগুলির" মধ্যে পড়ে। তবে আমি কখনই সেই নিয়ম পছন্দ করি নি।
ক্লাসিকথান্ডার

3
ক্ল্যাসিকথান্ডার হ্যাঁ, এটি সাধারণ প্রোগ্রামিংয়ের বিষয়গুলিতে অবশ্যই বেশি। আপনার পছন্দ হলে বন্ধ করতে ভোট দিন, আমি প্রশ্নটি আরও পোস্ট করেছি যাতে লোকেরা যখন তাদের কাছে অনুরূপ প্রশ্ন জিজ্ঞাসা করে তখন আমাদের কাছে কিছু বোঝাতে চাই। এটি সেই উদ্দেশ্যে খোলা বা বন্ধ করা যেতে পারে।
MichaelHouse

উত্তর:


41

বুলিয়ান পতাকা ব্যবহার করুন।

প্রদর্শিত উদাহরণে, আপনি কোডটিকে নিম্নলিখিতগুলির মতো হতে কিছু সংশোধন করতে চান:

//a boolean flag that lets us "remember" if this thing has happened already
bool thatThingHappened = false;

void Update() {
    if(!thatThingHappened && mousebuttonpressed) {
        //if that thing hasn't happened yet and the mouse is pressed
        thatThingHappened = true;
        ClickTheThing();
    }
}

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


1
আপনার প্রশ্নের সুস্পষ্ট উত্তর :-) আপনি বা অন্য কেউ যদি কেউ জানেন তবে আমি বিকল্প উপায়গুলি দেখতে আগ্রহী। এর জন্য একটি গ্লোবাল বুলিয়ান ব্যবহার আমার কাছে বরাবরই দুর্গন্ধযুক্ত।
এভোরলর

1
@ এভেলারর সবার কাছে সুস্পষ্ট নয় :) :) আমি বিকল্প সমাধানগুলিতেও আগ্রহী, সম্ভবত আমরা এমন কিছু শিখতে পারি যা এতটা স্পষ্ট নয়!
MichaelHouse

2
@ এভেলর বিকল্প হিসাবে আপনি প্রতিনিধিদের (ফাংশন পয়েন্টার) ব্যবহার করতে পারেন এবং কী পদক্ষেপ নেওয়া হয় তা পরিবর্তন করতে পারেন। উদাহরণস্বরূপ onStart() { delegate = doSomething; } ... if(mousebuttonpressed) { delegate.Execute(); }এবং void doSomething() { doStuff(); delegate = funcDoNothing; }তবে শেষ পর্যন্ত সমস্ত বিকল্পের মধ্যে কিছু সেট থাকে যা আপনি সেট / আনসেট না করে কিছু ধরণের পতাকা রাখেন ... এবং এই ক্ষেত্রে ডেলিগেট অন্য কিছু নয় (যদি আপনার কাছে দুটি বিকল্পের বেশি থাকে তবে সম্ভবত কি করবেন?)।
ওয়েজরা

2
@ ওন্ড্রা হ্যাঁ, এটি একটি উপায়। এটি যোগ করুন। আমরা পাশাপাশি এই প্রশ্নে সম্ভাব্য সমাধানগুলির একটি তালিকা তৈরি করতে পারি।
মাইকেলহাউস

1
@ জামেসসেনেল সম্ভবত এটি বহু-থ্রেডযুক্ত। তবে এখনও একটি ভাল অনুশীলন।
MichaelHouse

21

যদি পতাকা পতাকা যথেষ্ট না হয় বা আপনি void Update()পদ্ধতিতে কোডটির পঠনযোগ্যতা * উন্নত করতে চান তবে আপনি প্রতিনিধিদের (ফাংশন পয়েন্টার) ব্যবহার বিবেচনা করতে পারেন :

public class InputController 
{
  //declare delegate type:
  //<accessbility> delegate <return type> <name> ( <parameter1>, <paramteter2>, ...)
  public delegate void ClickAction();

  //declare a variable of that type
  public ClickAction ClickTheThing { get; set; }

  void onStart()
  {
    //assign it the method you wish to execute on first click
    ClickTheThing = doStuff;
  }

  void Update() {
    if(mousebuttonpressed) {
        //you simply call the delegate here, the currently assigned function will be executed
        ClickTheThing();
     }
  }

  private void doStuff()
  {
    //some logic here
    ClickTheThing = doNothing; //and set the delegate to other(empty) funtion
  }

  //or do something else
  private void doNothing(){}
}

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

func1() 
{
  //do logic 1 here
  someDelegate = func2;
}

func2() 
{
  //do logic 2 here
  someDelegate = func3;
}
//etc...

পরিবর্তে দশ হাজার বিভিন্ন পতাকা দিয়ে আপনার কোড জড়ান।
* বাকি কোডের কম রক্ষণাবেক্ষণের ব্যয়


আমি প্রত্যাশার সাথে ফলাফলের সাথে কিছু প্রোফাইলিং করেছি:

----------------------------------------
|     Method     |  Unity   |    C++   |
| -------------------------------------|
| positive flag  |  21 ms   |   6 ms   |
| negative flag  |  5 ms    |   7 ms   |
| delegate       |  25 ms   |   14 ms  |
----------------------------------------

প্রথম পরীক্ষাটি ইউনিটি 5.1.2 এ পরিচালিত হয়েছিল, System.Diagnostics.Stopwatch32-বিট নির্মিত প্রকল্পের সাথে ডিজাইন করা ( ডিজাইনে নয়!)। ভিজ্যুয়াল স্টুডিও 2015 এর অন্য একটি (v140) 32-বিট রিলিজ মোডে / অক্স পতাকা সহ সংকলিত। উভয় পরীক্ষা প্রতিটি বাস্তবায়নের জন্য 10,000,000 পুনরাবৃত্তি সহ, ইন্টেল i5-4670K সিপিইউ @ 3.4GHz এ পরিচালিত হয়েছিল। কোড:

//positive flag
if(flag){
    doClick();
    flag = false;
}
//negative flag
if(!flag){ }
else {
    doClick();
    flag = false;
}
//delegate
action();

উপসংহার: functionক্য সংকলক ফাংশন কলগুলি অনুকূল করার সময় একটি ভাল কাজ করে, ইতিবাচক পতাকা এবং প্রতিনিধি উভয়ের জন্য যথাক্রমে একই ফল দেয় (যথাক্রমে 21 এবং 25 এমএস) শাখার ভুল ধারণা বা ফাংশন কল এখনও বেশ ব্যয়বহুল (দ্রষ্টব্য: প্রতিনিধিকে ক্যাশে ধরে নেওয়া উচিত) এই পরীক্ষায়)।
মজার বিষয় হচ্ছে, 99ক্য সংকলকটি স্মার্ট যথেষ্ট নয় যখন শাখাটিকে যথাযথভাবে 99 মিলিয়ন ভুল অনুমান করা যায়, সুতরাং পরীক্ষার ম্যানুয়াল অবহেলা 5 এমএসের সেরা ফলাফল দেওয়ার জন্য কিছু কার্যকারিতা বাড়িয়ে তোলে। সি ++ সংস্করণটি অবহেলা করা অবস্থার জন্য কোনও কার্যকারিতা বাড়িয়ে তোলে না, তবে ফাংশন কলের সামগ্রিক ওভারহেড উল্লেখযোগ্যভাবে কম।
সবচেয়ে গুরুত্বপূর্ণ: পার্থক্যটি অনেকটা অপ্রাসঙ্গিক যে কোনও বাস্তব-জগতের দৃশ্যের জন্য


4
এএফআইকে এটি পারফরম্যান্সের দিক থেকেও ভাল। কোনও নির্দেশনা ফাংশন কল করা, অনুমান করা যে ফাংশনটি ইতিমধ্যে নির্দেশের ক্যাশে রয়েছে, পতাকা চেক করার চেয়ে অনেক দ্রুত, বিশেষত যেখানে অন্যান্য শর্তাধীন অধীনে চেকিং বাসা বাঁধে ।
ইঞ্জিনিয়ার

2
আমি মনে করি নবীন সঠিক, আমার বুলিয়ান পতাকা যাচাই করার চেয়ে খারাপ পারফরম্যান্স হওয়ার সম্ভাবনা রয়েছে - যদি না আপনার জেআইটি সত্যই স্মার্ট হয় এবং পুরো ফাংশনটিকে আক্ষরিক কিছুই দিয়ে প্রতিস্থাপন না করে। তবে আমরা ফলাফলগুলি প্রোফাইল না করা পর্যন্ত আমরা নিশ্চিতভাবে জানতে পারি না।
বিস্ময়কর

2
হুম, এই উত্তরটি আমাকে এসডাব্লু ইঞ্জিনিয়ারের বিবর্তনের কথা মনে করিয়ে দেয় । কৌতুক একদিকে, যদি আপনার এই পারফরম্যান্স উত্সাহের পুরোপুরি প্রয়োজন (এবং নিশ্চিত) হয় তবে এর জন্য যান। যদি তা না হয় তবে আমি এটিকে KISS রাখার পরামর্শ দিচ্ছি এবং অন্য উত্তরে প্রস্তাবিত মত বুলিয়ান পতাকা ব্যবহার করব । তবে, এখানে প্রতিনিধিত্ব করা বিকল্পের জন্য +1!
মুচাহো

1
যেখানে সম্ভব শর্তসাপূর্ণ এড়ানো। আমি মেশিন পর্যায়ে যা ঘটে তা নিয়ে কথা বলছি, তা সে আপনার নিজস্ব নেটিভ কোড, একটি জেআইটি সংকলক, বা অনুবাদক। এল 1 ক্যাশে হিট প্রায় একটি রেজিস্টার হিট হিসাবে সমান, সম্ভবত সামান্য ধীর অর্থাৎ 1 বা 2 চক্র, যেখানে শাখা সম্পর্কে ভুল ধারণা করা হয় যা প্রায়শই ঘটে তবে গড়পড়তাভাবে খুব বেশি হয় 10-10 চক্রের ক্রম হিসাবে costs Jalf দেখা উত্তর: stackoverflow.com/questions/289405/... এই: stackoverflow.com/questions/11227809/...
ইঞ্জিনিয়ার

1
আরও মনে রাখবেন যে বাইট 5 এর উত্তরে এই শর্তাদি আপনার প্রোগ্রামের আজীবনের জন্য প্রতিটি একক আপডেট হিসাবে ডাকা উচিত , এবং ভালভাবে বাসা বেঁধে থাকতে পারে বা তাদের মধ্যে নেস্টেড শর্তযুক্ত থাকতে পারে, যা পরিস্থিতি আরও খারাপ করে তোলে। ফাংশন পয়েন্টার / প্রতিনিধিরা যাওয়ার উপায়।
ইঞ্জিনিয়ার

3

সম্পূর্ণতার জন্য

(আসলে এটির মতো সুপারিশ করার মতো if(!already_called)আপনি এটি করার পরামর্শ দিচ্ছেন না তবে এটি করা "সঠিক" হবে))

আশ্চর্যজনকভাবে, সি ++ 11 স্ট্যান্ডার্ডটি একবার কোনও ফাংশন কল করার পরিবর্তে তুচ্ছ সমস্যাটিকে স্বীকৃতি দিয়েছে এবং এটিকে অত্যন্ত স্পষ্ট করে তুলেছে:

#include <mutex>

void Update() {
if(mousebuttonpressed) {
    static std::once_flag f;
    std::call_once(f, ClickTheThing);
}

}

স্বীকার করা যায় যে স্ট্যান্ডার্ডের উপস্থিতিতে স্ট্যান্ডার্ড সমাধানটি তুচ্ছ একটির চেয়ে কিছুটা উচ্চতর কারণ এটি এখনও গ্যারান্টি দেয় যে সর্বদা ঠিক একটি কল ঘটে, কখনও আলাদা কিছু হয় না।

তবে, আপনি সাধারণত কোনও মাল্টিথ্রেডেড ইভেন্টের লুপটি চালাচ্ছেন না এবং একই সাথে কয়েকটি ইঁদুরের বোতামগুলি টিপছেন না, যাতে থ্রেড সুরক্ষা আপনার ক্ষেত্রে কিছুটা অতিরিক্ত প্রয়োজন।

ব্যবহারিক ভাষায়, এর অর্থ হ'ল স্থানীয় বুলিয়ান (যা C ++ 11 যেভাবেই থ্রেড-নিরাপদ হওয়ার গ্যারান্টি দেয়) এর থ্রেড-নিরাপদ সূচনা ছাড়াও, স্ট্যান্ডার্ড সংস্করণে কল করা বা কল না করার আগে একটি পারমাণবিক টেস্ট_সেট অপারেশনও করতে হবে কাজ.

তবুও, আপনি যদি সুস্পষ্ট হওয়া পছন্দ করেন তবে সমাধান রয়েছে।

সম্পাদনা:
হু এখন যেহেতু আমি এখানে বসে আছি, কয়েক মিনিটের জন্য কোডটি ঘুরে দেখছি, আমি প্রায় এটির প্রস্তাব দিতে আগ্রহী।
প্রকৃতপক্ষে এটি প্রথমে মনে হয় যতটা নির্বোধ নয়, প্রকৃতপক্ষে এটি খুব স্পষ্ট এবং নির্বিঘ্নে আপনার অভিপ্রায়টি যোগাযোগ করে ... তাত্ক্ষণিকভাবে এটির কোনও সমাধানের চেয়ে আরও ভাল কাঠামোগত এবং আরও পাঠযোগ্য if


2

স্থাপত্যের উপর নির্ভর করে কিছু পরামর্শ পৃথক হবে vary

ফাংশন পয়েন্টার / ভেরিয়েন্ট / ডিএলএল / তাই / ইত্যাদি হিসাবে ক্লিকটিথিশিং () ক্লিক করুন ... এবং যখন অবজেক্ট / উপাদান / মডিউল / ইত্যাদি ... তাত্ক্ষণিকভাবে চালু হয় তা নিশ্চিত করে নিন যে এটি আপনার প্রয়োজনীয় ফাংশনটিতে আরম্ভ করা হয়েছে।

হ্যান্ডলারে যখনই মাউস বোতাম টিপুন তখন ক্লিক করুন এই টিচিং () ফাংশন পয়েন্টারটিতে ক্লিক করুন এবং তারপরে তত্ক্ষণাত পয়েন্টারটিকে অন্য একটি এনওপি (কোনও অপারেশন নয়) ফাংশন পয়েন্টার দিয়ে প্রতিস্থাপন করুন।

কারও পরে ঝাঁকুনির জন্য পতাকা এবং অতিরিক্ত যুক্তির প্রয়োজন নেই, কেবল এটি কল করুন এবং প্রতিবার এটি প্রতিস্থাপন করুন এবং এটি একটি এনওপি হিসাবে এনওপি কিছুই করে না এবং একটি এনওপি দিয়ে প্রতিস্থাপিত হয়।

অথবা আপনি কলটি এড়াতে পতাকা এবং যুক্তি ব্যবহার করতে পারেন।

বা আপনি কলটির পরে আপডেট () ফাংশনটি সংযোগ বিচ্ছিন্ন করতে পারেন যাতে বাইরের বিশ্ব এটি ভুলে যায় এবং আবার কখনও কল করে না।

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


2

ফাংশন পয়েন্টার বা প্রতিনিধি ব্যবহার করুন।

ফাংশন পয়েন্টারটি ধারণ করে চলকটি পরিবর্তন না হওয়া পর্যন্ত সুস্পষ্টভাবে পরীক্ষা করা দরকার। এবং যখন আপনার আর চালানোর জন্য যুক্তি বলার দরকার নেই, একটি খালি / না-অপশন ফাংশনটিতে একটি রেফ দিয়ে প্রতিস্থাপন করুন। শর্তসাপেক্ষে আপনার প্রোগ্রামের পুরো জীবনের প্রতিটি ফ্রেম চেক করার সাথে তুলনা করুন - এমনকি যদি পতাকাটি শুরু করার পরে প্রথম কয়েকটি ফ্রেমে কেবল প্রয়োজন হত! - অস্পষ্ট এবং অদক্ষ। (ভবিষ্যদ্বাণী সম্পর্কে বোরিলের বক্তব্য তবে এ ক্ষেত্রে স্বীকৃত।)

নেস্টেড শর্তাদি, যা এগুলি প্রায়শই গঠিত হয়, প্রতিটি ফ্রেমে একটি একক শর্তযুক্ত পরীক্ষা করার চেয়ে আরও ব্যয়বহুল, যেহেতু শাখার পূর্বাভাস সেই ক্ষেত্রে আর তার যাদু করতে পারে না। এর অর্থ 10 চক্রের ক্রমে নিয়মিত বিলম্ব - পাইপলাইন স্টল সমান উত্সাহ । নেস্টিং এই বুলিয়ান পতাকার উপরে বা নীচে ঘটতে পারে । কীভাবে জটিল গেম লুপগুলি দ্রুত হয়ে উঠতে পারে তা পাঠকদের খুব কমই মনে করিয়ে দেওয়া দরকার।

ফাংশন পয়েন্টার এই কারণে বিদ্যমান - তাদের ব্যবহার করুন!


1
আমরা একই লাইন বরাবর চিন্তা করছি। সবচেয়ে কার্যকর উপায় হ'ল যে কেউ কাজটি শেষ করে নিরলসভাবে কল করে চলে তার কাছ থেকে আপডেট () জিনিসটি সংযোগ বিচ্ছিন্ন করা, যা কিউটি স্টাইল সংকেত + স্লট সেটআপগুলিতে খুব সাধারণ। ওপি রানটাইম পরিবেশটি নির্দিষ্ট করে নি তাই যখন নির্দিষ্ট অপ্টিমাইজেশনের বিষয়টি আসে আমরা হ্যামস্ট্রং করি।
প্যাট্রিক হিউজেস

1

কিছু স্ক্রিপ্ট ভাষায় জাভাস্ক্রিপ্ট বা লুয়ার মতো সহজেই ফাংশন রেফারেন্সটি পরীক্ষা করা যায়। ইন অ্যাপ্লিকেশন Lua ( love2d ):

function ClickTheThing()
      .......
end
....

local ctt = ClickTheThing  --I make a local reference to function

.....

function update(dt)
..
    if ctt then
      ctt()
      ctt=nil
    end
..
end

0

একটি ভন নিউম্যান আর্কিটেকচার কম্পিউটার, মেমরি যেখানে আপনার প্রোগ্রামের নির্দেশাবলী এবং ডেটা সংরক্ষণ করা হয়। আপনি যদি কোডটি একবারে রান করতে চান তবে পদ্ধতিতে কোডটি NOP এর সাথে পদ্ধতিটি সম্পূর্ণ হওয়ার পরে পদ্ধতিটিতে ওভাররাইট করতে পারে। এই পদ্ধতিটি যদি আবার চালানো হয় তবে কিছুই হবে না।


6
এটি এমন কিছু আর্কিটেকচার ভেঙে দেবে যা রচনা প্রোগ্রামের স্মৃতি রক্ষা করে বা রম থেকে চালিত হয়। এটি ইনস্টল করা আছে তার উপর নির্ভর করে এলোমেলো অ্যান্টিভাইরাস সতর্কতাগুলিও বন্ধ করে দেবে।
প্যাট্রিক হিউজেস

0

পাইথনে যদি আপনার প্রকল্পের অন্যান্য লোকের কাছে ঝুঁকিপূর্ণ হওয়ার পরিকল্পনা রয়েছে:

code = compile('main code'+'del code', '<string>', 'exec')
exec code

এই স্ক্রিপ্টটি কোডটি অসুর করে তোলে:

from time import time as t

code = compile('del code', '<string>', 'exec')

print 'see code object:'
print code

while True:
    try:
        user = compile(raw_input('play with it (variable name is code) (type done to be done:\t'), '<user_input>', 'exec')
        exec user
    except BaseException as e:
        print e
        break

exec code

print 'no more code object:'
try:
    print code
except BaseException as e:
    print e

while True:
    try:
        user = compile(raw_input('try to play with it again (type done to be done:\t'), '<user_input>', 'exec')
        exec user
    except BaseException as e:
        print e
        break

0

এখানে আরও একটি অবদান রয়েছে, এটি কিছুটা সাধারণ / পুনরায় ব্যবহারযোগ্য, কিছুটা বেশি পঠনযোগ্য এবং রক্ষণাবেক্ষণযোগ্য তবে সম্ভবত অন্যান্য সমাধানগুলির চেয়ে কম দক্ষ।

আসুন আমাদের ক্লাসে একবার এক্সিকিউটিং লজিককে একবার, একবার:

class Once
{
    private Action body;
    public bool HasBeenCalled { get; private set; }
    public Once(Action body)
    {
        this.body = body;
    }
    public void Call()
    {
        if (!HasBeenCalled)
        {
            body();
        }
        HasBeenCalled = true;
    }
    public void Reset() { HasBeenCalled = false; }
}

এটি প্রদত্ত উদাহরণের মতো দেখায় যেমন:

Once clickTheThingOnce = new Once(ClickTheThing);

void Update() {
    if(mousebuttonpressed) {
        clickTheThingOnce.Call(); // ClickTheThing is only called once
                                  // or until .Reset() is called
    }
}

0

আপনি স্থির একটি পরিবর্তনশীল ব্যবহার বিবেচনা করতে পারেন।

void doOnce()
{
   static bool executed = false;

   if(executed == false)
   {
      ...Your code here
      executed = true;
   }
}

আপনি ClickTheThing()নিজে এটি ফাংশনে এটি করতে পারেন, বা অন্য ফাংশন তৈরি করতে এবং ClickTheThing()যদি বডি এ কল করতে পারেন।

এটি অন্যান্য সমাধানে প্রস্তাবিত একটি পতাকা ব্যবহারের ধারণার মতো, তবে পতাকাটি অন্য কোড থেকে সুরক্ষিত এবং ফাংশনে স্থানীয় হওয়ার কারণে অন্য কোথাও পরিবর্তন করা যায় না।


1
... তবে এটি আপনাকে একবার 'প্রতি বস্তু হিসাবে' কোড চালানো থেকে বিরত রাখে। (যদি এটি ব্যবহারকারীর প্রয়োজন হয় তবে ..;))
ভায়ল্যানকোর্ট

0

আমি আসলে এক্সবক্স কন্ট্রোলার ইনপুট নিয়ে এই দ্বিধাটি পেরিয়ে এসেছি। যদিও একেবারে একই নয় তবে এটি প্রায় একই রকম। আপনার প্রয়োজন অনুসারে আপনি আমার উদাহরণে কোডটি পরিবর্তন করতে পারেন।

সম্পাদনা করুন: আপনার পরিস্থিতি এটি -> ব্যবহার করবে

https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagrawmouse

এবং আপনি -> এর মাধ্যমে কীভাবে কোনও কাঁচা ইনপুট শ্রেণি তৈরি করবেন তা শিখতে পারেন

https://docs.microsoft.com/en-us/windows/desktop/inputdev/raw-input

তবে .. এখন সুপার অসাধারণ অ্যালগরিদমের ... সত্যই নয়, আরে .. এটি বেশ দুর্দান্ত :)

* সুতরাং ... আমরা প্রতিটি বোতামের রাজ্যগুলি সংরক্ষণ করতে পারি এবং যা চাপ, মুক্তি এবং হোল্ড ডাউন রয়েছে !!! আমরা হোল্ডিংয়ের সময়টিও যাচাই করতে পারি, তবে এটির জন্য যদি একক বিবৃতি প্রয়োজন হয় এবং যে কোনও সংখ্যক বোতাম চেক করতে পারে তবে এই তথ্যের জন্য নীচে কিছু নিয়ম দেখুন।

স্পষ্টতই যদি আমরা কিছু চাপা, প্রকাশ করা ইত্যাদি ইত্যাদি পরীক্ষা করতে চাই তবে আপনি "যদি (এটি) {}" করেন তবে এটি আমাদের প্রেস স্টেটটি কীভাবে পেতে পারে এবং তারপরে এটি পরবর্তী ফ্রেমটি বন্ধ করে দিতে পারে তাই আপনার " পরের বার আপনি যাচাই করবেন তখন সত্যই মিথ্যা হবে m

এখানে সম্পূর্ণ কোড: https://github.com/JeremyDX/DX_B/blob/master/DX_B/XGameInput.cpp

কিভাবে এটা কাজ করে..

সুতরাং আমি নিশ্চিত নই যে আপনি যখন একটি বোতাম টিপে টিপে চাপছেন বা না তা চিত্রিত করার সময় আপনি যে মানগুলি পেয়েছেন, তবে মূলত আমি যখন এক্সআইনপুট লোড করি তখন আমি 0 থেকে 65535 এর মধ্যে একটি 16 বিট মান পাই এটিতে "চাপা" জন্য 15 বিট সম্ভাব্য রাজ্য রয়েছে।

সমস্যাটি যখনই আমি এটি যাচাই করেছিলাম তখন এটি আমাকে তথ্যের বর্তমান অবস্থা দেয় give আমার বর্তমান রাষ্ট্রকে চাপ দেওয়া, প্রকাশিত এবং হোল্ড মানগুলিতে রূপান্তর করার জন্য একটি উপায়ের দরকার ছিল।

সুতরাং আমি যা করেছি তা নীচে রয়েছে।

প্রথমে আমরা একটি "কারেন্ট" ভেরিয়েবল তৈরি করি। প্রতিবার আমরা এই ডেটাটি যাচাই করি আমরা "বর্তমান" কে একটি "পূর্ববর্তী" পরিবর্তনশীলতে সেট করি এবং তারপরে এখানে দেখা হিসাবে নতুন তথ্য "বর্তমান" এ সঞ্চয় করি ->

uint64_t LAST = CURRENT;
CURRENT = gamepad.wButtons;

এই তথ্যের সাথে এখানে এটি আকর্ষণীয় হয় !!

এখন আমরা বুঝতে পারি যে কোনও বোতামটি নীচে রাখা হচ্ছে কিনা!

BUTTONS_HOLD = LAST & CURRENT;

এটি যা করে তা মূলত এটি দুটি মানগুলির সাথে তুলনা করে এবং উভয় প্রদর্শিত যে কোনও বোতাম প্রেসগুলি 1 টি থাকবে এবং সমস্ত কিছু 0 তে সেট থাকবে।

অর্থাত (1 | 2 | 4) এবং (2 | 4 | 8) ফল দেবে (2 | 4)।

এখন আমাদের কাছে কোন বোতামগুলি "হেলড" ডাউন আছে। আমরা বাকি পেতে পারি।

চেপে রাখা সহজ .. আমরা আমাদের "বর্তমান" অবস্থা গ্রহণ করি এবং যে কোনও হোল্ড ডাউন বোতাম সরিয়ে ফেলি।

BUTTONS_PRESSED = CURRENT ^ BUTTONS_HOLD;

প্রকাশিত হ'ল কেবলমাত্র আমরা এর পরিবর্তে আমাদের লাস্ট স্টেটের সাথে এটি তুলনা করি।

BUTTONS_RELEASED = LAST ^ BUTTONS_HOLD;

তাই চাপা পরিস্থিতি দেখে। যদি ধরা যাক বর্তমানে আমাদের 2 ছিল | 4 | 8 টিপে। আমরা খুঁজে পেয়েছি যে 2 | 4 যেখানে অনুষ্ঠিত। যখন আমরা হেল্ড বিটগুলি সরিয়ে ফেলি তখন আমরা কেবল 8 টি রেখে আসি This এটি এই চক্রটির জন্য নতুন চাপানো বিট।

একই রিলিজের জন্য আবেদন করা যেতে পারে। এই পরিস্থিতিতে "শেষ" সেট করা হয়েছিল 1 | 2 | 4. সুতরাং আমরা 2 অপসারণ যখন 4 বিট। আমরা 1 দিয়ে রেখেছি 1 সুতরাং বোতামটি 1 শেষ ফ্রেম থেকে প্রকাশিত হয়েছিল।

এই উপরের দৃশ্যটি সম্ভবত আপনি সবচেয়ে বিস্তৃত তুলনার জন্য প্রস্তাব করতে পারেন এবং এটি বিবৃতি বা লুপের জন্য মাত্র 3 দ্রুত বিট গণনার জন্য 3 স্তরের ডেটা সরবরাহ করে।

আমি হোল্ড ডেটাও ডকুমেন্ট করতে চেয়েছিলাম যাতে আমার পরিস্থিতি নিখুঁত না হলেও ... এটি কী করে তা আমরা মূলত আমাদের যাচাই করতে চাই তা সেট করে।

সুতরাং প্রতিবার আমরা যখন আমাদের প্রেস / রিলিজ / হোল্ড ডেটা সেট করি আমরা তখনও পরীক্ষা করে থাকি যে হোল্ড ডেটা এখনও বর্তমান হোল্ড বিট চেকের সমান কিনা। যদি এটি না হয় তবে বর্তমান সময়টিতে এটি পুনরায় সেট করুন। আমার ক্ষেত্রে আমি এটি ফ্রেম সূচীতে সেট করছি তাই আমি জানি এটির জন্য কতগুলি ফ্রেম রাখা হয়েছে down

এই পদ্ধতির খারাপ দিকটি হ'ল আমি স্বতন্ত্র হোল্ড টাইম পেতে পারি না তবে আপনি একবারে একাধিক বিট পরীক্ষা করতে পারেন। আমি যদি হোল্ড বিটটি 1 এ সেট করে রাখি 16 যদি হয় 1 বা 16 না রাখা হয় তবে এটি ব্যর্থ হবে। সুতরাং এটি টিকিং চালিয়ে যাওয়ার জন্য এই সমস্ত বোতামটি চেপে ধরে রাখা দরকার।

তারপরে আপনি কোডটি সন্ধান করলে আপনি সমস্ত ঝরঝরে ফাংশন কল দেখতে পাবেন।

সুতরাং আপনার উদাহরণটি কেবল এই অ্যালগরিদম দিয়ে একটি বোতাম টিপ হয়েছে এবং একটি বোতাম প্রেস কেবল একবার ঘটতে পারে কিনা তা খতিয়ে দেখার জন্য হ্রাস পাবে। পরের চেক টিপতে এটি উপস্থিত থাকবে না যেহেতু আপনি আরও টিপতে পারবেন না একবার আবার চাপ দেওয়ার আগে আপনাকে মুক্তি দিতে হবে।


সুতরাং আপনি মূলত একটি বুলের পরিবর্তে একটি বিটফিল্ড অন্যান্য উত্তরগুলিতে বর্ণিত হিসাবে ব্যবহার করেন?
ভায়ল্যানকোর্ট

হ্যাঁ বেশ লোল ..
জেরেমি ত্রিফিলো

এটি তার প্রয়োজনীয়তার জন্য ব্যবহার করা যেতে পারে যদিও নীচের এমএসডিএন কাঠামোর সাথে "ইউএসবাটনফ্লাগস" এ সমস্ত বোতামের অবস্থার একক মান রয়েছে contains ডকস.মাইক্রোসফট.ইন- ইউএস
জেরেমি ত্রিফিলো

যদিও আমি নিশ্চিত না যে কন্ট্রোলার বোতামগুলি সম্পর্কে এগুলি বলার প্রয়োজনীয়তাটি কোথা থেকে এসেছে। উত্তরের মূল বিষয়বস্তু অনেকগুলি বিভ্রান্তিকর পাঠ্যের নীচে লুকিয়ে রয়েছে।
ভায়ল্যানকোর্ট

হ্যাঁ আমি কেবলমাত্র একটি সম্পর্কিত ব্যক্তিগত দৃশ্য দিচ্ছিলাম এবং এটি সম্পাদন করার জন্য আমি কী করেছি। আমি অবশ্যই এটি পরে পরিষ্কার করে নেব এবং সম্ভবত আমি কীবোর্ড এবং মাউস ইনপুট যুক্ত করব এবং সেদিকে একটি দৃষ্টিভঙ্গি দেব।
জেরেমি ত্রিফিলো

-3

বোকা সস্তা উপায় কিন্তু আপনি লুপ জন্য ব্যবহার করতে পারে

for (int i = 0; i < 1; i++)
{
    //code here
}

লুপটিতে কোডটি সর্বদা কার্যকর করা হবে যখন লুপটি চালানো হবে। কোনও কিছুই কোড একবার সম্পাদন হতে বাধা দিচ্ছে না। লুপ বা কোনও লুপ ঠিক একই ফলাফল দেয় same
ভায়ল্যানকোর্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.