本文整理汇总了C++中common::FifoQueue类的典型用法代码示例。如果您正苦于以下问题:C++ FifoQueue类的具体用法?C++ FifoQueue怎么用?C++ FifoQueue使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了FifoQueue类的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: tie
namespace CoreTiming
{
struct EventType
{
TimedCallback callback;
const std::string* name;
};
struct Event
{
s64 time;
u64 fifo_order;
u64 userdata;
EventType* type;
};
// Sort by time, unless the times are the same, in which case sort by the order added to the queue
static bool operator>(const Event& left, const Event& right)
{
return std::tie(left.time, left.fifo_order) > std::tie(right.time, right.fifo_order);
}
static bool operator<(const Event& left, const Event& right)
{
return std::tie(left.time, left.fifo_order) < std::tie(right.time, right.fifo_order);
}
// unordered_map stores each element separately as a linked list node so pointers to elements
// remain stable regardless of rehashes/resizing.
static std::unordered_map<std::string, EventType> s_event_types;
// STATE_TO_SAVE
// The queue is a min-heap using std::make_heap/push_heap/pop_heap.
// We don't use std::priority_queue because we need to be able to serialize, unserialize and
// erase arbitrary events (RemoveEvent()) regardless of the queue order. These aren't accomodated
// by the standard adaptor class.
static std::vector<Event> s_event_queue;
static u64 s_event_fifo_id;
static std::mutex s_ts_write_lock;
static Common::FifoQueue<Event, false> s_ts_queue;
static float s_last_OC_factor;
float g_last_OC_factor_inverted;
int g_slice_length;
static constexpr int MAX_SLICE_LENGTH = 20000;
static s64 s_idled_cycles;
static u32 s_fake_dec_start_value;
static u64 s_fake_dec_start_ticks;
// Are we in a function that has been called from Advance()
static bool s_is_global_timer_sane;
s64 g_global_timer;
u64 g_fake_TB_start_value;
u64 g_fake_TB_start_ticks;
static EventType* s_ev_lost = nullptr;
static void EmptyTimedCallback(u64 userdata, s64 cyclesLate)
{
}
// Changing the CPU speed in Dolphin isn't actually done by changing the physical clock rate,
// but by changing the amount of work done in a particular amount of time. This tends to be more
// compatible because it stops the games from actually knowing directly that the clock rate has
// changed, and ensures that anything based on waiting a specific number of cycles still works.
//
// Technically it might be more accurate to call this changing the IPC instead of the CPU speed,
// but the effect is largely the same.
static int DowncountToCycles(int downcount)
{
return static_cast<int>(downcount * g_last_OC_factor_inverted);
}
static int CyclesToDowncount(int cycles)
{
return static_cast<int>(cycles * s_last_OC_factor);
}
EventType* RegisterEvent(const std::string& name, TimedCallback callback)
{
// check for existing type with same name.
// we want event type names to remain unique so that we can use them for serialization.
_assert_msg_(POWERPC, s_event_types.find(name) == s_event_types.end(),
"CoreTiming Event \"%s\" is already registered. Events should only be registered "
"during Init to avoid breaking save states.",
name.c_str());
auto info = s_event_types.emplace(name, EventType{callback, nullptr});
EventType* event_type = &info.first->second;
event_type->name = &info.first->first;
return event_type;
}
void UnregisterAllEvents()
{
_assert_msg_(POWERPC, s_event_queue.empty(), "Cannot unregister events with events pending");
s_event_types.clear();
}
//.........这里部分代码省略.........
示例2: void
namespace CoreTiming
{
struct EventType
{
TimedCallback callback;
std::string name;
};
static std::vector<EventType> event_types;
struct BaseEvent
{
s64 time;
u64 userdata;
int type;
};
typedef LinkedListItem<BaseEvent> Event;
// STATE_TO_SAVE
static Event *first;
static std::mutex tsWriteLock;
static Common::FifoQueue<BaseEvent, false> tsQueue;
// event pools
static Event *eventPool = nullptr;
int slicelength;
static int maxSliceLength = MAX_SLICE_LENGTH;
static s64 globalTimer;
static s64 idledCycles;
static u32 fakeDecStartValue;
static u64 fakeDecStartTicks;
static u64 fakeTBStartValue;
static u64 fakeTBStartTicks;
static int ev_lost;
static void (*advanceCallback)(int cyclesExecuted) = nullptr;
static Event* GetNewEvent()
{
if (!eventPool)
return new Event;
Event* ev = eventPool;
eventPool = ev->next;
return ev;
}
static void FreeEvent(Event* ev)
{
ev->next = eventPool;
eventPool = ev;
}
static void EmptyTimedCallback(u64 userdata, int cyclesLate) {}
int RegisterEvent(const std::string& name, TimedCallback callback)
{
EventType type;
type.name = name;
type.callback = callback;
// check for existing type with same name.
// we want event type names to remain unique so that we can use them for serialization.
for (auto& event_type : event_types)
{
if (name == event_type.name)
{
WARN_LOG(POWERPC, "Discarded old event type \"%s\" because a new type with the same name was registered.", name.c_str());
// we don't know if someone might be holding on to the type index,
// so we gut the old event type instead of actually removing it.
event_type.name = "_discarded_event";
event_type.callback = &EmptyTimedCallback;
}
}
event_types.push_back(type);
return (int)event_types.size() - 1;
}
void UnregisterAllEvents()
{
if (first)
PanicAlertT("Cannot unregister events with events pending");
event_types.clear();
}
void Init()
{
PowerPC::ppcState.downcount = maxSliceLength;
slicelength = maxSliceLength;
globalTimer = 0;
idledCycles = 0;
//.........这里部分代码省略.........
示例3: GetNewEvent
namespace CoreTiming
{
struct EventType
{
TimedCallback callback;
std::string name;
};
static std::vector<EventType> event_types;
struct BaseEvent
{
s64 time;
u64 userdata;
int type;
};
typedef LinkedListItem<BaseEvent> Event;
// STATE_TO_SAVE
static Event *first;
static std::mutex tsWriteLock;
static Common::FifoQueue<BaseEvent, false> tsQueue;
// event pools
static Event *eventPool = nullptr;
static float s_lastOCFactor;
float g_lastOCFactor_inverted;
int g_slicelength;
static int maxslicelength = MAX_SLICE_LENGTH;
static s64 idledCycles;
static u32 fakeDecStartValue;
static u64 fakeDecStartTicks;
// Are we in a function that has been called from Advance()
static bool globalTimerIsSane;
s64 g_globalTimer;
u64 g_fakeTBStartValue;
u64 g_fakeTBStartTicks;
static int ev_lost;
static Event* GetNewEvent()
{
if (!eventPool)
return new Event;
Event* ev = eventPool;
eventPool = ev->next;
return ev;
}
static void FreeEvent(Event* ev)
{
ev->next = eventPool;
eventPool = ev;
}
static void EmptyTimedCallback(u64 userdata, s64 cyclesLate) {}
// Changing the CPU speed in Dolphin isn't actually done by changing the physical clock rate,
// but by changing the amount of work done in a particular amount of time. This tends to be more
// compatible because it stops the games from actually knowing directly that the clock rate has
// changed, and ensures that anything based on waiting a specific number of cycles still works.
//
// Technically it might be more accurate to call this changing the IPC instead of the CPU speed,
// but the effect is largely the same.
static int DowncountToCycles(int downcount)
{
return (int)(downcount * g_lastOCFactor_inverted);
}
static int CyclesToDowncount(int cycles)
{
return (int)(cycles * s_lastOCFactor);
}
int RegisterEvent(const std::string& name, TimedCallback callback)
{
EventType type;
type.name = name;
type.callback = callback;
// check for existing type with same name.
// we want event type names to remain unique so that we can use them for serialization.
for (auto& event_type : event_types)
{
if (name == event_type.name)
{
WARN_LOG(POWERPC, "Discarded old event type \"%s\" because a new type with the same name was registered.", name.c_str());
// we don't know if someone might be holding on to the type index,
// so we gut the old event type instead of actually removing it.
event_type.name = "_discarded_event";
event_type.callback = &EmptyTimedCallback;
}
}
//.........这里部分代码省略.........
示例4: ScheduleEvent_Threadsafe
// This is to be called when outside threads, such as the graphics thread, wants to
// schedule things to be executed on the main thread.
void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata)
{
std::lock_guard<std::mutex> lk(tsWriteLock);
Event ne;
ne.time = globalTimer + cyclesIntoFuture;
ne.type = event_type;
ne.userdata = userdata;
tsQueue.Push(ne);
}
示例5: MoveEvents
void MoveEvents()
{
for (Event ev; s_ts_queue.Pop(ev);)
{
ev.fifo_order = s_event_fifo_id++;
s_event_queue.emplace_back(std::move(ev));
std::push_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>());
}
}
示例6: MoveEvents
void MoveEvents()
{
BaseEvent sevt;
while (tsQueue.Pop(sevt))
{
Event *evt = GetNewEvent();
evt->time = sevt.time;
evt->userdata = sevt.userdata;
evt->type = sevt.type;
AddEventToQueue(evt);
}
}
示例7: ScheduleEvent_Threadsafe
// This is to be called when outside threads, such as the graphics thread, wants to
// schedule things to be executed on the main thread.
void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata)
{
_assert_msg_(POWERPC, !Core::IsCPUThread(), "ScheduleEvent_Threadsafe from wrong thread");
if (Core::g_want_determinism)
{
ERROR_LOG(POWERPC, "Someone scheduled an off-thread \"%s\" event while netplay or movie play/record "
"was active. This is likely to cause a desync.",
event_types[event_type].name.c_str());
}
std::lock_guard<std::mutex> lk(tsWriteLock);
Event ne;
ne.time = g_globalTimer + cyclesIntoFuture;
ne.type = event_type;
ne.userdata = userdata;
tsQueue.Push(ne);
}
示例8: ScheduleEvent
void ScheduleEvent(s64 cycles_into_future, EventType* event_type, u64 userdata, FromThread from)
{
_assert_msg_(POWERPC, event_type, "Event type is nullptr, will crash now.");
bool from_cpu_thread;
if (from == FromThread::ANY)
{
from_cpu_thread = Core::IsCPUThread();
}
else
{
from_cpu_thread = from == FromThread::CPU;
_assert_msg_(POWERPC, from_cpu_thread == Core::IsCPUThread(),
"ScheduleEvent from wrong thread (%s)", from_cpu_thread ? "CPU" : "non-CPU");
}
if (from_cpu_thread)
{
s64 timeout = GetTicks() + cycles_into_future;
// If this event needs to be scheduled before the next advance(), force one early
if (!s_is_global_timer_sane)
ForceExceptionCheck(cycles_into_future);
s_event_queue.emplace_back(Event{timeout, s_event_fifo_id++, userdata, event_type});
std::push_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>());
}
else
{
if (Core::g_want_determinism)
{
ERROR_LOG(POWERPC, "Someone scheduled an off-thread \"%s\" event while netplay or "
"movie play/record was active. This is likely to cause a desync.",
event_type->name->c_str());
}
std::lock_guard<std::mutex> lk(s_ts_write_lock);
s_ts_queue.Push(Event{g_global_timer + cycles_into_future, 0, userdata, event_type});
}
}