updated actions with a pool of glue.

This commit is contained in:
Edward R. Gonzalez 2020-02-17 12:39:31 -05:00
parent d272fb6546
commit aa560c34b6
3 changed files with 183 additions and 44 deletions

View File

@ -7,20 +7,29 @@ Description: This was a little experiment of mine to mess with action binding...
Allows for non-member functions to be binded to an action, implements a functioning queue as well.
TODO: Possibly add support for member functions. Have it so that deduction of delegate typef is not required to add to queue properly (right now it does, see input procedure for example);
Note: Right now due to type dynamics all actions are allocated via a pool and reuse is attempted by not guaranteed...
*/
#pragma once
#include "Cpp_Alias.hpp"
namespace Actions
{
using IndexType = DataSize;
struct IAction
{
virtual void DoAction() = NULL;
virtual sfn DoAction() -> void = NULL;
};
template<typename FunctionType, typename... ActionParams>
@ -31,16 +40,41 @@ namespace Actions
public:
AAction(ActionType _actionToAssign, ActionParams... _params) :
action(_actionToAssign),
params(_params... )
params(_params... ),
done (false )
{};
private:
using IndexType = DataSize;
sfn Used() -> bool
{
return done;
}
void DoAction_Implementation(ActionParams... _params) { action(_params...); }
sfn IsSame(ActionParams... _paramsForAction) -> bool
{
Tuple<ActionParams...> paramsToCheck(_paramsForAction...);
if (params == paramsToCheck)
{
return true;
}
else
{
return false;
}
}
sfn ReInitalize(ActionParams... _params)
{
params = Tuple<ActionParams...> (_params...);
done = false;
}
private:
sfn DoAction_Implementation(ActionParams... _params) { action(_params...); }
template<IndexType... TuplePackIndex> // TuplePackSequence<TuplePackIndex...>
void ExpandTuple_CallDoActionImplementaiton(const Ref(Tuple<ActionParams...>) _paramsToExpand, std::index_sequence <TuplePackIndex...>)
sfn ExpandTuple_CallDoActionImplementaiton(const Ref(Tuple<ActionParams...>) _paramsToExpand, std::index_sequence <TuplePackIndex...>)
{
// ExpandTuplePack<TuplePackIndex>
DoAction_Implementation(std::get<TuplePackIndex>(_paramsToExpand)...);
@ -50,9 +84,11 @@ namespace Actions
ActionType action;
bool done;
public: // IAction
virtual void DoAction() override
virtual sfn DoAction() -> void override
{
ExpandTuple_CallDoActionImplementaiton
(
@ -60,22 +96,111 @@ namespace Actions
// MakeTuplePackSequence <ActionParams...>()
std::index_sequence_for<ActionParams...>()
);
done = true;
};
};
struct ActionPool_Dynamic
{
template<typename Type>
using AllocationsOf = std::forward_list<Type>;
using TypeIndex = std::type_index ;
using Managed_AAction = SPtr < IAction >;
using Managed_AActions = AllocationsOf < Managed_AAction >;
using AActions_Registry = std::map <TypeIndex , Managed_AActions>;
public:
template<typename Entry>
sfn Available(Ref(Entry) _entry) -> bool
{
return _entry != aActions_Available.end() ? true : false;
}
template<typename Entry>
sfn Contains(Ref(Entry) _entry) -> bool
{
return _entry != aActions_Available.end() ? true : false;
}
sfn Make_Managed_Actions() -> Ref(Managed_AActions)
{
mAAaction_Allocations.push_front(MakeSPtr<Managed_AActions>());
return Dref(mAAaction_Allocations.front().get());
}
template<typename FunctionType, typename... ActionParams>
sfn Request_AAction(Delegate< FunctionType> _actionToQueue, ActionParams... _paramsForAction) -> ptr<IAction>
{
using ActionType = AAction < FunctionType, ActionParams...>;
TypeIndex AActionID = typeid(ActionType);
deduce possibleEntry = aActions_Available.find(AActionID);
if (Contains(possibleEntry))
{
using Element = decltype(possibleEntry->second.begin());
for (Element possibleAction = possibleEntry->second.begin(); possibleAction != possibleEntry->second.end(); possibleAction++)
{
ptr< ActionType> castedEntry = static_cast< ptr< ActionType>>(possibleAction->get());
if (castedEntry->IsSame(_paramsForAction...))
{
return castedEntry;
}
else if (castedEntry->Used())
{
castedEntry->ReInitalize(_paramsForAction...);
return castedEntry;
}
}
SPtr< IAction> newAction = MakeSPtr< AAction<FunctionType, ActionParams...>>(_actionToQueue, _paramsForAction...);
ptr < IAction> returnRef = newAction.get ();
aActions_Available.at(AActionID).push_front(newAction);
return returnRef;
}
SPtr< IAction> newAction = MakeSPtr< AAction<FunctionType, ActionParams...>>(_actionToQueue, _paramsForAction...);
ptr < IAction> returnRef = newAction.get ();
aActions_Available.insert(std::make_pair(AActionID, Make_Managed_Actions()));
aActions_Available.at(AActionID).push_front(newAction);
return returnRef;
}
private:
AllocationsOf< SPtr<Managed_AActions> > mAAaction_Allocations;
AActions_Registry aActions_Available;
};
ActionPool_Dynamic DefaultActionPool_Dynamic;
struct ActionQueue
{
sfn HasAction()
{
return actionQueue.size() > 0;
}
using QueueType = std::deque< ptr<IAction>>;
template<typename FunctionType, typename... ActionParams>
sfn AddToQueue(Delegate< FunctionType> _actionToQueue, ActionParams... _paramsForAction)
{
// This is extremely inefficient, but in order to fix requires an object pool or something else...
SPtr< AAction<FunctionType, ActionParams...> > ptrToAction = MakeSPtr< AAction<FunctionType, ActionParams...> >(_actionToQueue, _paramsForAction...);
using GeneratedActionType = AAction<FunctionType, ActionParams...>;
ptr< IAction > actionRequested = DefaultActionPool_Dynamic.Request_AAction(_actionToQueue, _paramsForAction...);
if (HasAction())
{
@ -85,7 +210,7 @@ namespace Actions
for (Element element = actionQueue.begin(); element != actionQueue.end(); element++)
{
if ((*element).get() == ptrToAction.get())
if ( (*element) == actionRequested )
{
found = true;
}
@ -93,12 +218,12 @@ namespace Actions
if (not found)
{
actionQueue.push_front(std::move(ptrToAction));
actionQueue.push_front(actionRequested);
}
}
else
{
actionQueue.push_front(std::move(ptrToAction));
actionQueue.push_front(actionRequested);
}
}
@ -112,7 +237,11 @@ namespace Actions
}
}
using QueueType = std::deque< SPtr<IAction>>;
sfn HasAction()
{
return actionQueue.size() > 0;
}
QueueType actionQueue;
};

View File

@ -17,10 +17,12 @@ This merely removes the need to use operators I don't like and wraps them in eas
#include <cstdarg >
#include <cstddef >
#include <exception >
#include <forward_list>
#include <fstream >
#include <functional >
#include <iostream >
#include <cmath >
#include <map >
#include <memory >
#include <queue >
#include <sstream >
@ -29,6 +31,7 @@ This merely removes the need to use operators I don't like and wraps them in eas
#include <vector >
#include <thread >
#include <tuple >
#include <typeindex >
#include <utility >

View File

@ -80,8 +80,8 @@ namespace Execution
TimeValDec CycleStart , // Snapshot of cycle loop start time.
CycleEnd , // Snapshot of cycle loop end time.
DeltaTime , // Delta between last cycle start and end.
InputInterval = 1.0f / 576.0f, // Interval per second to complete the input process of the cycle.
PhysicsInterval = 1.0f / 288.0f, // Interval per second to complete the physics process of the cycle.
InputInterval = 1.0f / 400.0f, // Interval per second to complete the input process of the cycle.
PhysicsInterval = 1.0f / 240.0f, // Interval per second to complete the physics process of the cycle.
RenderInterval = 1.0f / 144.0f ; // Interval per second to complete the render process of the cycle.
ptr<Window> DefaultWindow; // Default window to use for execution.
@ -97,6 +97,13 @@ namespace Execution
ActionQueue ActionsToComplete; // Actions queue to run during the physics process of the cycle.
template<typename Type>
sfn RoundOff(Type _value, gInt _numDigitsToKeep) -> Type
{
uInt64 Rounder = pow(10, _numDigitsToKeep);
return round(_value * Rounder) / Rounder;
}
// Functionality
@ -234,15 +241,15 @@ namespace Execution
return;
}
sfn ModifyCamSpeed(bool _isPositive)
sfn ModifyCamSpeed(bool _isPositive, gFloat _delta)
{
if (_isPositive)
{
CamMoveSpeed++;
CamMoveSpeed += CamMoveSpeed * _delta;
}
else
{
CamMoveSpeed--;
CamMoveSpeed -= CamMoveSpeed * _delta;
}
}
@ -272,12 +279,12 @@ namespace Execution
if (KeyPressed(_currentWindowContext, EKeyCodes::UpArrow))
{
ActionsToComplete.AddToQueue(ModifyCamSpeedDelegate, true);
ActionsToComplete.AddToQueue(ModifyCamSpeedDelegate, true, PhysicsDelta);
}
if (KeysPressed(_currentWindowContext, EKeyCodes::DnArrow))
{
ActionsToComplete.AddToQueue(ModifyCamSpeedDelegate, false);
ActionsToComplete.AddToQueue(ModifyCamSpeedDelegate, false, PhysicsDelta);
}
if (KeyPressed(_currentWindowContext, EKeyCodes::F2))