Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modules that are need to be developed #2

Open
devolonter opened this issue Feb 24, 2013 · 38 comments
Open

Modules that are need to be developed #2

devolonter opened this issue Feb 24, 2013 · 38 comments
Labels

Comments

@devolonter
Copy link
Member

List of non-existing modules that you think are basic and they need to be developed for inclusion in the future.

@skn3
Copy link
Member

skn3 commented Feb 25, 2013

collision checking functions eg RectsOverlap, CircleOverlaps, PointInRect, etc

@swoolcock
Copy link

There's some non-frameworky utility stuff in Diddy and in my own personal projects that might be useful too:
Colorspace conversion (in Diddy). HSL, RGB, more could be added.
Matrix/Vector classes (mine are based heavily on the libGDX ones and have a lot of optimisations).
Array manipulation utilities (in Diddy)
String.format / sprintf-style formatting (in Diddy)
Internationalization (in Diddy)

There's also a side-project in Diddy for multithreading, but that might be out of scope.

@frameland
Copy link
Member

I would definetely vote for these modules you mentioned.
Vector
Matrix
Color
ArrayUtil

For the color, there could be a class for each color space?
RgbColor, HslColor, etc. and then you can convert between these.

@swoolcock
Copy link

I think it would be better to have a single Color class, then use getters
or properties to access each component per colorspace. As for the other
modules, I'll look at cleaning up the Diddy ones and removing dependencies.

@devolonter
Copy link
Member Author

I also vote for the inclusion of classes: Vector, Matrix, Color and ArrayUtil. Please, look at the collection’s scheme in wiki, are there any questions or objections?

@skn3
Copy link
Member

skn3 commented Mar 4, 2013

Seems nice to me 👍

@swoolcock
Copy link

I was actually about to post my own structure proposal, but then I realised it's almost identical to that one anyway. :)
A couple of suggestions though:

pub.native: Any externed stuff goes in here and is not referenced anywhere else in the library. Anything that's not supported by a particular platform should have a NOP stub method or a pure Monkey implementation (as mentioned before).

pub.math: Have separate classes for matrix/vector dimensions. ie. Matrix3, Matrix4, Vector2, Vector3.

Might be nice to have a MathUtil class there somewhere too that can handle easing and interpolation. Easing/interpolation aren't really restricted to graphics, so I think they belong in the math module. It'd also be a nice place to put things like clamping, and possibly a better pseudorandom number generator.

@frameland
Copy link
Member

I have an interpolation only module (no dependencies on mojo).
Maybe on top of that we could integrate it with our vector class? Then you would have:
math.Tween(Float)
math.Tween(Vector)

@swoolcock
Copy link

Sounds good. To be honest I think it would be useful for Color too. Tweening RGB is just horrid, but tweening HSL is lovely.
Reason why RGB is fail: Tweening between red and yellow won't give you orange as you'd expect. (255,0,0) to (0,255,255) passes through grey (128,128,128) instead. With HSL you'd leave saturation and luminance alone, and just tween the hue.

Rather than restricting tweening to these kinds of data types, I propose we make Vector/Color implement an ITweenable interface that allows you to tween as many different components as you like. You could do 1000 components if you want! ;)

@frameland
Copy link
Member

Yeah, you can't really tween rgb values - I agree on that.

The problem with an ITweenable interface is the following:
A vector has 2 values(x,y) and color has 3(h, s, l). So the challenge is to boil that down into a common interface.
You could return arrays or use reflection but then you have unnecessary overhead.

So maybe there is an obvious solution to that? It's because I tried to do exactly that (ITweenable interface) and failed because every class has a different amount of values which it returns.

EDIT: Oh, you mean the vector and color class have to implement the tweening themselves? That's a possibility.

@swoolcock
Copy link

Haven't tested, probably has compilation errors:

Interface ITweenable
Method GetComponentCount:Int()
Method SetComponent:Void(component:Int, value:Float)
Method GetComponent:Float(component:Int)
End

Class Vector2 Implements ITweenable
Field x:Float, y:Float

 Method GetComponentCount:Int()
     Return 2
 End

 Method SetComponent:Void(component:Int, value:Float)
     Select component
         Case 0
             x = value
         Case 1
             y = value
     End
 End

 Method GetComponent:Float(component:Int)
     Select component
         Case 0
             Return x
         Case 1
             Return y
     End
     Return 0
 End

End

Class Color Implements ITweenable
Field hue:Float, saturation:Float, luminance:Float, alpha:Float

 Method GetComponentCount:Int()
     Return 4
 End

 Method SetComponent:Void(component:Int, value:Float)
     Select component
         Case 0
             hue = value
         Case 1
             saturation = value
         Case 2
             luminance = value
         Case 3
             alpha = value
     End
 End

 Method GetComponent:Float(component:Int)
     Select component
         Case 0
             Return hue
         Case 1
             Return saturation
         Case 2
             Return luminance
         Case 3
             Return alpha
     End
     Return 0
 End

End

Function Tween:Void(target:ITweenable, startValue:ITweenable,
endValue:ITweenable, progress:Float)
For Local i:Int = 0 Until target.GetComponentCount()
Local startComp:Float = startValue.GetComponent(i)
Local endComp:Float = endValue.GetComponent(i)
target.SetComponent(i, startComp + (endComp-startComp)*progress)
Next
End

@frameland
Copy link
Member

Well, that's great :)
That would mean we only need 2 interfaces/functions:

Tween:Float(...) ' for normal Interpolation
Tween:Void(...) ' for custom classes which implement ITweenable

I think handling when something is finished should be left to the user.
Regarding event handling. Is a general event system out of scope for pub?

@skn3
Copy link
Member

skn3 commented Mar 5, 2013

Looks good but maybe not the I______ class names ;) ? I think we should try and keep things verbose.

Although I dont think its sensible to require that if you want a vector in your app that you then have to import the tween lib? We have to be careful that we don't turn pub into a framework.

@swoolcock
Copy link

Hmm... you'd want to make an event system very extendable and generic, which leaves a lot of work up to the developer, defeating the purpose of the module.

@skn3
Copy link
Member

skn3 commented Mar 5, 2013

You could do a basic callback system?
https://bitbucket.org/skn3/monkeymodules/src/master/skn3/callbacks

@swoolcock
Copy link

I only prefixed the interface with I because it's sort of a standard in many languages to mark interfaces and virtual classes as such.

@swoolcock
Copy link

Oh by the way, here's a simple Color class I just whacked together. Only a suggestion.

Class Color
Private
    Field red:Int = 255
    Field green:Int = 255
    Field blue:Int = 255

    Field alpha:Float = 1

    Field needsRecalcToRGB:Bool = False
    Field needsRecalcFromRGB:Bool = False

    Method RecalcToRGB:Void()
        needsRecalcToRGB = False
        ToRGB()
    End

    Method RecalcFromRGB:Void()
        needsRecalcFromRGB = False
        FromRGB()
    End

Public
    Method New(red:Int, green:Int, blue:Int)
        Self.red = red
        Self.green = green
        Self.blue = blue
    End

    Method ToRGB:Void()
        ' implemented by subclasses
    End

    Method FromRGB:Void()
        ' implemented by subclasses
    End

    Method Red:Int() Property
        If needsRecalcToRGB Then RecalcToRGB()
        Return red
    End

    Method Green:Int() Property
        If needsRecalcToRGB Then RecalcToRGB()
        Return green
    End

    Method Blue:Int() Property
        If needsRecalcToRGB Then RecalcToRGB()
        Return blue
    End

    Method Red:Void(red:Int) Property
        Self.red = red
        needsRecalcFromRGB = True
    End

    Method Green:Void(green:Int) Property
        Self.green = green
        needsRecalcFromRGB = True
    End

    Method Blue:Void(blue:Int) Property
        Self.blue = blue
        needsRecalcFromRGB = True
    End

    Method Alpha:Float() Property
        Return alpha
    End

    Method Alpha:Void(alpha:Float) Property
        Self.alpha = alpha
    End
End

Class ColorHSL Extends Color
Private
    Field hue:Float = 0
    Field saturation:Float = 1
    Field luminance:Float = 1

Public
    Method New(hue:Float, saturation:Float, luminance:Float)
        Self.hue = hue
        Self.saturation = saturation
        Self.luminance = luminance
        needsRecalcToRGB = True
    End

    Method Hue:Float() Property
        If needsRecalcFromRGB Then RecalcFromRGB()
        Return hue
    End

    Method Saturation:Float() Property
        If needsRecalcFromRGB Then RecalcFromRGB()
        Return saturation
    End

    Method Luminance:Float() Property
        If needsRecalcFromRGB Then RecalcFromRGB()
        Return luminance
    End

    Method Hue:Void(hue:Float) Property
        Self.hue = hue
        needsRecalcToRGB = True
    End

    Method Saturation:Void(saturation:Float) Property
        Self.saturation = saturation
        needsRecalcToRGB = True
    End

    Method Luminance:Void(luminance:Float) Property
        Self.luminance = luminance
        needsRecalcToRGB = True
    End

    Method ToRGB:Void()
        ' TODO: convert HSL to RGB (code is in Diddy)
    End

    Method FromRGB:Void()
        ' TODO: convert RGB to HSL (code is in Diddy)
    End
End

Function Main()
    ' creates an instance of ColorHSL describing fullbright red
    Local c:ColorHSL = New ColorHSL(0, 1, 0.5)

    ' reading the Red, Green, or Blue properties forces the RGB cache to be recalculated, giving us (255, 0, 0)
    Print c.Red
    Print c.Green
    Print c.Blue

    ' writing the Red, Green, or Blue properties flags the RGB values as dirty
    c.Red = 255
    c.Green = 255
    c.Blue = 0

    ' reading the Hue, Saturation, or Luminance properties recalculates them from the RGB since it was dirtied
    Print c.Hue
    Print c.Saturation
    Print c.Luminance
End

@frameland
Copy link
Member

skn3, you are right. pub shouldn't be a framework.

Maybe only the tweening functions itself could be a seperate module (no dependencies).
I also think vector or color shouldn't depend on it.

@frameland
Copy link
Member

swooclock - you could add setRGB(r, g, b, a = 1.0) and setHSL(h, s, l) for convenience.

Also having some predefined ones like in XNA would be nice: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.color_members(v=xnagamestudio.31).aspx
The question here is if they should be defined as Globals(because monkey doesn't allow them to be const, argh), passed as String arguments, or passed as an Int const.
I would tend for the last option so you could do: myColor.Set(Color.Black)

Generally I think all our classes should have a ToString() Method.

@devolonter
Copy link
Member Author

Huh! It seems I’m late for the discussion? :) Actually, I'm glad to see such an activity - it's great! It’s a pity that I can’t take an active part yet. So, fell free to make any changes to the schema and other wiki pages, if it’s necessary.

Also, I think that it's possible to add some modules already. For example, I created a repository pub.files.json (implementation by muddy_shoes) and added it as a submodule to the main repository (develop branch).

In general about discussion. I agree with @skn3 that we need to be careful not to turn the pub into a framework. But I support the adding of tweening system. Callback functionality also seems useful. But I'm not sure to which group it can be included.

pub.native sounds reasonable, but, in my opinion, not semantically. Although I think it is useful, and it warns about potential problems with different target. In general, I don’t mind.

pub.math: Have separate classes for matrix / vector dimensions. ie. Matrix3, Matrix4, Vector2, Vector3

I think it would make sense to merge them in one module. That is pub.math.vector includes Vector2 and Vector3 etc.

@swoolcock
Copy link

@Shinkiro1 I had actually planned on adding those exact methods. :)
If you'd like I can start working on Color. Just let me know where you think the best place to put it is.
I agree with the ToString() idea too.

Also, can we decide on a coding style? You can see mine from that code snippet, but of course I don't want to force anything on anyone.

@frameland
Copy link
Member

The wiki has the coding standards which are essentially the same as the ones in monkey.
Imo your coding style is perfectly fine, especially using long descriptive names as you do is much more preferable than using short acronyms.

The wiki also has a collection scheme which suggests you to put the color class inside utils (which does not exist for now).

@swoolcock
Copy link

Ok cool, I'll push a Color class soon. Regarding tweening, I'd thought of doing something like this, as it's more math-related than restricted to tweening.

    Interface Lerpable
        Method Lerp:Void(startValue:Object, endValue:Object, progress:Float)
    End

    Class Color Implements Lerpable
        Field h#, s#, l#

        Method Lerp:Void(startValue:Object, endValue:Object, progress:Float)
            Local startColor:Color = Color(startValue)
            Local endColor:Color = Color(endValue)
            If Not startColor Or Not endColor Then Return
            Self.h = startColor.h + (endColor.h-startColor.h) * progress
            Self.s = startColor.s + (endColor.s-startColor.s) * progress
            Self.l = startColor.l + (endColor.l-startColor.l) * progress
        End
    End

    Class Vector2 Implements Lerpable
        Field x#, y#

        Method Lerp:Void(startValue:Object, endValue:Object, progress:Float)
            Local startVec:Vector2 = Vector2(startValue)
            Local endVec:Vector2 = Vector2(endValue)
            If Not startVec Or Not endVec Then Return
            Self.x = startVec.x + (endVec.x-startVec.x) * progress
            Self.y = startVec.y + (endVec.y-startVec.y) * progress
        End
    End

    ' tweening code stores references to Lerpable and calls Lerp on them

Edit: @Shinkiro1 I'll see if I can integrate your tweening module with Color (without dependencies). If it looks to work well, I'll put in some vector/matrix classes and integrate those too.
Additionally, I think it might be easier to drop the HSL stuff into the one Color class with RGB. I really doubt anyone will need anything more than those two colorspaces. If necessary we can throw in CMYK too. The only reason I was going to split them is because HSL and HSV share component names (yes they're quite different).

@swoolcock
Copy link

Just gotta fill in some documentation then I'll push. Basically you can write to any of Red/Green/Blue/Hue/Saturation/Luminance and it will update the colour accordingly. I've made an ImmutableColor class that's used internally to make the predefined colours immutable. I've done the Lerpable thing too, pending suggestions for a better interface name!

@swoolcock
Copy link

You guys ok with me pushing some vector/matrix classes? They're loosely based on the libgdx ones (Vector2/Matrix3) https://github.com/libgdx/libgdx/tree/master/gdx/src/com/badlogic/gdx/math

@swoolcock swoolcock reopened this Mar 12, 2013
@swoolcock
Copy link

Oops... clicked the wrong button XD

@frameland
Copy link
Member

Of course. You are free to push whatever your want ;)

@swoolcock
Copy link

Pushed. Note how small math.monkey is, though. I really think a lot of the functions in collisions.monkey can be moved in there instead. They seem a bit generic and not necessarily restricted to collisions. For example, DistanceBetweenPoints should really just be Length, since it's Pythagoras. There's a fine line between "providing tools for the developer" and "holding their hand". I've always leaned toward the former.

@swoolcock
Copy link

Example:

Function Main:Int()
    ' creates an instance of Color describing fullbright red
    Local c:Color = New Color(0, 1, 0.5,,Color.HSL)

    ' reading the Red, Green, or Blue properties forces the RGB cache to be recalculated, giving us (255, 0, 0)
    Print "Hue="+c.Hue
    Print "Saturation="+c.Saturation
    Print "Luminance="+c.Luminance
    Print "Red="+c.Red
    Print "Green="+c.Green
    Print "Blue="+c.Blue

    ' writing the Red, Green, or Blue properties flags the RGB values as dirty
    c.Red = 255
    c.Green = 255
    c.Blue = 0

    ' reading the Hue, Saturation, or Luminance properties recalculates them from the RGB since it was dirtied
    Print "Hue="+c.Hue
    Print "Saturation="+c.Saturation
    Print "Luminance="+c.Luminance
    Print "Red="+c.Red
    Print "Green="+c.Green
    Print "Blue="+c.Blue

    Print "BLACK.Red="+Color.BLACK.Red
    Print "BLACK.Green="+Color.BLACK.Green
    Print "BLACK.Blue="+Color.BLACK.Blue
    Color.BLACK.Red = 100

    Print "BLACK.Red="+Color.BLACK.Red
    Print "BLACK.Green="+Color.BLACK.Green
    Print "BLACK.Blue="+Color.BLACK.Blue
    Return 0
End

@skn3
Copy link
Member

skn3 commented Mar 25, 2013

But do we want to force the user to import "math" if all they want to do is just have "collisions" in their game. Everything needs to be as self contained as possible. What does everyone think the limit of importing other pub modules should be?

@swoolcock
Copy link

This is why you use private imports. That way the module "just works",
and you don't need to get the user to manually import it. I think we'll
have to face the fact that there are some modules that will be
mandatory. Kinda like how you couldn't really write a Monkey program
without importing monkey.lang, which is why it's implicit (like java.lang).

@devolonter
Copy link
Member Author

I agree with @swoolcock and I think we can give some freedom in the use of basic monkey modules as well as pub modules. It’s just important to not abuse it.

@swoolcock
Copy link

Basically we can pick a handful of mandatory utility modules (hopefully no
more than about 3 or 4) and each of those modules has a total of ZERO
imports. That way there's no cross-linkage.

@skn3
Copy link
Member

skn3 commented Mar 26, 2013

Ok that does make things a tad easier, I wasn't sure what way we are going. Yeah definite that utils have no imports unless they are monkey core modules. I wonder if this pub project would be beneficial with marks new github approach for monkey? OR will the two projects compete?

@devolonter
Copy link
Member Author

I think we would all be happy if project was the part of the official Monkey repository. But I'm not sure that Mark will support the idea. He said many times that he does not believe in the success of big modules bundle. Although it might be worth a try. Maybe someone will ask Mark about it?

@skn3
Copy link
Member

skn3 commented Mar 27, 2013

shortest straw does it? lol He seemed to hint about 3rd party additions in his github thread so it could be a good oppertunity?

@devolonter
Copy link
Member Author

Yeah, I’ve noticed it as well. I think we should ask Mark about it. But I don’t want to be intrusive :)

@skn3
Copy link
Member

skn3 commented Apr 2, 2013

lol true ;) I guess we should wait and see what happens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants