diff options
Diffstat (limited to 'Src/timer')
-rw-r--r-- | Src/timer/Factory.cpp | 69 | ||||
-rw-r--r-- | Src/timer/Factory.h | 24 | ||||
-rw-r--r-- | Src/timer/ScriptFactory.cpp | 68 | ||||
-rw-r--r-- | Src/timer/ScriptFactory.h | 24 | ||||
-rw-r--r-- | Src/timer/ScriptObjectService.cpp | 29 | ||||
-rw-r--r-- | Src/timer/ScriptObjectService.h | 11 | ||||
-rw-r--r-- | Src/timer/api.h | 17 | ||||
-rw-r--r-- | Src/timer/main.cpp | 92 | ||||
-rw-r--r-- | Src/timer/resource.h | 14 | ||||
-rw-r--r-- | Src/timer/stimer.cpp | 175 | ||||
-rw-r--r-- | Src/timer/stimer.h | 76 | ||||
-rw-r--r-- | Src/timer/timer.rc | 76 | ||||
-rw-r--r-- | Src/timer/timer.sln | 40 | ||||
-rw-r--r-- | Src/timer/timer.vcxproj | 282 | ||||
-rw-r--r-- | Src/timer/timer.vcxproj.filters | 95 | ||||
-rw-r--r-- | Src/timer/timerapi.cpp | 32 | ||||
-rw-r--r-- | Src/timer/timerapi.h | 21 | ||||
-rw-r--r-- | Src/timer/timermul.cpp | 370 | ||||
-rw-r--r-- | Src/timer/timermul.h | 145 | ||||
-rw-r--r-- | Src/timer/tmultiplex.cpp | 128 | ||||
-rw-r--r-- | Src/timer/tmultiplex.h | 45 | ||||
-rw-r--r-- | Src/timer/version.rc2 | 39 |
22 files changed, 1872 insertions, 0 deletions
diff --git a/Src/timer/Factory.cpp b/Src/timer/Factory.cpp new file mode 100644 index 00000000..104f844f --- /dev/null +++ b/Src/timer/Factory.cpp @@ -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
\ No newline at end of file diff --git a/Src/timer/Factory.h b/Src/timer/Factory.h new file mode 100644 index 00000000..c7b0c144 --- /dev/null +++ b/Src/timer/Factory.h @@ -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; +}; + + diff --git a/Src/timer/ScriptFactory.cpp b/Src/timer/ScriptFactory.cpp new file mode 100644 index 00000000..75b6f558 --- /dev/null +++ b/Src/timer/ScriptFactory.cpp @@ -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
\ No newline at end of file diff --git a/Src/timer/ScriptFactory.h b/Src/timer/ScriptFactory.h new file mode 100644 index 00000000..4e516d01 --- /dev/null +++ b/Src/timer/ScriptFactory.h @@ -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; +}; + + diff --git a/Src/timer/ScriptObjectService.cpp b/Src/timer/ScriptObjectService.cpp new file mode 100644 index 00000000..6ea7cbb7 --- /dev/null +++ b/Src/timer/ScriptObjectService.cpp @@ -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 diff --git a/Src/timer/ScriptObjectService.h b/Src/timer/ScriptObjectService.h new file mode 100644 index 00000000..872657ac --- /dev/null +++ b/Src/timer/ScriptObjectService.h @@ -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; +}; diff --git a/Src/timer/api.h b/Src/timer/api.h new file mode 100644 index 00000000..f7ab3d6d --- /dev/null +++ b/Src/timer/api.h @@ -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 diff --git a/Src/timer/main.cpp b/Src/timer/main.cpp new file mode 100644 index 00000000..dd8f2b1f --- /dev/null +++ b/Src/timer/main.cpp @@ -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
\ No newline at end of file diff --git a/Src/timer/resource.h b/Src/timer/resource.h new file mode 100644 index 00000000..71f1a668 --- /dev/null +++ b/Src/timer/resource.h @@ -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 diff --git a/Src/timer/stimer.cpp b/Src/timer/stimer.cpp new file mode 100644 index 00000000..88a99472 --- /dev/null +++ b/Src/timer/stimer.cpp @@ -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; +} diff --git a/Src/timer/stimer.h b/Src/timer/stimer.h new file mode 100644 index 00000000..0e91c3f3 --- /dev/null +++ b/Src/timer/stimer.h @@ -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 diff --git a/Src/timer/timer.rc b/Src/timer/timer.rc new file mode 100644 index 00000000..fcff7711 --- /dev/null +++ b/Src/timer/timer.rc @@ -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 + diff --git a/Src/timer/timer.sln b/Src/timer/timer.sln new file mode 100644 index 00000000..21e4adb2 --- /dev/null +++ b/Src/timer/timer.sln @@ -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 diff --git a/Src/timer/timer.vcxproj b/Src/timer/timer.vcxproj new file mode 100644 index 00000000..8a128f7b --- /dev/null +++ b/Src/timer/timer.vcxproj @@ -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>
\ No newline at end of file diff --git a/Src/timer/timer.vcxproj.filters b/Src/timer/timer.vcxproj.filters new file mode 100644 index 00000000..6f91d699 --- /dev/null +++ b/Src/timer/timer.vcxproj.filters @@ -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>
\ No newline at end of file diff --git a/Src/timer/timerapi.cpp b/Src/timer/timerapi.cpp new file mode 100644 index 00000000..d0ed1f87 --- /dev/null +++ b/Src/timer/timerapi.cpp @@ -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
\ No newline at end of file diff --git a/Src/timer/timerapi.h b/Src/timer/timerapi.h new file mode 100644 index 00000000..65a4640d --- /dev/null +++ b/Src/timer/timerapi.h @@ -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 diff --git a/Src/timer/timermul.cpp b/Src/timer/timermul.cpp new file mode 100644 index 00000000..6e7213a9 --- /dev/null +++ b/Src/timer/timermul.cpp @@ -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 diff --git a/Src/timer/timermul.h b/Src/timer/timermul.h new file mode 100644 index 00000000..67dcafb2 --- /dev/null +++ b/Src/timer/timermul.h @@ -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 diff --git a/Src/timer/tmultiplex.cpp b/Src/timer/tmultiplex.cpp new file mode 100644 index 00000000..e28b79d0 --- /dev/null +++ b/Src/timer/tmultiplex.cpp @@ -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; +} diff --git a/Src/timer/tmultiplex.h b/Src/timer/tmultiplex.h new file mode 100644 index 00000000..3ed426ba --- /dev/null +++ b/Src/timer/tmultiplex.h @@ -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 diff --git a/Src/timer/version.rc2 b/Src/timer/version.rc2 new file mode 100644 index 00000000..69e70a60 --- /dev/null +++ b/Src/timer/version.rc2 @@ -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 |