forked from metin2/server
Add project files.
This commit is contained in:
218
game/src/event.cpp
Normal file
218
game/src/event.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Filename: event.c
|
||||
* Description: <20>̺<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> (timed event)
|
||||
*
|
||||
* Author: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (aka. <20><><EFBFBD><EFBFBD>, Cronan), <20>ۿ<EFBFBD><DBBF><EFBFBD> (aka. myevan, <20><><EFBFBD>ڷ<EFBFBD>)
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "event_queue.h"
|
||||
|
||||
extern void ContinueOnFatalError();
|
||||
extern void ShutdownOnFatalError();
|
||||
|
||||
#ifdef M2_USE_POOL
|
||||
MemoryPool event_info_data::pool_;
|
||||
static ObjectPool<EVENT> event_pool;
|
||||
#endif
|
||||
|
||||
static CEventQueue cxx_q;
|
||||
|
||||
/* <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD> */
|
||||
LPEVENT event_create_ex(TEVENTFUNC func, event_info_data* info, long when)
|
||||
{
|
||||
LPEVENT new_event = NULL;
|
||||
|
||||
/* <20>ݵ<EFBFBD><DDB5><EFBFBD> <20><><EFBFBD><EFBFBD> pulse <20>̻<EFBFBD><CCBB><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ŀ<EFBFBD> <20>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>. */
|
||||
if (when < 1)
|
||||
when = 1;
|
||||
|
||||
#ifdef M2_USE_POOL
|
||||
new_event = event_pool.Construct();
|
||||
#else
|
||||
new_event = M2_NEW event;
|
||||
#endif
|
||||
|
||||
assert(NULL != new_event);
|
||||
|
||||
new_event->func = func;
|
||||
new_event->info = info;
|
||||
new_event->q_el = cxx_q.Enqueue(new_event, when, thecore_heart->pulse);
|
||||
new_event->is_processing = FALSE;
|
||||
new_event->is_force_to_end = FALSE;
|
||||
|
||||
return (new_event);
|
||||
}
|
||||
|
||||
/* <20>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD> */
|
||||
void event_cancel(LPEVENT * ppevent)
|
||||
{
|
||||
LPEVENT event;
|
||||
|
||||
if (!ppevent)
|
||||
{
|
||||
sys_err("null pointer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event = *ppevent))
|
||||
return;
|
||||
|
||||
if (event->is_processing)
|
||||
{
|
||||
event->is_force_to_end = TRUE;
|
||||
|
||||
if (event->q_el)
|
||||
event->q_el->bCancel = TRUE;
|
||||
|
||||
*ppevent = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE>°<EFBFBD>?
|
||||
if (!event->q_el)
|
||||
{
|
||||
*ppevent = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (event->q_el->bCancel)
|
||||
{
|
||||
*ppevent = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
event->q_el->bCancel = TRUE;
|
||||
|
||||
*ppevent = NULL;
|
||||
}
|
||||
|
||||
void event_reset_time(LPEVENT event, long when)
|
||||
{
|
||||
if (!event->is_processing)
|
||||
{
|
||||
if (event->q_el)
|
||||
event->q_el->bCancel = TRUE;
|
||||
|
||||
event->q_el = cxx_q.Enqueue(event, when, thecore_heart->pulse);
|
||||
}
|
||||
}
|
||||
|
||||
/* <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD> */
|
||||
int event_process(int pulse)
|
||||
{
|
||||
long new_time;
|
||||
int num_events = 0;
|
||||
|
||||
// event_q <20><> <20>̺<EFBFBD>Ʈ ť<><C5A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pulse <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20>ȴ<EFBFBD>.
|
||||
while (pulse >= cxx_q.GetTopKey())
|
||||
{
|
||||
TQueueElement * pElem = cxx_q.Dequeue();
|
||||
|
||||
if (pElem->bCancel)
|
||||
{
|
||||
cxx_q.Delete(pElem);
|
||||
continue;
|
||||
}
|
||||
|
||||
new_time = pElem->iKey;
|
||||
|
||||
LPEVENT the_event = pElem->pvData;
|
||||
long processing_time = event_processing_time(the_event);
|
||||
cxx_q.Delete(pElem);
|
||||
|
||||
/*
|
||||
* <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD> <20>ð<EFBFBD><C3B0≯<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0 <20><><EFBFBD><EFBFBD> Ŭ <20><><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20>ٽ<EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
|
||||
* <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0 <20>̻<EFBFBD><CCBB><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> event <20><> <20>Ҵ<EFBFBD><D2B4><EFBFBD> <20><EFBFBD><DEB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʵ<EFBFBD><CAB5><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
*/
|
||||
the_event->is_processing = TRUE;
|
||||
|
||||
if (!the_event->info)
|
||||
{
|
||||
the_event->q_el = NULL;
|
||||
ContinueOnFatalError();
|
||||
}
|
||||
else
|
||||
{
|
||||
//sys_log(0, "EVENT: %s %d event %p info %p", the_event->file, the_event->line, the_event, the_event->info);
|
||||
new_time = (the_event->func) (get_pointer(the_event), processing_time);
|
||||
|
||||
if (new_time <= 0 || the_event->is_force_to_end)
|
||||
{
|
||||
the_event->q_el = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
the_event->q_el = cxx_q.Enqueue(the_event, new_time, pulse);
|
||||
the_event->is_processing = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
++num_events;
|
||||
}
|
||||
|
||||
return num_events;
|
||||
}
|
||||
|
||||
/* <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ð<EFBFBD><C3B0><EFBFBD> pulse <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD> */
|
||||
long event_processing_time(LPEVENT event)
|
||||
{
|
||||
long start_time;
|
||||
|
||||
if (!event->q_el)
|
||||
return 0;
|
||||
|
||||
start_time = event->q_el->iStartTime;
|
||||
return (thecore_heart->pulse - start_time);
|
||||
}
|
||||
|
||||
/* <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> pulse <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD> */
|
||||
long event_time(LPEVENT event)
|
||||
{
|
||||
long when;
|
||||
|
||||
if (!event->q_el)
|
||||
return 0;
|
||||
|
||||
when = event->q_el->iKey;
|
||||
return (when - thecore_heart->pulse);
|
||||
}
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD> */
|
||||
void event_destroy(void)
|
||||
{
|
||||
TQueueElement * pElem;
|
||||
|
||||
while ((pElem = cxx_q.Dequeue()))
|
||||
{
|
||||
LPEVENT the_event = (LPEVENT) pElem->pvData;
|
||||
|
||||
if (!pElem->bCancel)
|
||||
{
|
||||
// no op here
|
||||
}
|
||||
|
||||
cxx_q.Delete(pElem);
|
||||
}
|
||||
}
|
||||
|
||||
int event_count()
|
||||
{
|
||||
return cxx_q.Size();
|
||||
}
|
||||
|
||||
void intrusive_ptr_add_ref(EVENT* p) {
|
||||
++(p->ref_count);
|
||||
}
|
||||
|
||||
void intrusive_ptr_release(EVENT* p) {
|
||||
if ( --(p->ref_count) == 0 ) {
|
||||
#ifdef M2_USE_POOL
|
||||
event_pool.Destroy(p);
|
||||
#else
|
||||
M2_DELETE(p);
|
||||
#endif
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user