Skip to content

Commit

Permalink
a little refactor with C++20 Cencept.
Browse files Browse the repository at this point in the history
  • Loading branch information
pigpigyyy committed Nov 22, 2023
1 parent 54aa919 commit 381884d
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 65 deletions.
8 changes: 7 additions & 1 deletion Assets/Script/Dev/Entry.yue
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,14 @@ updateEntries = ->
allEntries[] = example
for test in *tests
allEntries[] = test
for game in *games
allEntries[] = game
[_, _, examples, tests] = game
for example in *examples
doraExamples[] = example
for test in *tests
doraTests[] = test
for group in *[
games
doraExamples
doraTests
cppTests
Expand Down
10 changes: 0 additions & 10 deletions Source/Basic/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,6 @@ uint32_t Object::getRefCount() const {
return _refCount;
}

bool Object::update(double deltaTime) {
DORA_UNUSED_PARAM(deltaTime);
return true;
}

bool Object::fixedUpdate(double deltaTime) {
DORA_UNUSED_PARAM(deltaTime);
return true;
}

void Object::cleanup() {
if (_weak) _weak->target = nullptr;
}
Expand Down
2 changes: 0 additions & 2 deletions Source/Basic/Object.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ class Object {
virtual ~Object();
virtual bool init();
/** @brief return true to stop updating, false to continue. */
virtual bool update(double deltaTime);
virtual bool fixedUpdate(double deltaTime);
virtual void cleanup();
void release();
void retain();
Expand Down
57 changes: 30 additions & 27 deletions Source/Basic/Scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,26 @@ NS_DOROTHY_BEGIN

/* Scheduler */

class FuncWrapper : public Object {
class FuncWrapperBase : public Object {
public:
virtual bool update(double deltaTime) override {
FuncWrapperBase(const std::function<bool(double)>& func)
: func(func) { }
bool update(double deltaTime) {
return func(deltaTime);
}
std::function<bool(double)> func;
ScheduledItem item;
CREATE_FUNC(FuncWrapper);
};

protected:
class FuncWrapper : public FuncWrapperBase {
public:
FuncWrapper(const std::function<bool(double)>& func)
: func(func)
: FuncWrapperBase(func)
, item(this) { }
ScheduledItemWrapper<FuncWrapperBase> item;
CREATE_FUNC(FuncWrapper)
DORA_TYPE_OVERRIDE(FuncWrapper);
};

std::vector<std::pair<Ref<Object>, ScheduledItem*>> Scheduler::_updateObjects;

Scheduler::Scheduler()
: _fixedFPS(60)
, _deltaTime(0.0)
Expand Down Expand Up @@ -79,7 +81,7 @@ void Scheduler::schedule(ScheduledItem* item) {
item->iter = _updateList.emplace(_updateList.end(), item);
}

void Scheduler::scheduleFixed(ScheduledItem* item) {
void Scheduler::scheduleFixed(FixedScheduledItem* item) {
AssertIf(item->iter, "target item is already scheduled");
item->target->retain();
item->iter = _fixedUpdateList.emplace(_fixedUpdateList.end(), item);
Expand All @@ -99,7 +101,7 @@ void Scheduler::unschedule(ScheduledItem* item) {
}
}

void Scheduler::unscheduleFixed(ScheduledItem* item) {
void Scheduler::unscheduleFixed(FixedScheduledItem* item) {
if (item->iter) {
_fixedUpdateList.erase(item->iter.value());
item->target->release();
Expand Down Expand Up @@ -139,19 +141,20 @@ bool Scheduler::update(double deltaTime) {
_deltaTime = deltaTime * _timeScale;
_leftTime += deltaTime;

static std::vector<std::pair<Ref<Object>, FixedScheduledItem*>> fixedUpdateObjects;
double fixedDelta = 1.0 / _fixedFPS;
double fixedDeltaTime = fixedDelta * _timeScale;
while (_leftTime > fixedDelta) {
_updateObjects.reserve(_fixedUpdateList.size());
fixedUpdateObjects.reserve(_fixedUpdateList.size());
for (auto item : _fixedUpdateList) {
_updateObjects.emplace_back(item->target, item);
fixedUpdateObjects.emplace_back(item->target, item);
}
for (const auto& updateObject : _updateObjects) {
if (updateObject.first->fixedUpdate(fixedDeltaTime)) {
unscheduleFixed(updateObject.second);
for (const auto& fixedUpdateObject : fixedUpdateObjects) {
if (fixedUpdateObject.second->fixedUpdate(fixedDeltaTime)) {
unscheduleFixed(fixedUpdateObject.second);
}
}
_updateObjects.clear();
fixedUpdateObjects.clear();
_leftTime -= fixedDelta;
}

Expand Down Expand Up @@ -190,31 +193,31 @@ bool Scheduler::update(double deltaTime) {
}

/* update scheduled items */
_updateObjects.reserve(_updateList.size());
static std::vector<std::pair<Ref<Object>, ScheduledItem*>> updateObjects;
updateObjects.reserve(_updateList.size());
for (auto item : _updateList) {
_updateObjects.emplace_back(item->target, item);
updateObjects.emplace_back(item->target, item);
}
for (const auto& updateObject : _updateObjects) {
if (updateObject.first->update(deltaTime)) {
for (const auto& updateObject : updateObjects) {
if (updateObject.second->update(deltaTime)) {
unschedule(updateObject.second);
}
}
_updateObjects.clear();
updateObjects.clear();
return false;
}

/* SystemTimer */

SystemTimer::SystemTimer()
SystemTimerBase::SystemTimerBase()
: _time(0)
, _duration(0)
, _scheduledItem(this) { }
, _duration(0) { }

bool SystemTimer::isRunning() const {
bool SystemTimerBase::isRunning() const {
return _time < _duration;
}

bool SystemTimer::update(double deltaTime) {
bool SystemTimerBase::update(double deltaTime) {
_time += s_cast<float>(deltaTime);
if (_time >= _duration) {
if (_callback) {
Expand All @@ -233,7 +236,7 @@ void SystemTimer::start(float duration, const std::function<void()>& callback) {
SharedDirector.getSystemScheduler()->schedule(&_scheduledItem);
}

void SystemTimer::stop() {
void SystemTimerBase::stop() {
_time = _duration = 0.0f;
_callback = nullptr;
}
Expand Down
92 changes: 75 additions & 17 deletions Source/Basic/Scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,67 +16,125 @@ class Array;

class ScheduledItem;

typedef std::list<ScheduledItem*> UpdateList;
typedef std::optional<std::list<ScheduledItem*>::iterator> UpdateIter;
using UpdateList = std::list<ScheduledItem*>;
using UpdateIter = std::optional<std::list<ScheduledItem*>::iterator>;

class ScheduledItem {
public:
ScheduledItem(Object* target)
: target(target) { }
virtual ~ScheduledItem() { }
Object* target;
UpdateIter iter;

virtual bool update(double deltaTime) = 0;
};

class Scheduler : public Object {
template <class T>
concept Updatable = requires(T t) {
std::is_base_of_v<Object, T>;
{ t.update(double()) } -> std::same_as<bool>;
};

template <Updatable T>
class ScheduledItemWrapper : public ScheduledItem {
public:
ScheduledItemWrapper(Updatable auto* item)
: ScheduledItem(item) { }

virtual bool update(double deltaTime) override {
return static_cast<T*>(target)->update(deltaTime);
}
};

class FixedScheduledItem;

using FixedUpdateList = std::list<FixedScheduledItem*>;
using FixedUpdateIter = std::optional<std::list<FixedScheduledItem*>::iterator>;

class FixedScheduledItem {
public:
FixedScheduledItem(Object* target)
: target(target) { }
virtual ~FixedScheduledItem() { }
Object* target;
FixedUpdateIter iter;

virtual bool fixedUpdate(double deltaTime) = 0;
};

template <class T>
concept FixedUpdatable = requires(T t) {
std::is_base_of_v<Object, T>;
{ t.fixedUpdate(double()) } -> std::same_as<bool>;
};

template <Updatable T>
class FixedScheduledItemWrapper : public FixedScheduledItem {
public:
FixedScheduledItemWrapper(Updatable auto* item)
: FixedScheduledItem(item) { }

virtual bool fixedUpdate(double deltaTime) override {
return static_cast<T*>(target)->fixedUpdate(deltaTime);
}
};

class Scheduler : public Object {
public:
virtual ~Scheduler();
PROPERTY(float, TimeScale);
PROPERTY(int, FixedFPS);
PROPERTY_READONLY(double, DeltaTime);
void schedule(ScheduledItem* item);
void scheduleFixed(ScheduledItem* item);
void scheduleFixed(FixedScheduledItem* item);
void schedule(const std::function<bool(double)>& handler);
void schedule(Action* action);
void unschedule(ScheduledItem* item);
void unscheduleFixed(ScheduledItem* item);
void unscheduleFixed(FixedScheduledItem* item);
void unschedule(Action* action);
virtual bool update(double deltaTime) override;
bool update(double deltaTime);
CREATE_FUNC(Scheduler);

protected:
Scheduler();
virtual ~Scheduler();

private:
int _fixedFPS;
float _timeScale;
double _deltaTime;
double _leftTime;
UpdateList _updateList;
UpdateList _fixedUpdateList;
FixedUpdateList _fixedUpdateList;
Ref<Array> _actionList;

private:
static std::vector<std::pair<Ref<Object>, ScheduledItem*>> _updateObjects;
DORA_TYPE_OVERRIDE(Scheduler);
};

class SystemTimer : public Object {
class SystemTimerBase : public Object {
public:
PROPERTY_BOOL(Running);
virtual bool update(double deltaTime) override;
void start(float duration, const std::function<void()>& callback);
bool update(double deltaTime);
void stop();
CREATE_FUNC(SystemTimer);

protected:
SystemTimer();

private:
SystemTimerBase();
float _time;
float _duration;
ScheduledItem _scheduledItem;
std::function<void()> _callback;
};

class SystemTimer : public SystemTimerBase {
public:
void start(float duration, const std::function<void()>& callback);
CREATE_FUNC(SystemTimer);

protected:
SystemTimer()
: SystemTimerBase()
, _scheduledItem(this) { }
ScheduledItemWrapper<SystemTimerBase> _scheduledItem;
DORA_TYPE_OVERRIDE(SystemTimer);
};

Expand Down
2 changes: 1 addition & 1 deletion Source/Common/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ typedef Slice String;
MyItem();
MyItem(int value);
virtual bool init() override;
CREATE_FUNC(MyItem)
CREATE_FUNC(MyItem);
};
// Use the create functions
Expand Down
6 changes: 3 additions & 3 deletions Source/Node/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -665,15 +665,15 @@ TouchHandler* Node::getTouchHandler() const {
Node::UpdateItem* Node::getUpdateItem() {
if (!_updateItem) {
_updateItem = New<Node::UpdateItem>();
_updateItem->scheduledItem = New<ScheduledItem>(this);
_updateItem->scheduledItem = New<ScheduledItemWrapper<Node>>(this);
}
return _updateItem.get();
}

ScheduledItem* Node::getFixedScheduledItem() {
FixedScheduledItem* Node::getFixedScheduledItem() {
auto updateItem = getUpdateItem();
if (!updateItem->fixedScheduledItem) {
updateItem->fixedScheduledItem = New<ScheduledItem>(this);
updateItem->fixedScheduledItem = New<FixedScheduledItemWrapper<Node>>(this);
}
return updateItem->fixedScheduledItem.get();
}
Expand Down
9 changes: 5 additions & 4 deletions Source/Node/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Listener;
class Signal;
class Slot;
class ScheduledItem;
class FixedScheduledItem;
class Scheduler;
class TouchHandler;
class NodeTouchHandler;
Expand Down Expand Up @@ -130,8 +131,8 @@ class Node : public Object {

virtual void visit();
virtual void render();
virtual bool fixedUpdate(double deltaTime) override;
virtual bool update(double deltaTime) override;
virtual bool fixedUpdate(double deltaTime);
virtual bool update(double deltaTime);

const AffineTransform& getLocalTransform();

Expand Down Expand Up @@ -322,14 +323,14 @@ class Node : public Object {
struct UpdateItem {
std::function<bool(double)> scheduledFunc;
Own<ScheduledItem> scheduledItem;
Own<ScheduledItem> fixedScheduledItem;
Own<FixedScheduledItem> fixedScheduledItem;
bool hasFunc() const;
bool fixedScheduled() const;
bool scheduled() const;
};
Own<UpdateItem> _updateItem;
UpdateItem* getUpdateItem();
ScheduledItem* getFixedScheduledItem();
FixedScheduledItem* getFixedScheduledItem();
enum: Flag::ValueType {
Visible = 1,
SelfVisible = 1 << 1,
Expand Down

0 comments on commit 381884d

Please sign in to comment.