2016-02-26 3 views
0

Я пишу движок игры на C++. Сейчас у меня есть класс GameListener, который имеет некоторые методы обратного вызова в игровом состоянии (например, update(), start(), awake()). Таким образом, GameObject должен реализовать любой из них, чтобы фактически быть GameObject. Это очень похоже на Unity3D.Зарегистрировать внедренные методы в C++

Проблема заключается в том, реализует ли какой-либо метод GameObject, он вызывается двигателем. Поэтому я могу получить пустые пустые методы, по сути ничего не делая. Как я могу избежать этого? Как-то зарегистрировать все методы, которые были реализованы, и вызвать их. В моей gameloop у меня есть что-то вроде этого (псевдокод):

for all gamelisteners do: 
gamelistener.awake(); 
gamelistener.update(); 
gamelistener.another_some_callback_method(); 
... 

Это не проблема, если у меня есть небольшое количество gamelisteners и методов обратного вызова. Но что, если у меня есть, скажем, 200 gamelisteners и 10 методов обратного вызова в интерфейсе GameListener. Не все gamelisteners реализуют все эти 10 методов обратного вызова, так что опять же я получаю кучу пустых методов, которые вызывают в gameloop.

Я слышал, что в C# это как-то может быть разрешено с отражениями (см., Какие методы были фактически реализованы, и называть только их). Как я могу решить это в C++?

+0

С [C++ 11] (https://en.wikipedia.org/wiki/C%2B%2B11) можно использовать [лямбда-выражения] (http://en.cppreference.com/w/cpp/language/lambda) & [std :: function] (http://en.cppreference.com/w/cpp/utility/functional/function). Но ваш вопрос слишком широк или неясен. –

+2

Знаете ли вы, что ничего не делать слишком дорого или вы предполагаете, что это будет? Возможно, вы пытаетесь оптимизировать слишком рано. –

+0

«Итак, GameObject должен реализовать любой из них, чтобы на самом деле быть GameObject' ---> вы имеете в виду« или »или« все ». – Prab

ответ

0

Одна из реализаций, которые у меня есть, состоит в том, что у меня есть структура указателей функций, которые «исполнитель» (в вашем случае GameObject) должен реализовывать и регистрировать эти указатели функций в основной структуре (GameEngine).

Итак, если разработчик регистрирует nullptr для конкретного обратного вызова, тогда структура должна пропускать инфиницию этого исполнителя об этом событии.

С другой стороны, если у вас есть обязательный обратный вызов, который должен быть реализован, то Gameengine не должно позволять геймобжектам быть зарегистрированы с ним, если он не реализует те ..

using callback_defn1 = std::function<void()>; 
using callback_defn2 = std::function<void(int)>; 

struct gameengine_callbacks { 
    callback_defn1 mandatory_callback1; 
    callback_defn1 mandatory_callback2; 
    callback_defn2 optional_callback1; 
}; 

И GameEngine что-то как

void GameEngine::register_objects(gameengine_callbacks callbacks) 
{ 
    if (callbacks.mandatory_callback1 == nullptr or callbacks.mandatory_callback1 == nullptr) 
    { 
     throw std::invalid_argument("some msg"); 
    } 
    // Proceed with your registration. 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^