www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Library design

reply "Rutger" <rutgerdlangforums mailinator.com> writes:
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!
Jun 12 2014
parent reply "TheFlyingFiddle" <kurtyan student.chalmers.se> writes:
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.
Jun 12 2014
parent "Rutger" <rutgerdlangforums mailinator.com> writes:
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!
Jun 13 2014