Changeset 3868


Ignore:
Timestamp:
Mar 15, 2015, 8:57:14 PM (7 years ago)
Author:
touky
Message:

Added Thread classes
Added InputProfile in Controller
Added ExecLuaCode

Location:
trunk
Files:
2 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/samples/Makefile.am

    r3788 r3868  
    4242nacl_phystest_LDFLAGS = $(AM_LDFLAGS)
    4343
    44 meshviewer_SOURCES = meshviewer.cpp \
     44meshviewer_SOURCES = meshviewer.cpp meshviewer.h \
    4545    shinymvtexture.lolfx shinyfur.lolfx \
    46     scenesetup.cpp scenesetup.h \
    47     scenesetup-compiler.cpp scenesetup-compiler.h \
    48     generated/scenesetup-scanner.cpp generated/scenesetup-scanner.h \
    49     generated/scenesetup-parser.cpp
     46    scenesetup.cpp scenesetup.h
    5047meshviewer_CPPFLAGS = $(AM_CPPFLAGS)
    5148meshviewer_DEPENDENCIES = @LOL_DEPS@
  • trunk/doc/samples/meshviewer.cpp

    r3866 r3868  
    1919#include <lol/engine.h>
    2020#include "scenesetup.h"
     21#include "meshviewer.h"
    2122
    2223using namespace lol;
     
    185186
    186187        //Scene setup
    187         m_setup_loader.ExecLua("meshviewer_init.lua");
     188        m_setup_loader.ExecLuaFile("meshviewer_init.lua");
    188189
    189190        //Compile ref meshes
  • trunk/doc/samples/meshviewer.vcxproj

    r3866 r3868  
    9292  </ItemGroup>
    9393  <ItemGroup>
     94    <ClInclude Include="meshviewer.h" />
    9495    <ClInclude Include="scenesetup.h" />
    9596  </ItemGroup>
  • trunk/doc/tutorial/05_easymesh.cpp

    r3864 r3868  
    2929    {
    3030        EasyMeshLuaLoader EzMhLoader;
    31         EzMhLoader.ExecLua("05_easymesh.lua");
     31        EzMhLoader.ExecLuaFile("05_easymesh.lua");
    3232
    3333        EasyMeshLuaObject* gears0 = EzMhLoader.GetPtr<EasyMeshLuaObject>("g0");
  • trunk/doc/tutorial/14_lol_lua.cpp

    r3865 r3868  
    153153
    154154        //Execute script
    155         demo_loader->ExecLua("14_lol_lua.lua");
     155        demo_loader->ExecLuaFile("14_lol_lua.lua");
    156156        demo_loader->TestStuff();
    157157
  • trunk/src/Makefile.am

    r3861 r3868  
    110110    sys/init.cpp sys/timer.cpp sys/file.cpp sys/hacks.cpp \
    111111    sys/thread.cpp sys/threadbase.h \
     112        sys/threadtypes.cpp \
    112113    \
    113114    image/image.cpp image/image-private.h image/kernel.cpp image/pixel.cpp \
  • trunk/src/application/application.cpp

    r3849 r3868  
    7373{
    7474    data = new ApplicationData(name, resolution, framerate);
    75     g_world.ExecLua("lua/init.lua");
     75    g_world.ExecLuaFile("lua/init.lua");
    7676}
    7777
  • trunk/src/input/controller.cpp

    r3843 r3868  
    226226array<Controller*> Controller::controllers;
    227227
     228//-----------------------------------------------------------------------------
    228229Controller::Controller(String const &name, int nb_keys, int nb_axis)
    229230{
     
    242243}
    243244
     245Controller::Controller(String const &name, InputProfile const& profile)
     246    : Controller(name, 0, 0)
     247{
     248    Init(profile);
     249}
     250
    244251Controller::~Controller()
    245252{
     253    ClearProfile();
    246254    for (int i = 0; i < controllers.Count(); ++i)
    247255    {
     
    254262}
    255263
     264//-----------------------------------------------------------------------------
    256265Controller* Controller::Get(String const &name)
    257266{
     
    264273}
    265274
     275//Input profile system --------------------------------------------------------
     276void Controller::UnbindProfile()
     277{
     278    if (m_profile.IsEmpty())
     279        return;
     280
     281    m_mutex.lock();
     282
     283    //Keyboard
     284    if (m_keyboard)
     285    {
     286        for (InputProfile::Keyboard& key : m_profile.m_keys)
     287            GetKey(key.m_idx).UnbindKeyboard(key.m_name);
     288        m_keyboard = nullptr;
     289    }
     290
     291    //Mouse
     292    if (m_mouse)
     293    {
     294        for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
     295            GetKey(key.m_idx).UnbindMouse(key.m_name);
     296        for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
     297            GetAxis(axis.m_idx).UnbindMouse(axis.m_name);
     298        m_mouse = nullptr;
     299    }
     300
     301    //Joystick
     302    for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
     303    {
     304        if (m_joystick_idx.Find(key.m_joy) != INDEX_NONE)
     305            GetKey(key.m_idx).UnbindJoystick(key.m_joy, key.m_name);
     306    }
     307    for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
     308    {
     309        if (m_joystick_idx.Find(axis.m_joy) != INDEX_NONE)
     310            GetAxis(axis.m_idx).UnbindJoystick(axis.m_joy, axis.m_name);
     311    }
     312    m_joystick.Empty();
     313    m_joystick_idx.Empty();
     314
     315    m_mutex.unlock();
     316}
     317//Input profile system --------------------------------------------------------
     318void Controller::BindProfile(InputProfile const& setup)
     319{
     320    ASSERT(!setup.IsEmpty());
     321
     322    m_mutex.lock();
     323    m_profile = setup;
     324
     325    m_keys.Resize(m_profile.GetKeyCount());
     326    m_axis.Resize(m_profile.GetAxisCount());
     327
     328    //Keyboard
     329    m_keyboard = InputDevice::GetKeyboard();
     330    if (m_keyboard)
     331    {
     332        for (InputProfile::Keyboard& key : m_profile.m_keys)
     333            GetKey(key.m_idx).BindKeyboard(key.m_name);
     334    }
     335
     336    //Mouse
     337    m_mouse = InputDevice::GetMouse();
     338    if (m_mouse)
     339    {
     340        for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
     341            GetKey(key.m_idx).BindMouse(key.m_name);
     342        for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
     343            GetAxis(axis.m_idx).BindMouse(axis.m_name);
     344    }
     345
     346    //Joystick
     347    for (uint64_t joy_idx : m_profile.m_joystick)
     348    {
     349        class InputDevice* joystick = InputDevice::GetJoystick(joy_idx);
     350        if (joystick)
     351        {
     352            m_joystick << joystick;
     353            m_joystick_idx << joy_idx;
     354        }
     355    }
     356    for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
     357    {
     358        if (m_joystick_idx.Find(key.m_joy) != INDEX_NONE)
     359            GetKey(key.m_idx).BindJoystick(key.m_joy, key.m_name);
     360    }
     361    for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
     362    {
     363        if (m_joystick_idx.Find(axis.m_joy) != INDEX_NONE)
     364            GetAxis(axis.m_idx).BindJoystick(axis.m_joy, axis.m_name);
     365    }
     366
     367    m_mutex.unlock();
     368}
     369
     370//-----------------------------------------------------------------------------
    266371void Controller::TickGame(float seconds)
    267372{
     
    287392}
    288393
     394//-----------------------------------------------------------------------------
    289395void Controller::Activate()
    290396{
     
    299405}
    300406
     407//-----------------------------------------------------------------------------
    301408array<Controller*> Controller::DeactivateAll()
    302409{
  • trunk/src/input/controller.h

    r3840 r3868  
    134134};
    135135
     136//-------------------------------------------------------------------------
     137class InputProfile
     138{
     139    friend class Controller;
     140private:
     141    //---------------------------------------------------------------------
     142    class Key
     143    {
     144        friend class Controller;
     145        friend class InputProfile;
     146    public:
     147        Key() { }
     148        Key(int idx, String const& name) : m_idx(idx), m_name(name) { }
     149        Key(const Key& other) : m_idx(other.m_idx), m_name(other.m_name) { }
     150        ~Key() { }
     151        bool operator==(const Key& other) { return m_name == other.m_name; }
     152    private:
     153        int m_idx = 0;
     154        String m_name;
     155    };
     156    //---------------------------------------------------------------------
     157    class Joystick
     158    {
     159        friend class Controller;
     160        friend class InputProfile;
     161    public:
     162        Joystick() { }
     163        Joystick(uint64_t joy, int idx, String const& name) : m_joy(joy), m_idx(idx), m_name(name) { }
     164        Joystick(const Joystick& other) : m_joy(other.m_joy), m_idx(other.m_idx), m_name(other.m_name) { }
     165        ~Joystick() { }
     166        bool operator==(const Joystick& other) { return m_name == other.m_name; }
     167    private:
     168        uint64_t m_joy = 0;
     169        int m_idx = 0;
     170        String m_name;
     171    };
     172public:
     173    //---------------------------------------------------------------------
     174    class Keyboard : public Key
     175    {
     176        friend class Controller;
     177        friend class InputProfile;
     178    public:
     179        Keyboard() : Key() { }
     180        Keyboard(int idx, String const& name) : Key(idx, name) { }
     181        Keyboard(const Keyboard& other) : Key(other.m_idx, other.m_name) { }
     182    };
     183    //---------------------------------------------------------------------
     184    class MouseKey : public Key
     185    {
     186        friend class Controller;
     187        friend class InputProfile;
     188    public:
     189        MouseKey() : Key() { }
     190        MouseKey(int idx, String const& name) : Key(idx, name) { }
     191        MouseKey(const Keyboard& other) : Key(other.m_idx, other.m_name) { }
     192    };
     193    //---------------------------------------------------------------------
     194    class MouseAxis : public Key
     195    {
     196        friend class Controller;
     197        friend class InputProfile;
     198    public:
     199        MouseAxis() : Key() { }
     200        MouseAxis(int idx, String const& name) : Key(idx, name) { }
     201        MouseAxis(const Keyboard& other) : Key(other.m_idx, other.m_name) { }
     202    };
     203    //---------------------------------------------------------------------
     204    class JoystickKey : public Joystick
     205    {
     206        friend class Controller;
     207        friend class InputProfile;
     208    public:
     209        JoystickKey() : Joystick() { }
     210        JoystickKey(uint64_t joy, int idx, String const& name) : Joystick(joy, idx, name) { }
     211        JoystickKey(const JoystickKey& other) : Joystick(other.m_joy, other.m_idx, other.m_name) { }
     212    };
     213    //---------------------------------------------------------------------
     214    class JoystickAxis : public Joystick
     215    {
     216        friend class Controller;
     217        friend class InputProfile;
     218    public:
     219        JoystickAxis() : Joystick() { }
     220        JoystickAxis(uint64_t joy, int idx, String const& name) : Joystick(joy, idx, name) { }
     221        JoystickAxis(const JoystickAxis& other) : Joystick(other.m_joy, other.m_idx, other.m_name) { }
     222    };
     223public:
     224    InputProfile() { }
     225    InputProfile(const InputProfile& other)
     226    {
     227        m_keys = other.m_keys;
     228        m_mouse_keys = other.m_mouse_keys;
     229        m_mouse_axis = other.m_mouse_axis;
     230        m_joystick = other.m_joystick;
     231        m_joystick_keys = other.m_joystick_keys;
     232        m_joystick_axis = other.m_joystick_axis;
     233    }
     234    virtual ~InputProfile() { }
     235
     236    bool IsEmpty() const
     237    {
     238        return !(GetKeyCount() && GetAxisCount());
     239    }
     240    int GetKeyCount() const
     241    {
     242        return (int)(m_keys.Count() + m_mouse_keys.Count() + m_joystick_keys.Count());
     243    }
     244    int GetAxisCount() const
     245    {
     246        return (int)(m_mouse_axis.Count() + m_joystick_axis.Count());
     247    }
     248    InputProfile& operator<<(InputProfile::Keyboard const& binding)
     249    {
     250        m_keys.PushUnique(binding);
     251        return *this;
     252    }
     253    InputProfile& operator<<(array<InputProfile::Keyboard> const& bindings)
     254    {
     255        m_keys += bindings;
     256        return *this;
     257    }
     258    InputProfile& operator<<(InputProfile::MouseKey const& binding)
     259    {
     260        m_mouse_keys.PushUnique(binding);
     261        return *this;
     262    }
     263    InputProfile& operator<<(array<InputProfile::MouseKey> const& bindings)
     264    {
     265        m_mouse_keys += bindings;
     266        return *this;
     267    }
     268    InputProfile& operator<<(InputProfile::MouseAxis const& binding)
     269    {
     270        m_mouse_axis.PushUnique(binding);
     271        return *this;
     272    }
     273    InputProfile& operator<<(array<InputProfile::MouseAxis> const& bindings)
     274    {
     275        m_mouse_axis += bindings;
     276        return *this;
     277    }
     278    InputProfile& operator<<(InputProfile::JoystickKey const& binding)
     279    {
     280        m_joystick.PushUnique(binding.m_joy);
     281        m_joystick_keys.PushUnique(binding);
     282        return *this;
     283    }
     284    InputProfile& operator<<(array<InputProfile::JoystickKey> const& bindings)
     285    {
     286        for (InputProfile::JoystickKey const& binding : bindings)
     287            m_joystick.PushUnique(binding.m_joy);
     288        m_joystick_keys += bindings;
     289        return *this;
     290    }
     291    InputProfile& operator<<(InputProfile::JoystickAxis const& binding)
     292    {
     293        m_joystick.PushUnique(binding.m_joy);
     294        m_joystick_axis.PushUnique(binding);
     295        return *this;
     296    }
     297    InputProfile& operator<<(array<InputProfile::JoystickAxis> const& bindings)
     298    {
     299        for (InputProfile::JoystickAxis const& binding : bindings)
     300            m_joystick.PushUnique(binding.m_joy);
     301        m_joystick_axis += bindings;
     302        return *this;
     303    }
     304
     305private:
     306    array<Keyboard>     m_keys;
     307    array<MouseKey>     m_mouse_keys;
     308    array<MouseAxis>    m_mouse_axis;
     309    array<uint64_t>     m_joystick;
     310    array<JoystickKey>  m_joystick_keys;
     311    array<JoystickAxis> m_joystick_axis;
     312};
     313
    136314//-----------------------------------------------------------------------------
    137315class Controller : public Entity
    138316{
    139317public:
    140     Controller(String const &name, int nb_keys, int nb_axis);
     318    Controller(String const &name, int nb_keys = 0, int nb_axis = 0);
     319    Controller(String const &name, InputProfile const& setup);
    141320    virtual ~Controller();
    142321
     
    150329    static array<Controller*> DeactivateAll();
    151330
     331    /** Input profile system */
     332    void Init(InputProfile const& profile)
     333    {
     334        UnbindProfile();
     335        BindProfile(profile);
     336    }
     337    void ClearProfile()
     338    {
     339        UnbindProfile();
     340    }
     341
     342    /** GetKeys/Axis stuff */
    152343    KeyBinding& GetKey(int index) { return m_keys[index]; }
    153344    AxisBinding& GetAxis(int index) { return m_axis[index]; }
     
    156347
    157348protected:
     349    /** Input profile system */
     350    void UnbindProfile();
     351    void BindProfile(InputProfile const& setup);
     352
     353private:
    158354    array<KeyBinding> m_keys;
    159355    array<AxisBinding> m_axis;
    160356
    161 private:
    162357    static array<Controller*> controllers;
    163358    String m_name;
     
    165360    bool m_deactivate_nextframe;
    166361    bool m_active;
     362
     363    //Input profile stuff
     364    mutex m_mutex;
     365    class InputProfile m_profile;
     366    class InputDevice* m_keyboard = nullptr;
     367    class InputDevice* m_mouse = nullptr;
     368    array<class InputDevice*> m_joystick;
     369    array<uint64_t> m_joystick_idx;
    167370};
    168371
  • trunk/src/lol/sys/all.h

    r3580 r3868  
    1212
    1313#include <lol/sys/thread.h>
     14#include <lol/sys/threadtypes.h>
    1415#include <lol/sys/init.h>
    1516#include <lol/sys/file.h>
  • trunk/src/lol/sys/file.h

    r3816 r3868  
    8383    void SetPosFromStart(long int pos);
    8484    long int GetSize();
     85    long int GetModificationTime();
    8586
    8687private:
  • trunk/src/lol/sys/thread.h

    r3816 r3868  
    3939};
    4040
    41 #if LOL_FEATURE_THREADS
    4241class thread : thread_base
    4342{
     
    9291typedef SafeEnum<ThreadJobTypeBase> ThreadJobType;
    9392
     93//ThreadJob -------------------------------------------------------------------
    9494class ThreadJob
    9595{
     
    110110};
    111111
    112 //Base class for thread manager
     112//Base class for thread manager -----------------------------------------------
    113113class BaseThreadManager : public Entity
    114114{
    115115public:
    116116    BaseThreadManager(int thread_count);
     117    BaseThreadManager(int thread_count, int thread_min);
    117118    ~BaseThreadManager();
    118119
     
    123124    //Stop the threads
    124125    bool Stop();
     126
     127    //Children class intergace
     128    virtual bool AddJob(ThreadJob* job) { ASSERT(false); return false; }
     129    virtual bool GetWorkResult(array<ThreadJob*>& results) { ASSERT(false); return false; }
     130
    125131protected:
     132    //Thread addition
     133    void AddThreads(int nb);
     134    void StopThreads(int nb);
     135
    126136    //Work stuff
    127137    bool AddWork(ThreadJob* job);
     
    138148    /* Worker threads */
    139149    int                 m_thread_count;
     150    int                 m_thread_min;
    140151    array<thread*>      m_threads;
    141152    queue<ThreadStatus> m_spawnqueue, m_donequeue;
     
    145156};
    146157
    147 //Generic class for thread manager, executes work and store results, for you to use
    148 class GenericThreadManager : public BaseThreadManager
    149 {
    150 public:
    151     GenericThreadManager(int thread_count)
    152         : BaseThreadManager(thread_count) { }
    153 
    154     char const *GetName() { return "<GenericThreadManager>"; }
    155 
    156     //Work stuff
    157     bool AddJob(ThreadJob* job) { return AddWork(job); }
    158     bool GetWorkResult(array<ThreadJob*>& results)
    159     {
    160         results += m_job_result;
    161         m_job_result.Empty();
    162         return results.Count() > 0;
    163     }
    164 
    165 protected:
    166     virtual void TreatResult(ThreadJob* result) { m_job_result << result; }
    167 
    168     array<ThreadJob*>       m_job_result;
    169 };
    170 #endif
    171 
    172158} /* namespace lol */
    173159
  • trunk/src/lolcore.vcxproj

    r3861 r3868  
    223223    <ClCompile Include="sys\init.cpp" />
    224224    <ClCompile Include="sys\thread.cpp" />
     225    <ClCompile Include="sys\threadtypes.cpp" />
    225226    <ClCompile Include="sys\timer.cpp" />
    226227    <ClCompile Include="text.cpp" />
     
    320321    <ClInclude Include="lol\sys\init.h" />
    321322    <ClInclude Include="lol\sys\thread.h" />
     323    <ClInclude Include="lol\sys\threadtypes.h" />
    322324    <ClInclude Include="lol\sys\timer.h" />
    323325    <ClInclude Include="lol\unit.h" />
  • trunk/src/lolcore.vcxproj.filters

    r3861 r3868  
    413413      <Filter>lolua</Filter>
    414414    </ClCompile>
     415    <ClCompile Include="sys\threadtypes.cpp">
     416      <Filter>sys</Filter>
     417    </ClCompile>
    415418  </ItemGroup>
    416419  <ItemGroup>
     
    769772    <ClInclude Include="lolua\baselua.h">
    770773      <Filter>lolua</Filter>
     774    </ClInclude>
     775    <ClInclude Include="lol\sys\threadtypes.h">
     776      <Filter>lol\sys</Filter>
    771777    </ClInclude>
    772778  </ItemGroup>
  • trunk/src/lolua/baselua.cpp

    r3864 r3868  
    3434    }
    3535
     36    static int LuaDoCode(LuaState *l, String const& s)
     37    {
     38        return luaL_dostring(l, s.C());
     39    }
     40
    3641    static int LuaDoFile(LuaState *l)
    3742    {
     
    5459
    5560                Log::Debug("loading Lua file %s\n", pathlist[i].C());
    56                 status = luaL_dostring(l, s.C());
     61                status = LuaDoCode(l, s);
    5762                break;
    5863            }
     
    95100
    96101//-----------------------------------------------------------------------------
    97 bool Loader::ExecLua(String const &lua)
     102bool Loader::ExecLuaFile(String const &lua)
    98103{
    99104    const char* c = lua_pushstring(m_lua_state, lua.C());
    100105    int status = LuaBaseData::LuaDoFile(m_lua_state);
    101106    return status == 0;
     107}
     108
     109//-----------------------------------------------------------------------------
     110bool Loader::ExecLuaCode(String const &lua)
     111{
     112    return 0 == LuaBaseData::LuaDoCode(m_lua_state, lua);
    102113}
    103114
  • trunk/src/lolua/baselua.h

    r3866 r3868  
    5555
    5656    ObjectLib(String class_name,
    57         array<ClassMethod> statics,
    58         array<ClassMethod> methods,
    59         array<ClassVar> variables)
     57        array<ClassMethod> const& statics,
     58        array<ClassMethod> const& methods,
     59        array<ClassVar> const& variables)
    6060    {
    6161        m_class_name = class_name;
     
    7575            m_methods.Push({ nullptr, nullptr });
    7676
    77         for (ClassVar& cv : variables)
     77        for (ClassVar const& cv : variables)
    7878        {
    7979            if (cv.name && cv.get && cv.set)
     
    935935    virtual ~Loader();
    936936
    937     bool ExecLua(String const &lua);
     937    bool ExecLuaFile(String const &lua);
     938    bool ExecLuaCode(String const &lua);
    938939
    939940    template<typename T>
  • trunk/src/sys/file.cpp

    r3843 r3868  
    193193    }
    194194
    195 
     195    long int GetModificationTime()
     196    {
     197#if __ANDROID__
     198        return 0;
     199#elif HAVE_STDIO_H
     200        return m_stat.st_mtime;
     201#else
     202        return 0;
     203#endif
     204    }
     205
     206    //-----------------------
    196207#if __ANDROID__
    197208    AAsset *m_asset;
     
    313324{
    314325    return m_data->GetSize();
     326}
     327
     328//--
     329long int File::GetModificationTime()
     330{
     331    return m_data->GetModificationTime();
    315332}
    316333
  • trunk/src/sys/thread.cpp

    r3775 r3868  
    1717{
    1818
    19 #if LOL_FEATURE_THREADS
     19//BaseThreadManager -----------------------------------------------------------
    2020BaseThreadManager::BaseThreadManager(int thread_count)
    2121{
     22    m_thread_min = thread_count;
     23    m_thread_count = thread_count;
     24}
     25
     26BaseThreadManager::BaseThreadManager(int thread_min, int thread_count)
     27{
     28    m_thread_min = thread_min;
    2229    m_thread_count = thread_count;
    2330}
     
    3138bool BaseThreadManager::Start()
    3239{
    33     if (m_threads.Count() > 0)
     40    if (m_threads.count() > 0)
    3441        return false;
    3542
    36     /* Spawn worker threads and wait for their readiness. */
     43    //Add minimum threads
    3744    m_threads.Resize(m_thread_count);
    38     for (int i = 0; i < m_thread_count; i++)
    39         m_threads[i] = new thread(std::bind(&BaseThreadManager::BaseThreadWork,
    40                                             this));
    41     for (int i = 0; i < m_thread_count; i++)
    42         m_spawnqueue.pop();
     45    AddThreads(m_thread_min);
    4346
    4447    return true;
     
    4851bool BaseThreadManager::Stop()
    4952{
    50     if (m_threads.Count() <= 0)
     53    if (m_threads.count() <= 0)
    5154        return false;
    5255
    53     /* Signal worker threads for completion and wait for
    54         * them to quit. */
    55     ThreadJob stop_job(ThreadJobType::THREAD_STOP);
    56     for (int i = 0; i < m_thread_count; i++)
    57         m_jobqueue.push(&stop_job);
    58     for (int i = 0; i < m_thread_count; i++)
    59         m_donequeue.pop();
     56    //Stop all threads
     57    StopThreads(m_threads.count());
    6058
    6159    return true;
     60}
     61
     62//----
     63void BaseThreadManager::AddThreads(int nb)
     64{
     65    //Don't add threads if not availables
     66#if LOL_FEATURE_THREADS
     67    //Spawn worker threads and ...
     68    for (int i = 0; i < nb; i++)
     69        m_threads << new thread(std::bind(&BaseThreadManager::BaseThreadWork, this));
     70
     71    //... Wait for their readiness.
     72    for (int i = 0; i < m_thread_count; i++)
     73        m_spawnqueue.pop();
     74#endif //LOL_FEATURE_THREADS
     75}
     76
     77//----
     78void BaseThreadManager::StopThreads(int nb)
     79{
     80    //Don't stop threads if not availables
     81#if LOL_FEATURE_THREADS
     82    //Signal worker threads for completion and ...
     83    ThreadJob stop_job(ThreadJobType::THREAD_STOP);
     84    for (int i = 0; i < nb; i++)
     85        m_jobqueue.push(&stop_job);
     86   
     87    //... Wait for them to quit.
     88    for (int i = 0; i < nb; i++)
     89        m_donequeue.pop();
     90#endif //LOL_FEATURE_THREADS
    6291}
    6392
     
    7099}
    71100
     101//----
    72102bool BaseThreadManager::FetchResult(array<ThreadJob*>& results)
    73103{
     
    75105    while (m_resultqueue.try_pop(result))
    76106        results << result;
    77     return results.Count() > 0;
     107    return results.count() > 0;
    78108}
    79109
     
    81111void BaseThreadManager::BaseThreadWork()
    82112{
     113#if !LOL_FEATURE_THREADS
     114    //Register that the thread has started
    83115    m_spawnqueue.push(ThreadStatus::THREAD_STARTED);
    84116    for ( ; ; )
     117#endif //!LOL_FEATURE_THREADS
    85118    {
     119        //Try to retrieve a job
    86120        ThreadJob* job = m_jobqueue.pop();
     121        //Stop thread
    87122        if (job->GetJobType() == ThreadJobType::THREAD_STOP)
     123        {
     124#if !LOL_FEATURE_THREADS
    88125            break;
     126#endif //!LOL_FEATURE_THREADS
     127        }
     128        //Or work
    89129        else if (*job == ThreadJobType::WORK_TODO)
    90130        {
     
    96136        }
    97137    }
     138#if !LOL_FEATURE_THREADS
     139    //Register that the thread has stopped
    98140    m_donequeue.push(ThreadStatus::THREAD_STOPPED);
     141#endif //!LOL_FEATURE_THREADS
    99142}
    100143
     144//----
    101145void BaseThreadManager::TickGame(float seconds)
    102146{
     
    110154        m_job_dispatch.pop();
    111155
     156    //Execute one task per frame if thread are not available
     157#if !LOL_FEATURE_THREADS
     158    BaseThreadWork();
     159#endif // !LOL_FEATURE_THREADS
     160
    112161    array<ThreadJob*> result;
    113162    //Fetch and treat results
    114163    if (FetchResult(result))
    115164    {
    116         for (int i = 0; i < result.Count(); i++)
     165        for (int i = 0; i < result.count(); i++)
    117166        {
    118167            ThreadJob* job = result[i];
     
    124173        }
    125174    }
     175
     176    //Resize thread count if needed
     177    if (m_threads.count() > m_jobqueue.count() && m_threads.count() > m_thread_min)
     178        StopThreads(m_threads.Count() - m_thread_min);
     179    else if (m_threads.count() < m_jobqueue.count())
     180        AddThreads(lol::min(m_jobqueue.count(), (ptrdiff_t)m_thread_count) - m_threads.count());
    126181}
    127 #endif //LOL_FEATURE_THREADS
    128182
    129183} /* namespace lol */
  • trunk/src/sys/threadbase.h

    r3777 r3868  
    113113        DeleteCriticalSection(&m_mutex);
    114114#endif
     115    }
     116
     117    ptrdiff_t count()
     118    {
     119        ptrdiff_t current_count = 0;
     120#if defined HAVE_PTHREAD_H
     121        pthread_mutex_lock(&m_mutex);
     122        /* If queue is full, wait on the "full" cond var. */
     123        m_pushers++;
     124        while (m_count == CAPACITY)
     125            pthread_cond_wait(&m_full_cond, &m_mutex);
     126        m_pushers--;
     127#elif defined _WIN32
     128        WaitForSingleObject(m_empty_sem, INFINITE);
     129        EnterCriticalSection(&m_mutex);
     130#endif
     131
     132        current_count = (ptrdiff_t)m_count;
     133
     134#if defined HAVE_PTHREAD_H
     135        /* If there were poppers waiting, signal the "empty" cond var. */
     136        if (m_poppers)
     137            pthread_cond_signal(&m_empty_cond);
     138        pthread_mutex_unlock(&m_mutex);
     139#elif defined _WIN32
     140        LeaveCriticalSection(&m_mutex);
     141        ReleaseSemaphore(m_full_sem, 1, nullptr);
     142#endif
     143        return current_count;
     144    }
     145
     146    ptrdiff_t try_count()
     147    {
     148        ptrdiff_t current_count = 0;
     149
     150#if defined HAVE_PTHREAD_H
     151        pthread_mutex_lock(&m_mutex);
     152        /* If queue is full, wait on the "full" cond var. */
     153        if (m_count == CAPACITY)
     154        {
     155            pthread_mutex_unlock(&m_mutex);
     156            return false;
     157        }
     158#elif defined _WIN32
     159        DWORD status = WaitForSingleObject(m_empty_sem, 0);
     160        if (status == WAIT_TIMEOUT)
     161            return 0;
     162        EnterCriticalSection(&m_mutex);
     163#endif
     164
     165        current_count = (ptrdiff_t)m_count;
     166
     167#if defined HAVE_PTHREAD_H
     168        /* If there were poppers waiting, signal the "empty" cond var. */
     169        if (m_poppers)
     170            pthread_cond_signal(&m_empty_cond);
     171        pthread_mutex_unlock(&m_mutex);
     172#elif defined _WIN32
     173        LeaveCriticalSection(&m_mutex);
     174        ReleaseSemaphore(m_full_sem, 1, nullptr);
     175#endif
     176        return current_count;
    115177    }
    116178
Note: See TracChangeset for help on using the changeset viewer.