Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
69
Src/timer/Factory.cpp
Normal file
69
Src/timer/Factory.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include "Factory.h"
|
||||
#include "api.h"
|
||||
#include "timerapi.h"
|
||||
|
||||
TimerApi *timer_svc = 0;
|
||||
static const char serviceName[] = "Timer Service";
|
||||
|
||||
void Factory::Stop()
|
||||
{
|
||||
delete timer_svc;
|
||||
timer_svc=0;
|
||||
}
|
||||
FOURCC Factory::GetServiceType()
|
||||
{
|
||||
return WaSvc::UNIQUE;
|
||||
}
|
||||
|
||||
const char *Factory::GetServiceName()
|
||||
{
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
GUID Factory::GetGUID()
|
||||
{
|
||||
return timerApiServiceGuid;
|
||||
}
|
||||
|
||||
void *Factory::GetInterface(int global_lock)
|
||||
{
|
||||
if (!timer_svc)
|
||||
timer_svc = new TimerApi;
|
||||
// if (global_lock)
|
||||
// WASABI_API_SVC->service_lock(this, (void *)ifc);
|
||||
return timer_svc;
|
||||
}
|
||||
|
||||
int Factory::SupportNonLockingInterface()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Factory::ReleaseInterface(void *ifc)
|
||||
{
|
||||
//WASABI_API_SVC->service_unlock(ifc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *Factory::GetTestString()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Factory::ServiceNotify(int msg, int param1, int param2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CBCLASS Factory
|
||||
START_DISPATCH;
|
||||
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
|
||||
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
|
||||
CB(WASERVICEFACTORY_GETGUID, GetGUID)
|
||||
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
|
||||
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
|
||||
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
|
||||
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
|
||||
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
24
Src/timer/Factory.h
Normal file
24
Src/timer/Factory.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "api.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
#include <api/service/services.h>
|
||||
|
||||
class Factory : public waServiceFactory
|
||||
{
|
||||
public:
|
||||
FOURCC GetServiceType();
|
||||
const char *GetServiceName();
|
||||
GUID GetGUID();
|
||||
void *GetInterface(int global_lock);
|
||||
int SupportNonLockingInterface();
|
||||
int ReleaseInterface(void *ifc);
|
||||
const char *GetTestString();
|
||||
int ServiceNotify(int msg, int param1, int param2);
|
||||
void Stop();
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
68
Src/timer/ScriptFactory.cpp
Normal file
68
Src/timer/ScriptFactory.cpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include "ScriptFactory.h"
|
||||
#include "api.h"
|
||||
#include "ScriptObjectService.h"
|
||||
|
||||
static ScriptObjectService svc;
|
||||
static const char serviceName[] = "Timer Maki Object";
|
||||
|
||||
// GUID of our service factory, not the GUID of the maki object
|
||||
// {538A1D71-74B0-4fbf-877A-241D10A937F3}
|
||||
static const GUID timer_maki_guid =
|
||||
{ 0x538a1d71, 0x74b0, 0x4fbf, { 0x87, 0x7a, 0x24, 0x1d, 0x10, 0xa9, 0x37, 0xf3 } };
|
||||
|
||||
|
||||
FOURCC ScriptFactory::GetServiceType()
|
||||
{
|
||||
return svc.getServiceType();
|
||||
}
|
||||
|
||||
const char *ScriptFactory::GetServiceName()
|
||||
{
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
GUID ScriptFactory::GetGUID()
|
||||
{
|
||||
return timer_maki_guid;
|
||||
}
|
||||
|
||||
void *ScriptFactory::GetInterface(int global_lock)
|
||||
{
|
||||
// if (global_lock)
|
||||
// WASABI_API_SVC->service_lock(this, (void *)ifc);
|
||||
return &svc;
|
||||
}
|
||||
|
||||
int ScriptFactory::SupportNonLockingInterface()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ScriptFactory::ReleaseInterface(void *ifc)
|
||||
{
|
||||
//WASABI_API_SVC->service_unlock(ifc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *ScriptFactory::GetTestString()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ScriptFactory::ServiceNotify(int msg, int param1, int param2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CBCLASS ScriptFactory
|
||||
START_DISPATCH;
|
||||
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
|
||||
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
|
||||
CB(WASERVICEFACTORY_GETGUID, GetGUID)
|
||||
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
|
||||
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
|
||||
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
|
||||
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
|
||||
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
24
Src/timer/ScriptFactory.h
Normal file
24
Src/timer/ScriptFactory.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "api.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
#include <api/service/services.h>
|
||||
|
||||
class ScriptFactory : public waServiceFactory
|
||||
{
|
||||
public:
|
||||
FOURCC GetServiceType();
|
||||
const char *GetServiceName();
|
||||
GUID GetGUID();
|
||||
void *GetInterface(int global_lock);
|
||||
int SupportNonLockingInterface();
|
||||
int ReleaseInterface(void *ifc);
|
||||
const char *GetTestString();
|
||||
int ServiceNotify(int msg, int param1, int param2);
|
||||
void Stop();
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
29
Src/timer/ScriptObjectService.cpp
Normal file
29
Src/timer/ScriptObjectService.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include "ScriptObjectService.h"
|
||||
#include <api/script/objects/rootobjcontroller.h>
|
||||
#include "STimer.h"
|
||||
|
||||
ScriptObjectController *script_root=0;
|
||||
extern TimerScriptController _timerController;
|
||||
|
||||
|
||||
ScriptObjectController *ScriptObjectService::getController(int n)
|
||||
{
|
||||
if (n == 0)
|
||||
return &_timerController;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ScriptObjectService::onRegisterClasses(ScriptObjectController *rootController)
|
||||
{
|
||||
script_root = rootController;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CBCLASS ScriptObjectService
|
||||
START_DISPATCH;
|
||||
CB(GETCONTROLLER, getController);
|
||||
VCB(ONREGISTER, onRegisterClasses);
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
11
Src/timer/ScriptObjectService.h
Normal file
11
Src/timer/ScriptObjectService.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include <api/service/svcs/svc_scriptobj.h>
|
||||
|
||||
class ScriptObjectService : public svc_scriptObject
|
||||
{
|
||||
public:
|
||||
ScriptObjectController *getController(int n);
|
||||
void onRegisterClasses(ScriptObjectController *rootController);
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
17
Src/timer/api.h
Normal file
17
Src/timer/api.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef NULLSOFT_API_TIMER_H
|
||||
#define NULLSOFT_API_TIMER_H
|
||||
|
||||
#include <api/config/api_config.h>
|
||||
#define WASABI_API_CONFIG configApi
|
||||
|
||||
#include <api/syscb/api_syscb.h>
|
||||
#define WASABI_API_SYSCB sysCallbackApi
|
||||
|
||||
#include <api/script/api_maki.h>
|
||||
#define WASABI_API_MAKI makiApi
|
||||
|
||||
#include "timerapi.h"
|
||||
extern TimerApi *timer_svc;
|
||||
#define WASABI_API_TIMER timer_svc
|
||||
|
||||
#endif // !NULLSOFT_API_TIMER_H
|
92
Src/timer/main.cpp
Normal file
92
Src/timer/main.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
#include "api.h"
|
||||
#include "../nu/ServiceWatcher.h"
|
||||
#include "../Agave/Component/ifc_wa5component.h"
|
||||
#include <api/service/waServiceFactory.h>
|
||||
#include "Factory.h"
|
||||
#include "ScriptFactory.h"
|
||||
|
||||
Factory factory;
|
||||
static ScriptFactory scriptFactory;
|
||||
api_config *WASABI_API_CONFIG = 0;
|
||||
api_syscb *WASABI_API_SYSCB = 0;
|
||||
api_service *WASABI_API_SVC = 0;
|
||||
api_maki *WASABI_API_MAKI = 0;
|
||||
|
||||
static ServiceWatcher serviceWatcher;
|
||||
|
||||
class TimerComponent : public ifc_wa5component
|
||||
{
|
||||
public:
|
||||
void RegisterServices(api_service *service);
|
||||
int RegisterServicesSafeModeOk();
|
||||
void DeregisterServices(api_service *service);
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
||||
template <class api_t>
|
||||
api_t *GetService(GUID serviceGUID)
|
||||
{
|
||||
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(serviceGUID);
|
||||
if (sf)
|
||||
return (api_t *)sf->getInterface();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void ReleaseService(GUID serviceGUID, void *service)
|
||||
{
|
||||
if (service)
|
||||
{
|
||||
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(serviceGUID);
|
||||
if (sf)
|
||||
sf->releaseInterface(service);
|
||||
}
|
||||
}
|
||||
|
||||
void TimerComponent::RegisterServices(api_service *service)
|
||||
{
|
||||
WASABI_API_SVC = service;
|
||||
WASABI_API_SYSCB = GetService<api_syscb>(syscbApiServiceGuid);
|
||||
serviceWatcher.WatchWith(WASABI_API_SVC);
|
||||
serviceWatcher.WatchFor(&WASABI_API_CONFIG, configApiServiceGuid);
|
||||
serviceWatcher.WatchFor(&WASABI_API_MAKI, makiApiServiceGuid);
|
||||
service->service_register(&factory);
|
||||
service->service_register(&scriptFactory);
|
||||
|
||||
// register for service callbacks in case any of these don't exist yet
|
||||
WASABI_API_SYSCB->syscb_registerCallback(&serviceWatcher);
|
||||
}
|
||||
|
||||
int TimerComponent::RegisterServicesSafeModeOk()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TimerComponent::DeregisterServices(api_service *service)
|
||||
{
|
||||
service->service_deregister(&factory);
|
||||
service->service_deregister(&scriptFactory);
|
||||
serviceWatcher.StopWatching();
|
||||
serviceWatcher.Clear();
|
||||
|
||||
ReleaseService(configApiServiceGuid, WASABI_API_CONFIG);
|
||||
ReleaseService(syscbApiServiceGuid, WASABI_API_SYSCB);
|
||||
ReleaseService(makiApiServiceGuid, WASABI_API_MAKI);
|
||||
factory.Stop();
|
||||
}
|
||||
|
||||
TimerComponent timerComponent;
|
||||
extern "C" __declspec(dllexport) ifc_wa5component *GetWinamp5SystemComponent()
|
||||
{
|
||||
return &timerComponent;
|
||||
}
|
||||
|
||||
#define CBCLASS TimerComponent
|
||||
START_DISPATCH;
|
||||
VCB(API_WA5COMPONENT_REGISTERSERVICES, RegisterServices)
|
||||
CB(15, RegisterServicesSafeModeOk)
|
||||
VCB(API_WA5COMPONENT_DEREEGISTERSERVICES, DeregisterServices)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
14
Src/timer/resource.h
Normal file
14
Src/timer/resource.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by timer.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
175
Src/timer/stimer.cpp
Normal file
175
Src/timer/stimer.cpp
Normal file
|
@ -0,0 +1,175 @@
|
|||
#include "api.h"
|
||||
#include "stimer.h"
|
||||
#include <api/script/objcontroller.h>
|
||||
#include <api/script/objects/rootobj.h>
|
||||
#include "Factory.h"
|
||||
extern Factory factory;
|
||||
|
||||
STimer::STimer() {
|
||||
getScriptObject()->vcpu_setInterface(timerGuid, (void *)static_cast<STimer *>(this));
|
||||
getScriptObject()->vcpu_setClassName(L"Timer");
|
||||
getScriptObject()->vcpu_setController(timerController);
|
||||
delay = 1000;
|
||||
started = 0;
|
||||
}
|
||||
|
||||
STimer::~STimer() {
|
||||
}
|
||||
|
||||
void STimer::setDelay(int d) {
|
||||
delay = d;
|
||||
if (started)
|
||||
timerclient_setTimer(STIMER_ID, getDelay());
|
||||
}
|
||||
|
||||
int STimer::getDelay(void) {
|
||||
return delay;
|
||||
}
|
||||
|
||||
void STimer::start(void) {
|
||||
if (started) { stop(); }
|
||||
timerclient_setTimer(STIMER_ID, getDelay());
|
||||
started = 1;
|
||||
}
|
||||
|
||||
void STimer::stop(void) {
|
||||
if (!started) return;
|
||||
timerclient_killTimer(STIMER_ID);
|
||||
started = 0;
|
||||
}
|
||||
|
||||
void STimer::onTimer(void)
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
script_onTimer(SCRIPT_CALL, getScriptObject());
|
||||
}
|
||||
}
|
||||
|
||||
void STimer::timerclient_timerCallback(int id)
|
||||
{
|
||||
if (id == STIMER_ID)
|
||||
onTimer();
|
||||
}
|
||||
|
||||
int STimer::isRunning() {
|
||||
return started;
|
||||
}
|
||||
|
||||
extern ScriptObjectController *script_root;
|
||||
TimerScriptController _timerController;
|
||||
TimerScriptController *timerController=&_timerController;
|
||||
|
||||
// -- Functions table -------------------------------------
|
||||
function_descriptor_struct TimerScriptController::exportedFunction[] = {
|
||||
{L"setDelay", 1, (void*)STimer::script_setDelay },
|
||||
{L"getDelay", 0, (void*)STimer::script_getDelay },
|
||||
{L"start", 0, (void*)STimer::script_start },
|
||||
{L"stop", 0, (void*)STimer::script_stop },
|
||||
{L"onTimer", 0, (void*)STimer::script_onTimer },
|
||||
{L"isRunning",0, (void*)STimer::script_isRunning },
|
||||
{L"getSkipped",0, (void*)STimer::script_getSkipped },
|
||||
};
|
||||
// --------------------------------------------------------
|
||||
|
||||
const wchar_t *TimerScriptController::getClassName() {
|
||||
return L"Timer";
|
||||
}
|
||||
|
||||
const wchar_t *TimerScriptController::getAncestorClassName() {
|
||||
return L"Object";
|
||||
}
|
||||
|
||||
ScriptObjectController *TimerScriptController::getAncestorController() {
|
||||
return script_root;
|
||||
}
|
||||
|
||||
ScriptObject *TimerScriptController::instantiate() {
|
||||
if (!WASABI_API_TIMER)
|
||||
{
|
||||
WASABI_API_TIMER = (TimerApi *)factory.GetInterface(0);
|
||||
}
|
||||
STimer *s = new STimer;
|
||||
ASSERT(s != NULL);
|
||||
return s->getScriptObject();
|
||||
}
|
||||
|
||||
void TimerScriptController::destroy(ScriptObject *o) {
|
||||
STimer *s = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
|
||||
ASSERT(s != NULL);
|
||||
delete s;
|
||||
}
|
||||
|
||||
void *TimerScriptController::encapsulate(ScriptObject *o) {
|
||||
return NULL; // no encapsulation for timer yet
|
||||
}
|
||||
|
||||
void TimerScriptController::deencapsulate(void *o) {
|
||||
}
|
||||
|
||||
int TimerScriptController::getNumFunctions() {
|
||||
return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
|
||||
}
|
||||
|
||||
const function_descriptor_struct *TimerScriptController::getExportedFunctions() {
|
||||
return exportedFunction;
|
||||
}
|
||||
|
||||
GUID TimerScriptController::getClassGuid() {
|
||||
return timerGuid;
|
||||
}
|
||||
|
||||
scriptVar STimer::script_onTimer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
PROCESS_HOOKS0(o, timerController);
|
||||
SCRIPT_FUNCTION_CHECKABORTEVENT;
|
||||
SCRIPT_EXEC_EVENT0(o);
|
||||
}
|
||||
|
||||
static bool isNumeric(int t)
|
||||
{
|
||||
return (t == SCRIPT_INT || t == SCRIPT_BOOLEAN || t == SCRIPT_FLOAT || t == SCRIPT_DOUBLE);
|
||||
}
|
||||
|
||||
scriptVar STimer::script_setDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar d) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
ASSERT(isNumeric(d.type));
|
||||
STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
|
||||
if (t) t->setDelay(d.data.idata);
|
||||
RETURN_SCRIPT_VOID;
|
||||
}
|
||||
|
||||
scriptVar STimer::script_getDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
|
||||
if (t) return MAKE_SCRIPT_INT(t->getDelay());
|
||||
RETURN_SCRIPT_ZERO;
|
||||
}
|
||||
|
||||
scriptVar STimer::script_start(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
|
||||
if (t) t->start();
|
||||
RETURN_SCRIPT_VOID;
|
||||
}
|
||||
|
||||
scriptVar STimer::script_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
|
||||
if (t) t->stop();
|
||||
RETURN_SCRIPT_VOID;
|
||||
}
|
||||
|
||||
scriptVar STimer::script_isRunning(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
|
||||
if (t) return MAKE_SCRIPT_BOOLEAN(t->isRunning());
|
||||
RETURN_SCRIPT_ZERO;
|
||||
}
|
||||
|
||||
scriptVar STimer::script_getSkipped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
|
||||
SCRIPT_FUNCTION_INIT;
|
||||
STimer *t = static_cast<STimer *>(o->vcpu_getInterface(timerGuid));
|
||||
if (t) return MAKE_SCRIPT_INT(t->timerclient_getSkipped());
|
||||
RETURN_SCRIPT_ZERO;
|
||||
}
|
76
Src/timer/stimer.h
Normal file
76
Src/timer/stimer.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
//PORTABLE
|
||||
#ifndef _STIMER_H
|
||||
#define _STIMER_H
|
||||
|
||||
#include <api/script/objects/rootobject.h>
|
||||
#include <api/script/objects/rootobj.h>
|
||||
|
||||
#include <api/timer/timerclient.h>
|
||||
|
||||
#define STIMER_PARENT RootObjectInstance
|
||||
|
||||
// {5D0C5BB6-7DE1-4b1f-A70F-8D1659941941}
|
||||
static const GUID timerGuid =
|
||||
{ 0x5d0c5bb6, 0x7de1, 0x4b1f, { 0xa7, 0xf, 0x8d, 0x16, 0x59, 0x94, 0x19, 0x41 } };
|
||||
|
||||
class TimerScriptController : public ScriptObjectControllerI {
|
||||
public:
|
||||
|
||||
virtual const wchar_t *getClassName();
|
||||
virtual const wchar_t *getAncestorClassName();
|
||||
virtual ScriptObjectController *getAncestorController();
|
||||
virtual int getNumFunctions();
|
||||
virtual const function_descriptor_struct *getExportedFunctions();
|
||||
virtual GUID getClassGuid();
|
||||
virtual ScriptObject *instantiate();
|
||||
virtual void destroy(ScriptObject *o);
|
||||
virtual void *encapsulate(ScriptObject *o);
|
||||
virtual void deencapsulate(void *o);
|
||||
|
||||
private:
|
||||
|
||||
static function_descriptor_struct exportedFunction[];
|
||||
|
||||
};
|
||||
|
||||
extern TimerScriptController *timerController;
|
||||
|
||||
|
||||
#ifndef _NOSTUDIO
|
||||
|
||||
#define STIMER_ID 2481
|
||||
|
||||
class STimer : public STIMER_PARENT, public TimerClientDI {
|
||||
public:
|
||||
STimer();
|
||||
virtual ~STimer();
|
||||
|
||||
void start(void);
|
||||
void stop(void);
|
||||
int getDelay(void);
|
||||
void setDelay(int d);
|
||||
void onTimer(void);
|
||||
int isRunning();
|
||||
|
||||
void timerclient_timerCallback(int id);
|
||||
|
||||
private:
|
||||
int delay;
|
||||
int started;
|
||||
|
||||
#else
|
||||
class STimer : public STIMER_SCRIPTPARENT {
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
static scriptVar script_onTimer(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
|
||||
static scriptVar script_setDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar d);
|
||||
static scriptVar script_getDelay(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
|
||||
static scriptVar script_start(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
|
||||
static scriptVar script_stop(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
|
||||
static scriptVar script_isRunning(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
|
||||
static scriptVar script_getSkipped(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
|
||||
};
|
||||
|
||||
#endif
|
76
Src/timer/timer.rc
Normal file
76
Src/timer/timer.rc
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.K.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""version.rc2""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.K.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#include "version.rc2"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
40
Src/timer/timer.sln
Normal file
40
Src/timer/timer.sln
Normal file
|
@ -0,0 +1,40 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29424.173
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timer", "timer.vcxproj", "{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bfc", "..\Wasabi\bfc\bfc.vcxproj", "{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Debug|x64.Build.0 = Debug|x64
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|Win32.Build.0 = Release|Win32
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|x64.ActiveCfg = Release|x64
|
||||
{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}.Release|x64.Build.0 = Release|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|x64.Build.0 = Debug|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|Win32.Build.0 = Release|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5A4ED350-80C8-4501-87C2-26BBC67EAD28}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
282
Src/timer/timer.vcxproj
Normal file
282
Src/timer/timer.vcxproj
Normal file
|
@ -0,0 +1,282 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C7C45E25-5C76-4F59-AEBD-992CEC2A5C2E}</ProjectGuid>
|
||||
<RootNamespace>timer</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<TargetExt>.w5s</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg">
|
||||
<VcpkgEnabled>false</VcpkgEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<VcpkgConfiguration>Debug</VcpkgConfiguration>
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
|
||||
<VcpkgConfiguration>Debug</VcpkgConfiguration>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.;..;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TIMER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(ProjectDir)x86_Debug\$(ProjectName).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.;..;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;_USRDLL;TIMER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(ProjectDir)x64_Debug\$(ProjectName).lib</ImportLibrary>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\
|
||||
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>.;..;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TIMER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(ProjectDir)x86_Release\$(ProjectName).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>.;..;../Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;_USRDLL;TIMER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(ProjectDir)x64_Release\$(ProjectName).lib</ImportLibrary>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\ </Command>
|
||||
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\System\'</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Wasabi\bfc\bfc.vcxproj">
|
||||
<Project>{d0ec862e-dddd-4f4f-934f-b75dc9062dc1}</Project>
|
||||
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
|
||||
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Wasabi\Wasabi.vcxproj">
|
||||
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\nu\ServiceWatcher.cpp" />
|
||||
<ClCompile Include="..\Wasabi\api\script\objcontroller.cpp" />
|
||||
<ClCompile Include="..\Wasabi\api\script\objects\rootobj.cpp" />
|
||||
<ClCompile Include="..\Wasabi\api\script\objects\rootobjcbx.cpp" />
|
||||
<ClCompile Include="..\Wasabi\api\script\scriptobji.cpp" />
|
||||
<ClCompile Include="..\Wasabi\api\script\scriptobjx.cpp" />
|
||||
<ClCompile Include="..\Wasabi\api\timer\timerclient.cpp" />
|
||||
<ClCompile Include="Factory.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="ScriptFactory.cpp" />
|
||||
<ClCompile Include="ScriptObjectService.cpp" />
|
||||
<ClCompile Include="stimer.cpp" />
|
||||
<ClCompile Include="timerapi.cpp" />
|
||||
<ClCompile Include="timermul.cpp" />
|
||||
<ClCompile Include="tmultiplex.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="api.h" />
|
||||
<ClInclude Include="Factory.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="ScriptFactory.h" />
|
||||
<ClInclude Include="ScriptObjectService.h" />
|
||||
<ClInclude Include="stimer.h" />
|
||||
<ClInclude Include="timerapi.h" />
|
||||
<ClInclude Include="timermul.h" />
|
||||
<ClInclude Include="tmultiplex.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="timer.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
95
Src/timer/timer.vcxproj.filters
Normal file
95
Src/timer/timer.vcxproj.filters
Normal file
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Factory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Wasabi\api\script\objcontroller.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Wasabi\api\script\objects\rootobj.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Wasabi\api\script\objects\rootobjcbx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ScriptFactory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ScriptObjectService.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Wasabi\api\script\scriptobji.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Wasabi\api\script\scriptobjx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\nu\ServiceWatcher.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stimer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="timerapi.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Wasabi\api\timer\timerclient.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="timermul.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tmultiplex.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="api.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Factory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScriptFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ScriptObjectService.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stimer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="timerapi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="timermul.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tmultiplex.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{dc3ff9be-ed5b-4440-a237-bd67ac1d61ba}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ressource Files">
|
||||
<UniqueIdentifier>{196e3323-cdec-4d80-91b1-c5896e275321}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{691078fc-f387-4cdb-aa1b-f1d6a961cf0d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="timer.rc">
|
||||
<Filter>Ressource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
32
Src/timer/timerapi.cpp
Normal file
32
Src/timer/timerapi.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "api.h"
|
||||
#include "timerapi.h"
|
||||
#include "tmultiplex.h"
|
||||
|
||||
//timer_api *timerApi = NULL;
|
||||
|
||||
TimerApi::TimerApi()
|
||||
{
|
||||
}
|
||||
|
||||
TimerApi::~TimerApi()
|
||||
{
|
||||
multiplex.shutdown();
|
||||
}
|
||||
|
||||
TimerToken TimerApi::timer_add(TimerClient *client, intptr_t id, int ms)
|
||||
{
|
||||
multiplex.add(client, id, ms);
|
||||
return id;
|
||||
}
|
||||
|
||||
void TimerApi::timer_remove(TimerClient *client, TimerToken id)
|
||||
{
|
||||
multiplex.remove(client, id);
|
||||
}
|
||||
|
||||
#define CBCLASS TimerApi
|
||||
START_DISPATCH;
|
||||
CB(TIMER_API_ADD, timer_add);
|
||||
VCB(TIMER_API_REMOVE, timer_remove);
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
21
Src/timer/timerapi.h
Normal file
21
Src/timer/timerapi.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef __TIMER_SVC_H
|
||||
#define __TIMER_SVC_H
|
||||
|
||||
#include <api/timer/api_timer.h>
|
||||
#include "tmultiplex.h"
|
||||
|
||||
class TimerApi : public timer_api
|
||||
{
|
||||
public:
|
||||
TimerApi();
|
||||
~TimerApi();
|
||||
virtual TimerToken timer_add(TimerClient *client, intptr_t id, int ms);
|
||||
virtual void timer_remove(TimerClient *client, TimerToken token = -1);
|
||||
|
||||
protected:
|
||||
MainTimerMultiplexer multiplex;
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
370
Src/timer/timermul.cpp
Normal file
370
Src/timer/timermul.cpp
Normal file
|
@ -0,0 +1,370 @@
|
|||
#include <bfc/platform/platform.h>
|
||||
#include "timermul.h"
|
||||
|
||||
#include <api.h>
|
||||
#include <api/config/items/attribs.h>
|
||||
#include <api/config/items/cfgitem.h>
|
||||
|
||||
// {9149C445-3C30-4e04-8433-5A518ED0FDDE}
|
||||
const GUID uioptions_guid =
|
||||
{ 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
|
||||
|
||||
PtrListQuickSorted<MultiplexerServer, MultiplexerServerComparatorTID> servers_tid;
|
||||
PtrListQuickSorted<MultiplexerServer, MultiplexerServerComparatorTID> servers_mux;
|
||||
|
||||
TimerMultiplexer::TimerMultiplexer() {
|
||||
timerset = 0;
|
||||
nslices = 0;
|
||||
resolution = -1;
|
||||
check_resolution = true;
|
||||
client = NULL;
|
||||
curslice = 0;
|
||||
running_timer = NULL;
|
||||
uioptions = NULL;
|
||||
justexited = 0;
|
||||
firstevent = 1;
|
||||
resetTimer(50); // initial, is changed for config value on first event
|
||||
}
|
||||
|
||||
TimerMultiplexer::~TimerMultiplexer() {
|
||||
doShutdown();
|
||||
}
|
||||
|
||||
void TimerMultiplexer::setClient(TimerMultiplexerClient *_client) {
|
||||
client = _client;
|
||||
}
|
||||
|
||||
void TimerMultiplexer::addTimer(int ms, void *data) {
|
||||
//if (ms < 0) { DebugString("Timer with negative delay set, ignored coz the time machine service isn't ready yet\n"); }
|
||||
MultiplexedTimer *t = new MultiplexedTimer(ms, data);
|
||||
if (ms >= MAX_TIMER_DELAY) {
|
||||
lptimers.addItem(t);
|
||||
t->nexttick = Wasabi::Std::getTickCount() + t->ms;
|
||||
} else {
|
||||
timers.addItem(t);
|
||||
if (nslices > 0)
|
||||
distribute(t);
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::removeTimer(void *data) {
|
||||
|
||||
if (running_timer && running_timer->data == data)
|
||||
running_timer = NULL;
|
||||
|
||||
int i;
|
||||
for (i=0;i<timers.getNumItems();i++) {
|
||||
MultiplexedTimer *t = timers.enumItem(i);
|
||||
if (t->data == data) {
|
||||
removeFromWheel(t);
|
||||
timers.removeByPos(i);
|
||||
delete t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i=0;i<lptimers.getNumItems();i++) {
|
||||
MultiplexedTimer *t = lptimers.enumItem(i);
|
||||
if (t->data == data) {
|
||||
removeFromLowPrecision(t);
|
||||
delete t;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::setResolution(int ms) {
|
||||
resolution = ms;
|
||||
}
|
||||
|
||||
void TimerMultiplexer::shutdown() {
|
||||
doShutdown();
|
||||
}
|
||||
|
||||
void TimerMultiplexer::doShutdown() {
|
||||
timers.deleteAll();
|
||||
wheel.deleteAll();
|
||||
lptimers.deleteAll();
|
||||
if (timerset) {
|
||||
MultiplexerServer *s = servers_mux.findItem((const wchar_t *)this);
|
||||
if (s) {
|
||||
#ifdef WIN32
|
||||
KillTimer(NULL, s->getId());
|
||||
#elif defined(LINUX)
|
||||
|
||||
#endif
|
||||
}
|
||||
timerset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::checkResolution(DWORD now) {
|
||||
if (check_resolution == true)
|
||||
{
|
||||
if (WASABI_API_CONFIG)
|
||||
{
|
||||
if (uioptions == NULL)
|
||||
{
|
||||
uioptions = WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid);
|
||||
if (uioptions)
|
||||
{
|
||||
ifc_dependent *ui_change = uioptions->getDependencyPtr();
|
||||
ui_change->dependent_regViewer(this, 1);
|
||||
}
|
||||
}
|
||||
check_resolution = uioptions?false:true;
|
||||
int nresolution = uioptions ? _intVal(uioptions, L"Multiplexed timers resolution") : DEF_RES;
|
||||
|
||||
nresolution = MAX(10, MIN(MAX_TIMER_DELAY/LOW_RES_DIV, nresolution));
|
||||
if (nresolution != resolution) {
|
||||
resetTimer(nresolution);
|
||||
resolution = nresolution;
|
||||
resetWheel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID CALLBACK timerMultiplexerServerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
|
||||
MultiplexerServer *s = servers_tid.findItem((const wchar_t *)&idEvent);
|
||||
if (s) s->getMultiplexer()->onServerTimer();
|
||||
}
|
||||
|
||||
void TimerMultiplexer::resetTimer(int newresolution) {
|
||||
if (timerset) {
|
||||
MultiplexerServer *s = servers_mux.findItem((const wchar_t *)this);
|
||||
if (s)
|
||||
KillTimer(NULL, s->getId());
|
||||
}
|
||||
|
||||
// linux port implements settimer
|
||||
UINT_PTR id = SetTimer(NULL, 0, newresolution, timerMultiplexerServerProc);
|
||||
MultiplexerServer *s = servers_mux.findItem((const wchar_t *)this);
|
||||
if (!s) {
|
||||
s = new MultiplexerServer(this, (UINT)id);
|
||||
servers_mux.addItem(s);
|
||||
servers_tid.addItem(s);
|
||||
} else {
|
||||
s->setId(id);
|
||||
servers_tid.sort();
|
||||
}
|
||||
timerset = 1;
|
||||
}
|
||||
|
||||
PtrList<MultiplexedTimer> *TimerMultiplexer::getSlice(int n) {
|
||||
ASSERT(nslices > 0);
|
||||
return wheel.enumItem(n % nslices);
|
||||
}
|
||||
|
||||
void TimerMultiplexer::resetWheel() {
|
||||
|
||||
wheel.deleteAll();
|
||||
|
||||
nslices = MAX_TIMER_DELAY / resolution;
|
||||
|
||||
for (int i=0;i<nslices;i++)
|
||||
wheel.addItem(new PtrList< MultiplexedTimer >);
|
||||
|
||||
curslice = 0;
|
||||
distributeAll();
|
||||
}
|
||||
|
||||
void TimerMultiplexer::distributeAll() {
|
||||
for (int i=0;i<timers.getNumItems();i++) {
|
||||
distribute(timers.enumItem(i));
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::distribute(MultiplexedTimer *t) {
|
||||
ASSERT(t != NULL);
|
||||
|
||||
int delay = t->ms;
|
||||
|
||||
int slice = delay / resolution + curslice;
|
||||
PtrList<MultiplexedTimer> *l = getSlice(slice);
|
||||
|
||||
ASSERT(l != NULL);
|
||||
|
||||
l->addItem(t);
|
||||
}
|
||||
|
||||
void TimerMultiplexer::onServerTimer() {
|
||||
|
||||
justexited = 0;
|
||||
|
||||
DWORD now = Wasabi::Std::getTickCount();
|
||||
|
||||
checkResolution(now);
|
||||
|
||||
runCurSlice(now);
|
||||
|
||||
if ((curslice % (nslices/LOW_RES_DIV)) == 0) { // execute low precision timers every MAX_TIMER_DELAY/LOW_RES_DIV
|
||||
runLowPrecisionTimers(now);
|
||||
}
|
||||
|
||||
if (!justexited) {
|
||||
curslice++;
|
||||
curslice %= nslices;
|
||||
}
|
||||
|
||||
justexited = 1;
|
||||
|
||||
if (firstevent) {
|
||||
firstevent = 0;
|
||||
checkResolution(Wasabi::Std::getTickCount());
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::runCurSlice(DWORD now) {
|
||||
//DebugString("Running slice %d\n", curslice);
|
||||
PtrList<MultiplexedTimer> *slice = getSlice(curslice);
|
||||
ASSERT(slice != NULL);
|
||||
|
||||
// mark them clean
|
||||
int i;
|
||||
for (i=0;i<slice->getNumItems();i++)
|
||||
slice->enumItem(i)->flag = 0;
|
||||
|
||||
// run events
|
||||
int n;
|
||||
do {
|
||||
n = 0;
|
||||
for (i=0;i<slice->getNumItems();i++) {
|
||||
MultiplexedTimer *t = slice->enumItem(i);
|
||||
if (t == NULL) break; // do not remove this line even if you think it's useless
|
||||
// t might have been removed by a previous runTimer in this slice, so see if it's still here and if not, ignore
|
||||
if (!timers.haveItem(t)) { slice->removeItem(t); i--; continue; }
|
||||
if (t->flag == 1) continue;
|
||||
t->flag = 1;
|
||||
int lastdelay = MAX(0, (int)(now - t->lastmscount));
|
||||
DWORD last = t->lastmscount;
|
||||
if (last == 0) last = now;
|
||||
t->lastmscount = now;
|
||||
t->lastdelay = lastdelay;
|
||||
running_timer = t;
|
||||
runTimer(now, last, t, slice, i);
|
||||
// -----------------------------------------------------------------------
|
||||
// WARNING
|
||||
//
|
||||
// below this line, you can no longer assume that t is pointing at valid
|
||||
// memory, because runTimer can eventually call removeTimer
|
||||
// -----------------------------------------------------------------------
|
||||
n++;
|
||||
}
|
||||
} while (n > 0);
|
||||
}
|
||||
|
||||
void TimerMultiplexer::runTimer(DWORD now, DWORD last, MultiplexedTimer *t, PtrList<MultiplexedTimer> *slice, int pos) {
|
||||
|
||||
int nextslice = curslice + t->ms / resolution;
|
||||
int spent = now - last;
|
||||
int lost = spent - t->ms;
|
||||
|
||||
if (lost > 0) {
|
||||
t->lost += (float)lost / (float)t->ms;
|
||||
}
|
||||
|
||||
PtrList<MultiplexedTimer> *next = getSlice(nextslice);
|
||||
ASSERT(next != NULL);
|
||||
|
||||
if (slice == next) {
|
||||
nextslice++;
|
||||
next = getSlice(nextslice);
|
||||
}
|
||||
|
||||
slice->removeByPos(pos);
|
||||
next->addItem(t);
|
||||
|
||||
int skip = (int)t->lost;
|
||||
t->lost -= (int)t->lost;
|
||||
if (client) {
|
||||
client->onMultiplexedTimer(t->data, skip, t->lastdelay);
|
||||
// -----------------------------------------------------------------------
|
||||
// WARNING
|
||||
//
|
||||
// below this line, you can no longer assume that t is pointing at valid
|
||||
// memory, because onMultiplexedTimer can eventually call removeTimer
|
||||
// -----------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::removeFromWheel(MultiplexedTimer *t) {
|
||||
for (int i=0;i<nslices;i++) {
|
||||
PtrList<MultiplexedTimer> *slice = getSlice(i);
|
||||
for (int j=0;j<slice->getNumItems();j++) {
|
||||
if (slice->enumItem(j) == t) {
|
||||
slice->removeByPos(j);
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::removeFromLowPrecision(MultiplexedTimer *t) {
|
||||
for (int i=0;i<lptimers.getNumItems();i++) {
|
||||
if (lptimers.enumItem(i) == t) {
|
||||
lptimers.removeByPos(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimerMultiplexer::runLowPrecisionTimers(DWORD now) {
|
||||
int restart;
|
||||
do {
|
||||
restart = 0;
|
||||
for (int i=0;i<lptimers.getNumItems();i++) {
|
||||
MultiplexedTimer *t = lptimers.enumItem(i);
|
||||
if (t->nexttick < now) {
|
||||
if (client) {
|
||||
running_timer = t;
|
||||
t->lost += (now - t->nexttick) / t->ms;
|
||||
int skip = (int)t->lost;
|
||||
t->lost -= skip; // remove integer part
|
||||
DWORD last = t->lastmscount;
|
||||
t->lastdelay = now-last;
|
||||
t->lastmscount = now;
|
||||
t->nexttick = t->nexttick+(t->ms)*(skip+1);
|
||||
client->onMultiplexedTimer(t->data, skip, t->lastdelay);
|
||||
// -----------------------------------------------------------------------
|
||||
// WARNING
|
||||
//
|
||||
// below this line, you can no longer assume that t is pointing at valid
|
||||
// memory, because onMultiplexedTimer can eventually call removeTimer
|
||||
// -----------------------------------------------------------------------
|
||||
}
|
||||
if (running_timer == NULL) { // onMultiplexedTimer called removeTimer
|
||||
restart =1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (restart);
|
||||
}
|
||||
|
||||
|
||||
int TimerMultiplexer::getNumTimers() {
|
||||
return timers.getNumItems();
|
||||
}
|
||||
|
||||
int TimerMultiplexer::getNumTimersLP() {
|
||||
return lptimers.getNumItems();
|
||||
}
|
||||
|
||||
int TimerMultiplexer::dependentViewer_callback(ifc_dependent *item, const GUID *classguid, int cb, intptr_t param1, intptr_t param2 , void *ptr, size_t ptrlen)
|
||||
{
|
||||
if (param1 == CfgItem::Event_ATTRIBUTE_CHANGED)
|
||||
{
|
||||
check_resolution=true;
|
||||
}
|
||||
else if (param1 == CfgItem::Event_ATTRIBUTE_REMOVED)
|
||||
{
|
||||
uioptions=0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define CBCLASS TimerMultiplexer
|
||||
START_DISPATCH;
|
||||
CB(DEPENDENTVIEWER_CALLBACK, dependentViewer_callback)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
145
Src/timer/timermul.h
Normal file
145
Src/timer/timermul.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
#ifndef __TIMER_MULTIPLEXER_H
|
||||
#define __TIMER_MULTIPLEXER_H
|
||||
|
||||
#include <bfc/common.h>
|
||||
#include <bfc/ptrlist.h>
|
||||
#include <api/dependency/api_dependentviewer.h>
|
||||
|
||||
// FG> not too sure how to get a callback for attribute change, if anyone wants to change it be my guest ;)
|
||||
#define RESOLUTION_CHECK_DELAY 1000 // check for resolution changes every second
|
||||
|
||||
// if uioptions CfgItem not found, use this value for resolution
|
||||
#define DEF_RES 20
|
||||
|
||||
// below MAX_TIMER_DELAY, timer are multiplexed using a 'wheel' algorithm (mem used = MAX_TIMER_DELAY/resolution * sizeof(PtrList) + ntimers*sizeof(MultiplexedTimer), but fast (no lookup) )
|
||||
// above MAX_TIMER_DELAY, resolution drops to MAX_TIMER_DELAY/LOW_RES_DIV and uses ntimers*sizeof(MultiplexedTimer) bytes
|
||||
#define MAX_TIMER_DELAY 1000 // keep this dividable by LOW_RES_DIV please
|
||||
#define LOW_RES_DIV 4
|
||||
|
||||
class CfgItem;
|
||||
class api_config;
|
||||
|
||||
class TimerMultiplexerClient {
|
||||
public:
|
||||
virtual void onMultiplexedTimer(void *data, int skip, int mssincelast)=0;
|
||||
};
|
||||
|
||||
class MultiplexedTimer {
|
||||
public:
|
||||
MultiplexedTimer(int _ms, void *_data) : ms(_ms), data(_data) {
|
||||
nexttick=0;
|
||||
flag=0;
|
||||
lost = 0;
|
||||
lastmscount=0;
|
||||
lastdelay=0;
|
||||
}
|
||||
virtual ~MultiplexedTimer() { }
|
||||
|
||||
int ms;
|
||||
void *data;
|
||||
DWORD nexttick; // only used by low precision timers
|
||||
int flag; // only used by hi precision timers
|
||||
float lost; // only used by hi precision timers
|
||||
DWORD lastmscount;
|
||||
int lastdelay;
|
||||
};
|
||||
|
||||
class TimerMultiplexer : public ifc_dependentviewer
|
||||
{
|
||||
public:
|
||||
|
||||
TimerMultiplexer();
|
||||
virtual ~TimerMultiplexer();
|
||||
|
||||
virtual void setClient(TimerMultiplexerClient *client);
|
||||
|
||||
virtual void onServerTimer();
|
||||
|
||||
virtual void addTimer(int ms, void *data);
|
||||
virtual void removeTimer(void *data);
|
||||
virtual void setResolution(int ms);
|
||||
|
||||
virtual void shutdown();
|
||||
virtual int getNumTimers();
|
||||
virtual int getNumTimersLP();
|
||||
|
||||
private:
|
||||
|
||||
void checkResolution(DWORD now);
|
||||
void resetTimer(int newresolution);
|
||||
void resetWheel();
|
||||
void distributeAll();
|
||||
void distribute(MultiplexedTimer *t);
|
||||
void runCurSlice(DWORD now);
|
||||
void runTimer(DWORD now, DWORD last, MultiplexedTimer *t, PtrList<MultiplexedTimer> *slice, int pos);
|
||||
void removeFromWheel(MultiplexedTimer *t);
|
||||
void runLowPrecisionTimers(DWORD now);
|
||||
void removeFromLowPrecision(MultiplexedTimer *t);
|
||||
void doShutdown();
|
||||
PtrList<MultiplexedTimer> *getSlice(int n);
|
||||
|
||||
TimerMultiplexerClient *client;
|
||||
int resolution;
|
||||
bool check_resolution;
|
||||
int timerset;
|
||||
|
||||
int curslice;
|
||||
int nslices;
|
||||
int justexited;
|
||||
int firstevent;
|
||||
|
||||
PtrList< PtrList< MultiplexedTimer > > wheel;
|
||||
PtrList< MultiplexedTimer > timers;
|
||||
PtrList< MultiplexedTimer > lptimers;
|
||||
MultiplexedTimer *running_timer;
|
||||
int dependentViewer_callback(ifc_dependent *item, const GUID *classguid, int cb, intptr_t param1 = 0, intptr_t param2 = 0, void *ptr = NULL, size_t ptrlen = 0);
|
||||
|
||||
CfgItem *uioptions;
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
class MultiplexerServer {
|
||||
public:
|
||||
MultiplexerServer(TimerMultiplexer *mux, UINT tid) : m_mux(mux), m_tid(tid) {}
|
||||
virtual ~MultiplexerServer() {}
|
||||
TimerMultiplexer *getMultiplexer() { return m_mux; }
|
||||
UINT_PTR getId() { return m_tid; }
|
||||
void setId(UINT_PTR id) { m_tid = id; }
|
||||
private:
|
||||
TimerMultiplexer *m_mux;
|
||||
UINT_PTR m_tid;
|
||||
};
|
||||
|
||||
class MultiplexerServerComparatorTID {
|
||||
public:
|
||||
// comparator for sorting
|
||||
static int compareItem(MultiplexerServer *p1, MultiplexerServer* p2) {
|
||||
if (p1->getId() < p2->getId()) return -1;
|
||||
if (p1->getId() > p2->getId()) return 1;
|
||||
return 0;
|
||||
}
|
||||
// comparator for searching
|
||||
static int compareAttrib(const wchar_t *attrib, MultiplexerServer *item) {
|
||||
if (*((UINT *)attrib) < item->getId()) return -1;
|
||||
if (*((UINT *)attrib) < item->getId()) return 1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class MultiplexerServerComparatorMux{
|
||||
public:
|
||||
// comparator for sorting
|
||||
static int compareItem(MultiplexerServer *p1, MultiplexerServer* p2) {
|
||||
if (p1->getMultiplexer() < p2->getMultiplexer()) return -1;
|
||||
if (p1->getMultiplexer() > p2->getMultiplexer()) return 1;
|
||||
return 0;
|
||||
}
|
||||
// comparator for searching
|
||||
static int compareAttrib(const wchar_t *attrib, MultiplexerServer *item) {
|
||||
if ((TimerMultiplexer *)attrib < item->getMultiplexer()) return -1;
|
||||
if ((TimerMultiplexer *)attrib < item->getMultiplexer()) return 1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
128
Src/timer/tmultiplex.cpp
Normal file
128
Src/timer/tmultiplex.cpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
#include "tmultiplex.h"
|
||||
#include <api/timer/timerclient.h>
|
||||
#include <assert.h>
|
||||
VirtualTimer::VirtualTimer(TimerClient *_client, intptr_t _id, api_dependent *depend) :
|
||||
client(_client), id(_id), dep(depend)
|
||||
{
|
||||
name = client->timerclient_getName();
|
||||
mclient = client->timerclient_getMasterClient();
|
||||
}
|
||||
|
||||
MainTimerMultiplexer::MainTimerMultiplexer() {
|
||||
setClient(this);
|
||||
}
|
||||
|
||||
MainTimerMultiplexer::~MainTimerMultiplexer() {
|
||||
/*
|
||||
foreach(timerclients)
|
||||
VirtualTimer *vt = timerclients.getfor();
|
||||
//DebugString("TIMER MULTIPLEXER WARNING: TimerClient %X (%s) was not deregistered\n", vt->client, vt->name.getValue());
|
||||
endfor;
|
||||
*/
|
||||
// NOTE: if you get a crash here, someone probably had a timer event outstanding
|
||||
// or didn't call down in timerclient_timerCallback()
|
||||
|
||||
// Also this is guaranteed to happen if one of your timerclient objects (ie: a wnd) was not deleted
|
||||
// eventho your DLL has been unloaded. the watched pointer will remain watched instead of unregistering
|
||||
// itself from its viewers. DependentViewerI (one of our direct ancestors) will try to dereference that pointer in
|
||||
// order to signal it that a viewer was detached, and it will crash.
|
||||
|
||||
timerclients.deleteAll();
|
||||
}
|
||||
|
||||
void MainTimerMultiplexer::add(TimerClient *client, intptr_t id, int ms) {
|
||||
remove(client, id);
|
||||
api_dependent *d = client->timerclient_getDependencyPtr();
|
||||
assert(d != NULL);
|
||||
VirtualTimer *t = new VirtualTimer(client, id, d);
|
||||
timerclients.addItem(t);
|
||||
viewer_addViewItem(d);
|
||||
if (t->mclient) {
|
||||
d = t->mclient->timerclient_getDependencyPtr();
|
||||
ASSERT(d != NULL);
|
||||
viewer_addViewItem(d);
|
||||
}
|
||||
addTimer(ms, static_cast<void *>(t));
|
||||
}
|
||||
|
||||
void MainTimerMultiplexer::remove(TimerClient *client, intptr_t id) {
|
||||
while (masters.haveItem(client)) masters.removeItem(client);
|
||||
for (int i=0;i<timerclients.getNumItems();i++) {
|
||||
VirtualTimer *t = timerclients.enumItem(i);
|
||||
masters.removeItem(t->mclient);//BU store mclient on VirtualTimer now
|
||||
if (t->client == client && (t->id == id || id == -1)) {
|
||||
viewer_delViewItem(t->dep);
|
||||
timerclients.removeByPos(i);
|
||||
removeTimer(static_cast<void *>(t));
|
||||
delete t;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MainTimerMultiplexer::isValidTimerClientPtr(TimerClient *tc, api_dependent *dep) {
|
||||
// try {
|
||||
__try {
|
||||
api_dependent *d = tc->timerclient_getDependencyPtr();
|
||||
if (d != dep) return 0;
|
||||
//} catch (...) {
|
||||
} __except (1) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MainTimerMultiplexer::onMultiplexedTimer(void *data, int skip, int mssincelasttimer) {
|
||||
assert(data != NULL);
|
||||
VirtualTimer *t = static_cast<VirtualTimer *>(data);
|
||||
if (!isValidTimerClientPtr(t->client, t->dep)) {
|
||||
//DebugString("TIMER MULTIPLEXER WARNING: TimerClient %X (%s) is no longer valid! (%d)\n", t->client, t->name.getValue(), t->id);
|
||||
remove(t->client, -1);
|
||||
t->client = 0;
|
||||
} else {
|
||||
TimerClient *mc = t->client->timerclient_getMasterClient();
|
||||
if (mc) masters.addItem(mc);
|
||||
t->client->timerclient_setSkipped(skip);
|
||||
t->client->timerclient_setTimerDelay(mssincelasttimer);
|
||||
t->client->timerclient_timerCallback(t->id);
|
||||
// -----------------------------------------------------------------------
|
||||
// WARNING
|
||||
//
|
||||
// below this line, you can no longer assume that t is pointing at valid
|
||||
// memory, because timerCallback can eventually call remove
|
||||
// -----------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
void MainTimerMultiplexer::onServerTimer() {
|
||||
TimerMultiplexer::onServerTimer();
|
||||
TimerClient *last = NULL;
|
||||
for (int i=0;i<masters.getNumItems();i++) {
|
||||
TimerClient *t = masters.enumItem(i);
|
||||
if (t == last) continue;
|
||||
t->timerclient_onMasterClientMultiplex();
|
||||
last = t;
|
||||
}
|
||||
masters.removeAll();
|
||||
}
|
||||
|
||||
int MainTimerMultiplexer::haveClient(TimerClient *client) {
|
||||
for (int i=0;i<timerclients.getNumItems();i++)
|
||||
{
|
||||
VirtualTimer *vt = timerclients.enumItem(i);
|
||||
if (vt && vt->client == client)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MainTimerMultiplexer::viewer_onItemDeleted(api_dependent *item) {
|
||||
for (int i=0;i<timerclients.getNumItems();i++) {
|
||||
VirtualTimer *vt = timerclients.enumItem(i);
|
||||
if (vt->dep == item) {
|
||||
remove(vt->client, -1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
45
Src/timer/tmultiplex.h
Normal file
45
Src/timer/tmultiplex.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef __MAIN_TIMERMULTIPLEXER_H
|
||||
#define __MAIN_TIMERMULTIPLEXER_H
|
||||
|
||||
#include "timermul.h"
|
||||
#include <bfc/depend.h>
|
||||
#include <bfc/string/StringW.h>
|
||||
#include <api/timer/timerclient.h>
|
||||
|
||||
class VirtualTimer
|
||||
{
|
||||
public:
|
||||
VirtualTimer(TimerClient *_client, intptr_t _id, api_dependent *depend);
|
||||
virtual ~VirtualTimer() { }
|
||||
|
||||
TimerClient *client, *mclient;
|
||||
api_dependent *dep;
|
||||
StringW name;
|
||||
intptr_t id;
|
||||
};
|
||||
|
||||
class MainTimerMultiplexer : public TimerMultiplexer, public TimerMultiplexerClient, public DependentViewerI {
|
||||
public:
|
||||
|
||||
MainTimerMultiplexer();
|
||||
virtual ~MainTimerMultiplexer();
|
||||
|
||||
virtual void add(TimerClient *client, intptr_t id, int ms);
|
||||
virtual void remove(TimerClient *client, intptr_t id);
|
||||
|
||||
virtual void onMultiplexedTimer(void *data, int skip, int mssincelast);
|
||||
virtual void onServerTimer();
|
||||
|
||||
virtual int viewer_onItemDeleted(api_dependent *item);
|
||||
|
||||
private:
|
||||
|
||||
int isValidTimerClientPtr(TimerClient *tc, api_dependent *dep);
|
||||
|
||||
int haveClient(TimerClient *client);
|
||||
PtrList<VirtualTimer> timerclients;
|
||||
PtrListQuickSortedByPtrVal<TimerClient> masters;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
39
Src/timer/version.rc2
Normal file
39
Src/timer/version.rc2
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "../Winamp/buildType.h"
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION WINAMP_PRODUCTVER
|
||||
PRODUCTVERSION WINAMP_PRODUCTVER
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Winamp SA"
|
||||
VALUE "FileDescription", "Winamp 5.x System Component"
|
||||
VALUE "FileVersion", STR_WINAMP_PRODUCTVER
|
||||
VALUE "InternalName", "timer.w5s"
|
||||
VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
|
||||
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
|
||||
VALUE "OriginalFilename", "timer.w5s"
|
||||
VALUE "ProductName", "Winamp Timer API & Scripting Support Service"
|
||||
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
Loading…
Add table
Add a link
Reference in a new issue