Thread overview | |||||
---|---|---|---|---|---|
|
June 13, 2014 Library design | ||||
---|---|---|---|---|
| ||||
I'm trying to create a minimal tweening library in D based on the commonly used easing equations by Robert Penner (http://www.robertpenner.com/easing/). One of the goals with the design of the library is that any numeric type should be tweenable.(The user of the library shouldn't have to do any casting of their own etc) Now how do I go about and design a data structure that can take either floats, ints or doubles, store them and modify them? This is what I hacked together earlier today: abstract class TweenWrapper{ } class Tween(T) : TweenWrapper{ T owner; string[] members; /** Duration in milliseconds */ int duration; /** Elapsed time in milliseconds */ int elapsedTime; bool isComplete; /** Type of easing */ EasingType easingType; } TweenWrapper is just what it sounds like, a wrapper so I don't have to specify any type for the container holding the Tween objects(DList!TweenWrapper). __traits(getMember, owner, members[0]) = valueReturnedFromEasingFunction; Was How I planned to use this class.. but you know, compile time only. Let me know if this isn't enough to go on. Is what I'm asking even possible(the easy way) in D? TL;DR Help me make D Dynamic! |
June 13, 2014 Re: Library design | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rutger | On Friday, 13 June 2014 at 04:11:38 UTC, Rutger wrote:
> I'm trying to create a minimal tweening library in D based on the
> commonly used easing equations by Robert Penner
> (http://www.robertpenner.com/easing/).
> One of the goals with the design of the library is that any
> numeric type should be tweenable.(The user of the library
> shouldn't have to do any casting of their own etc) Now how do I
> go about and design a data structure that can take either floats,
> ints or doubles, store them and modify them?
>
> This is what I hacked together earlier today:
>
>
> abstract class TweenWrapper{
>
> }
>
>
> class Tween(T) : TweenWrapper{
>
> T owner;
>
> string[] members;
>
> /** Duration in milliseconds */
> int duration;
>
> /** Elapsed time in milliseconds */
> int elapsedTime;
>
> bool isComplete;
>
> /** Type of easing */
> EasingType easingType;
>
> }
>
> TweenWrapper is just what it sounds like, a wrapper so I don't
> have to specify any type for the container holding the Tween
> objects(DList!TweenWrapper).
>
> __traits(getMember, owner, members[0]) =
> valueReturnedFromEasingFunction;
> Was How I planned to use this class.. but you know, compile time
> only.
>
>
> Let me know if this isn't enough to go on.
> Is what I'm asking even possible(the easy way) in D?
>
>
> TL;DR
> Help me make D Dynamic!
From what i can tell you want something similar to this.
interface ITween
{
void update(int elapsedTime);
}
class Tween(T, string member) : ITween
{
//Expands to
//|alias memberType = typeof(T.memberName);|
mixin("alias memberType = typeof("
~ T.stringof ~ "." ~ member ~ ");");
memberType from;
memberType to;
EasingType type;
int duration;
int elapsedTime;
T owner;
@property bool isComplete()
{
return elapsedTime >= duration;
}
void update(int time)
{
elapsedTime = min(elapsedTime + time, duration);
double amount = elapsedTime / cast(double)duration;
auto tweened = ease(type, from, to, amount);
__traits(getMember, owner, member) = tweened;
}
}
Where ease is a method that will look something like this:
T ease(T)(EasingType type, T from, T to, double amount) if(isNumeric!T)
{
double result;
if(type == EasingType.linear)
result = linearEase(amount);
else
assert(0, "Not yet implemented");
return cast(T)((to - from) * result + from));
}
double linearEase(double amount)
{
return amount;
}
This will work for all number types.
Hope this was helpful.
|
June 13, 2014 Re: Library design | ||||
---|---|---|---|---|
| ||||
Posted in reply to TheFlyingFiddle | On Friday, 13 June 2014 at 05:54:02 UTC, TheFlyingFiddle wrote:
> On Friday, 13 June 2014 at 04:11:38 UTC, Rutger wrote:
>> I'm trying to create a minimal tweening library in D based on the
>> commonly used easing equations by Robert Penner
>> (http://www.robertpenner.com/easing/).
>> One of the goals with the design of the library is that any
>> numeric type should be tweenable.(The user of the library
>> shouldn't have to do any casting of their own etc) Now how do I
>> go about and design a data structure that can take either floats,
>> ints or doubles, store them and modify them?
>>
>> This is what I hacked together earlier today:
>>
>>
>> abstract class TweenWrapper{
>>
>> }
>>
>>
>> class Tween(T) : TweenWrapper{
>>
>> T owner;
>>
>> string[] members;
>>
>> /** Duration in milliseconds */
>> int duration;
>>
>> /** Elapsed time in milliseconds */
>> int elapsedTime;
>>
>> bool isComplete;
>>
>> /** Type of easing */
>> EasingType easingType;
>>
>> }
>>
>> TweenWrapper is just what it sounds like, a wrapper so I don't
>> have to specify any type for the container holding the Tween
>> objects(DList!TweenWrapper).
>>
>> __traits(getMember, owner, members[0]) =
>> valueReturnedFromEasingFunction;
>> Was How I planned to use this class.. but you know, compile time
>> only.
>>
>>
>> Let me know if this isn't enough to go on.
>> Is what I'm asking even possible(the easy way) in D?
>>
>>
>> TL;DR
>> Help me make D Dynamic!
>
>
> From what i can tell you want something similar to this.
>
> interface ITween
> {
> void update(int elapsedTime);
> }
>
> class Tween(T, string member) : ITween
> {
> //Expands to
> //|alias memberType = typeof(T.memberName);|
>
> mixin("alias memberType = typeof("
> ~ T.stringof ~ "." ~ member ~ ");");
>
> memberType from;
> memberType to;
> EasingType type;
>
> int duration;
> int elapsedTime;
>
> T owner;
>
> @property bool isComplete()
> {
> return elapsedTime >= duration;
> }
>
> void update(int time)
> {
> elapsedTime = min(elapsedTime + time, duration);
> double amount = elapsedTime / cast(double)duration;
> auto tweened = ease(type, from, to, amount);
> __traits(getMember, owner, member) = tweened;
> }
> }
>
> Where ease is a method that will look something like this:
>
> T ease(T)(EasingType type, T from, T to, double amount) if(isNumeric!T)
> {
> double result;
> if(type == EasingType.linear)
> result = linearEase(amount);
> else
> assert(0, "Not yet implemented");
>
> return cast(T)((to - from) * result + from));
> }
>
> double linearEase(double amount)
> {
> return amount;
> }
>
> This will work for all number types.
>
> Hope this was helpful.
Gonna try this later, thanks a lot!
|
Copyright © 1999-2021 by the D Language Foundation