Jean Privat [Wed, 25 May 2016 19:38:25 +0000 (15:38 -0400)]
nitrpg&nitcorn: replace `rand` with `NIT_TESTING_ID` for their tests
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 19:36:09 +0000 (15:36 -0400)]
tests.sh: add NIT_TESTING_ID with the same semantic than with nitunit
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 19:34:38 +0000 (15:34 -0400)]
nitunit manual: document NIT_TESTING, SRAND and NIT_TESTING_ID
Signed-off-by: Jean Privat <jean@pryen.org>
Alexandre Terrasa [Thu, 26 May 2016 04:31:21 +0000 (00:31 -0400)]
nitdoc: use --share-dir option
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Thu, 26 May 2016 04:31:07 +0000 (00:31 -0400)]
toolcontext: introduce --share-dir
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 23:56:50 +0000 (19:56 -0400)]
lib/popcorn: document use_before and use_after
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 23:47:59 +0000 (19:47 -0400)]
tests: fix model_visitor tests since mdoc fix
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 23:43:18 +0000 (19:43 -0400)]
model/model_collect: importation_poset do not collect direct parents and children
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Fri, 18 Dec 2015 05:20:41 +0000 (00:20 -0500)]
model_collect: add services for module importation
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Jean Privat [Wed, 25 May 2016 19:34:04 +0000 (15:34 -0400)]
nitunit: set more environment variables NIT_TESTING_ID and SRAND
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 19:33:34 +0000 (15:33 -0400)]
lib/core: add `Sys::pid`
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 00:15:08 +0000 (20:15 -0400)]
tests: update nitunit tests
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 00:11:56 +0000 (20:11 -0400)]
nitunit: show a progress bar
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 00:11:08 +0000 (20:11 -0400)]
nitunit: suites in docunits have a name
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 00:10:27 +0000 (20:10 -0400)]
nitunit: separate the error message from the test output
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Wed, 25 May 2016 00:06:57 +0000 (20:06 -0400)]
nitunit: add more information in UnitTest
Signed-off-by: Jean Privat <jean@pryen.org>
Alexandre Terrasa [Mon, 23 May 2016 20:52:36 +0000 (16:52 -0400)]
lib/popcorn: App uses pre / post middlewares
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Mon, 23 May 2016 20:52:12 +0000 (16:52 -0400)]
lib/popcorn: introduce Router::use_after service
So the user can force some middlewares to be called after the other handlers.
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Mon, 23 May 2016 20:51:55 +0000 (16:51 -0400)]
lib/popcorn: introduce Router::use_before service
So the user can force some middlewares to be called before the other handlers.
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Mon, 23 May 2016 20:50:38 +0000 (16:50 -0400)]
lib/popcorn: extract Router::handler_in private service
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Mon, 23 May 2016 20:49:11 +0000 (16:49 -0400)]
lib/popcorn: extract Router::build_route private service
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 02:56:27 +0000 (22:56 -0400)]
src/model: fix mdoc_or_fallback for MClasses and MProperties
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 01:32:15 +0000 (21:32 -0400)]
src/model: model_visitor uses MEntity::visibility
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 01:20:17 +0000 (21:20 -0400)]
src/model: model_json use MEntity::location
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 01:18:19 +0000 (21:18 -0400)]
src/model: model_json use MEntity::visibility
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Wed, 25 May 2016 01:10:36 +0000 (21:10 -0400)]
src/model: generalize visibility to all MEntities
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Jean Privat [Tue, 24 May 2016 23:59:10 +0000 (19:59 -0400)]
nitunit: fix some nitunit flags.
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Tue, 24 May 2016 23:12:43 +0000 (19:12 -0400)]
Merge: NOTICE: Update author list and years
Commands used:
* `git shortlog -sne <commit range> -- benchmarks/ contrib/ c_src/ examples/ misc/ share/man/ src/ tests/ Changelog LICENSE LICENSE-BSD LICENSE-GPL-2 Makefile NOTICE README.md VERSION .gitattributes .gitignore .gitmodules .mailmap .project`
* `git shortlog -sne <commit range> -- lib/ clib/ share/nitdoc/`
* To check the first commit date of an author: `git log --author=<author BRE> --reverse --date-order | less`
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Pull-Request: #2120
Reviewed-by: Jean Privat <jean@pryen.org>
Jean Privat [Tue, 24 May 2016 23:12:34 +0000 (19:12 -0400)]
Merge: Reworked crypto.nit to introduce basic XOR attacks
lib/crypto:
`crypto.nit` was getting pretty overwhelmed with the upcoming changes so it was exploded into a package.
Introduced classes for cipher management to help with attacks.
lib/crapto:
Introduced 2 attacks on basic XOR ciphers.
Pull-Request: #2080
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Jean Privat [Tue, 24 May 2016 23:12:29 +0000 (19:12 -0400)]
Merge: Added `copy_from` service to `NativeString`
Usability PR, since I got tired of handling indexes and different structures manually, this method abstracts the job of copying the content of a `Text` to a `NativeString` object.
Pull-Request: #2062
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Philippe Pepos Petitclerc [Sat, 14 May 2016 01:20:41 +0000 (21:20 -0400)]
lib/crapto: Introduce 2 new attacks on XOR ciphers
Introduced an attack on Single-byte XOR cipher based on english frequency analysis
Introduced an attack on Repeated-key XOR cipher based on hamming distances and Single-byte XOR attacks.
Signed-off-by: Philippe Pepos Petitclerc <ppeposp@gmail.com>
Philippe Pepos Petitclerc [Sat, 14 May 2016 01:08:53 +0000 (21:08 -0400)]
lib/crypto: Introduce XOR cipher management classes
Introduced Single-byte XOR cipher management class
Introduced Repeating-key XOR cipher management class
Signed-off-by: Philippe Pepos Petitclerc <ppeposp@gmail.com>
Philippe Pepos Petitclerc [Sat, 14 May 2016 14:59:08 +0000 (10:59 -0400)]
lib/crypto: Explode crypto.nit into package
Basic ciphers and utils are in basic_ciphers.nit
XOR-focused algorithms are in xor_ciphers.nit
Signed-off-by: Philippe Pepos Petitclerc <ppeposp@gmail.com>
Lucas Bajolet [Tue, 24 May 2016 14:23:42 +0000 (10:23 -0400)]
tests: Added `Text::copy_to_native` test
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>
Jean Privat [Tue, 24 May 2016 13:16:47 +0000 (09:16 -0400)]
Merge: Revamp Clock to return float values for easier memory management
This PR updates the main services of `Clock` to return float values instead of malloced extern instances of `Timespec`. There is a precision loss, but it's sufficient for games and the likes, and a program needing higher precision can still use `Timespec` directly. Clients don't even have to worry about memory management anymore.
Pull-Request: #2117
Reviewed-by: Jean Privat <jean@pryen.org>
Jean Privat [Tue, 24 May 2016 13:16:42 +0000 (09:16 -0400)]
Merge: Implementing the Nit wrapper over the native postgres wrapper
This wrapper works around the `native_postgres.nit` class and implements the minimal amount of functionality of that class to start a connection, use the execution methods, and inspect the results. It's the next phase in the postgres package, I've also added tests.
@xymus
Pull-Request: #2104
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
itsWill [Tue, 17 May 2016 21:32:38 +0000 (23:32 +0200)]
started working on the nit wrapper over the native postgres wrapper
Signed-off-by: itsWill <guilhermerpmansur@gmail.com>
Alexis Laferrière [Mon, 23 May 2016 23:50:24 +0000 (19:50 -0400)]
niti: filter the -lrt flag on OS X
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Jean-Christophe Beaupré [Mon, 23 May 2016 23:36:37 +0000 (19:36 -0400)]
NOTICE: Update author list and years
Signed-off-by: Jean-Christophe Beaupré <jcbrinfo@users.noreply.github.com>
Alexis Laferrière [Mon, 23 May 2016 02:03:44 +0000 (22:03 -0400)]
Benitlux app: revamp UI of the login/signup screen and double check passwords
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Jean Privat [Mon, 23 May 2016 02:28:26 +0000 (22:28 -0400)]
Merge: A few game related services and tweaks
Once again, here are some details on less intuitive commits:
* `AMotionEventAction::down_time` is used to better understand and respond to complex touch gestures.
* Serialization caches are accessed in the game WBTW to selectively delete data from the memory.
* `ThinGame::tick` is basically a counter of the current game logic frame. This value must be modified externally in mutliplayer games or sometimes when deserializing a game.
* `ImprovedNoise` can be useful in the lib, from experience it gives a better result that our current noise algorithms and it is in 3D. However it has less customization options.
* `EulerCamera::camera_to_world` is used to translate mouse position to in-world 3D coordinates in simple games viewed from directly above or from the side, like SDO and Action Nitro.
Pull-Request: #2119
Reviewed-by: Jean Privat <jean@pryen.org>
Jean Privat [Mon, 23 May 2016 02:28:15 +0000 (22:28 -0400)]
Merge: Update xymus.net to activate the full API for the mobile client
This PR activates full support for the Benilux mobile app on the [xymus.net](xymus.net) production server. It was missing only the RESTful API code which is generated by nitrestful, and the admin interface.
A future PR will update the HTML interface with info on the app, or it will drop the hard coded content of the Benitlux page/views in favor of local content.
Pull-Request: #2118
Reviewed-by: Jean Privat <jean@pryen.org>
Alexis Laferrière [Mon, 23 May 2016 02:02:30 +0000 (22:02 -0400)]
Benitlux app: show server messages on the login/signup screen
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Mon, 23 May 2016 02:00:09 +0000 (22:00 -0400)]
Benitlux App: clean up dead code
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 22 May 2016 20:35:23 +0000 (16:35 -0400)]
tests: remove the orphaned file xymus_net.res
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 22 May 2016 18:44:11 +0000 (14:44 -0400)]
xymus.net: add missing package metadata, gitignore and README
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 22 May 2016 18:49:13 +0000 (14:49 -0400)]
xymus.net: move server config to contrib
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 22 May 2016 18:22:17 +0000 (14:22 -0400)]
tests: remove reference to the old location of nitcorn examples
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 21 May 2016 17:16:05 +0000 (13:16 -0400)]
xymus.net: update xymus.net with the API for the mobile client
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 22 May 2016 15:51:18 +0000 (11:51 -0400)]
test: update test_kill_process to revamped Clock
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Wed, 24 Feb 2016 22:06:01 +0000 (17:06 -0500)]
lib/gamnit: intro EulerCamera::camera_to_world
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 26 Jul 2015 11:37:56 +0000 (07:37 -0400)]
lib/noise: fix missing doubling of the permutation array
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Wed, 9 Sep 2015 23:55:57 +0000 (19:55 -0400)]
lib/noise: move ImprovedNoise from the rosetta perlin noise example
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 22 May 2016 13:52:48 +0000 (09:52 -0400)]
contrib & lib: fix other clients of clock
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 22 May 2016 13:48:53 +0000 (09:48 -0400)]
tests & lib/realtime: rewrite test as a nitunit
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Jean Privat [Sun, 22 May 2016 12:56:17 +0000 (08:56 -0400)]
Merge: Refactorize nitunit
Future improvement of nitunit require a saner codebase.
This PR does not bring a lot of features but propose instead some code improvements.
Summary:
* a new class UnitTest to factorize DocUnit and TestCase
* DocUnit are created, with its metadata, while discovered
* DocUnit do not enclose a XML node to fill but will generate one with to_xml.
* Easter egg: precise locations are included in the DocUnits. Each line of *collected* code can be located back to the original source code. This feature is not really used yet, except to locate the docunit itself.
The last commits are divided in order to make the reviewing more easy. I tought that is was better than a big stashed change.
Future PR will target usability since unit-tests are now reified in a common way on both sides (docunits and testsuites).
Pull-Request: #2114
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexis Laferrière [Fri, 12 Jun 2015 21:12:38 +0000 (17:12 -0400)]
lib/serialization: let refinements and subclasses access caches
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Wed, 29 Oct 2014 13:36:38 +0000 (09:36 -0400)]
lib/a_star: intro `find_closest`
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Thu, 28 May 2015 20:30:28 +0000 (16:30 -0400)]
lib/bucketed_game: make `ThinGame::tick` writable for loading and multiplayer
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Mon, 18 May 2015 11:46:18 +0000 (07:46 -0400)]
lib/bucketed_game: intro services to get stats on buckets
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Fri, 30 Jan 2015 14:57:46 +0000 (09:57 -0500)]
lib/android: intro motion down_time
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 21 May 2016 13:59:33 +0000 (09:59 -0400)]
lib & contrib: update users of Clock
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 21 May 2016 13:50:25 +0000 (09:50 -0400)]
lib/realtime: free attributes of Clock at finalize_once
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 21 May 2016 13:57:52 +0000 (09:57 -0400)]
lib/realtime: fix clock to return mostly Float values
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 21 May 2016 04:19:00 +0000 (00:19 -0400)]
lib/realtime: fix `Timespec::-`
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Fri, 12 Jun 2015 21:12:55 +0000 (17:12 -0400)]
lib/realtime: intro `Clock::peek_lapse`
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Jean Privat [Sat, 21 May 2016 05:40:50 +0000 (01:40 -0400)]
Merge: Document Docker
Add documentation and an example of a docker image for a Nit application
Pull-Request: #2116
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Jean Privat [Sat, 21 May 2016 05:40:41 +0000 (01:40 -0400)]
Merge: gamnit: miscellaneous services and a few fixes
This PR groups features required by my recent unpublished tech demos built on gamnit.
Here are more details on the less intuitive commits:
* The change to `current_fps` lets a program use it right from the beginning and gives a value which is somewhat realistic (vs returning 0).
* The `placeholder_model` can be useful when quickly writing the prototype of a game to get something visible in the 3D space.
* The doc of `subtexture` clarifies an ambiguity as to whether the method expected pixel offsets or proportional values out of 1.0.
* The tool `texture_atlas_parser` can be useful to other games.
* `draw_mode` is very useful to create optimized `Mesh`, using `gl_TRIANGLE_STRIP` and `gl_TRIANGLE_FAN`.
* The old API of `triangulate` was counter-intuitive. The result was put in a parameter and the list of points was cleared in the process. This PR offers a simple method and the recursive implementation as an optimized alternative. ping @BlackMinou
* `tinks_vr` is not playable but it shows how to convert a gamnit game to a basic VR version.
Pull-Request: #2115
Reviewed-by: Jean Privat <jean@pryen.org>
Jean Privat [Sat, 21 May 2016 05:40:13 +0000 (01:40 -0400)]
Merge: src/platforms: fallback to version field "0" on error when asking for a git_revision
The _app.nit_ annotation `version` sets the version of mobile app packages (.apk and .app). For example, `version(1, 5, git_revision)` may produce the version string "1.5.6b42a7c".
This PR fixes an error when asking for a `git_revision` but the call to `git rev-parse` fails.
Note that the normal git error is printed before the nitc warning message, so debugging should be easy.
Close #2111
Pull-Request: #2113
Reviewed-by: Jean Privat <jean@pryen.org>
Jean Privat [Sat, 21 May 2016 05:40:11 +0000 (01:40 -0400)]
Merge: Nitweb uses popcorn
Get rid of plain corn boiler plate code from nitweb.
Consider only the last two commits since the others are from #2094 and #2110.
Pull-Request: #2112
Reviewed-by: Jean Privat <jean@pryen.org>
Jean Privat [Sat, 21 May 2016 05:39:19 +0000 (01:39 -0400)]
docker: add a README
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Sat, 21 May 2016 05:38:59 +0000 (01:38 -0400)]
docker: add a Dockerfile example
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Sat, 21 May 2016 05:37:17 +0000 (01:37 -0400)]
Fix PATH and WORKDIR with Docker images
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Sat, 21 May 2016 05:35:17 +0000 (01:35 -0400)]
tests: update sav for nitunit
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Fri, 20 May 2016 18:51:15 +0000 (14:51 -0400)]
nitunit/docunit: consider invalid-block as prefailed nitunits
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Fri, 20 May 2016 18:50:09 +0000 (14:50 -0400)]
nitunit: remove old tc object used for names
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Fri, 20 May 2016 18:45:54 +0000 (14:45 -0400)]
nitunit: DocUnit is also a TestUnit
Signed-off-by: Jean Privat <jean@pryen.org>
Alexandre Terrasa [Fri, 20 May 2016 00:01:31 +0000 (20:01 -0400)]
src/web: nitweb use popcorn
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexandre Terrasa [Thu, 19 May 2016 23:46:56 +0000 (19:46 -0400)]
src/web: render do not require the server reference anymore
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>
Alexis Laferrière [Mon, 18 Jan 2016 04:59:35 +0000 (23:59 -0500)]
contrib/tinks: add VR
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Tue, 23 Feb 2016 17:24:47 +0000 (12:24 -0500)]
lib/geometry: change triangulate API for easier usage
The old API was counter intuitive. The result was put in a parameter and
the list of points was cleared in the process.
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Wed, 10 Feb 2016 02:37:56 +0000 (21:37 -0500)]
lib/gamnit: intro draw_mode
This is very useful to create optimized Mesh, using gl_TRIANGLE_STRIP and gl_TRIANGLE_FAN.
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Fri, 20 May 2016 18:35:51 +0000 (14:35 -0400)]
lib/gamnit & egl: extract number of color bits as attributes
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 7 Feb 2016 18:37:55 +0000 (13:37 -0500)]
lib/gamnit: fix order on the color bits count
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 7 Feb 2016 17:22:58 +0000 (12:22 -0500)]
lib/gamnit: rename GamnitAssetTexture to TextureAsset
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sun, 7 Feb 2016 17:22:13 +0000 (12:22 -0500)]
lib/gamnit: fix wrap of subtextures on models
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 6 Feb 2016 23:53:32 +0000 (18:53 -0500)]
lib/gamnit: move texture_atlas_parser
This tool can be useful to other games.
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 6 Feb 2016 23:48:11 +0000 (18:48 -0500)]
lib/gamnit: intro GamnitProgram::diagnose
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Thu, 21 Jan 2016 16:27:50 +0000 (11:27 -0500)]
lib/gamnit: fix `cube::tex_coords`
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Wed, 20 Apr 2016 11:33:47 +0000 (07:33 -0400)]
lib/gamnit: improve doc of subtexture with a vital detail
There was an ambiguity as to whether the method expected pixel offsets original
proportional values out of 1.0.
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 16 Apr 2016 16:06:19 +0000 (12:06 -0400)]
lib/gamnit: extract placeholder model
This model can be useful when quickly writing the prototype of a game
to get something visible in the 3D space.
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Alexis Laferrière [Sat, 16 Apr 2016 16:06:07 +0000 (12:06 -0400)]
lib/gamnit: initialize `current_fps` to `maximum_fps`
This lets a program use `current_fps` right from the beginning and
gives a value which is somewhat realistic (vs returning 0).
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Jean Privat [Fri, 20 May 2016 18:41:52 +0000 (14:41 -0400)]
nitunit: new class UnitTest to factorize TestCase and DocUnit
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Fri, 20 May 2016 17:26:35 +0000 (13:26 -0400)]
nitunit: docunit have their own location
Signed-off-by: Jean Privat <jean@pryen.org>
Jean Privat [Fri, 20 May 2016 17:24:11 +0000 (13:24 -0400)]
nitunit: docunits are directly created while discovering.
No need to create then latter.
Signed-off-by: Jean Privat <jean@pryen.org>
Alexis Laferrière [Fri, 20 May 2016 14:40:42 +0000 (10:40 -0400)]
src/platforms: fallback to "0" on error when asking for a git_revision
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>
Jean Privat [Fri, 20 May 2016 02:29:50 +0000 (22:29 -0400)]
Merge: Update nitweb
Update nitweb to use #2024 and #2041.
Pull-Request: #2110
Reviewed-by: Jean Privat <jean@pryen.org>
Jean Privat [Fri, 20 May 2016 02:29:46 +0000 (22:29 -0400)]
Merge: Split and improve Docker
I splitted the image in a light and a full one: https://hub.docker.com/r/privat/mynit/tags/
* the light one contains only the nit tools the the packages to build them. 225MB
* the full one contains most libraries, tools like inkscape, and the android sdk. 2GB
Pull-Request: #2109
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Jean Privat [Fri, 20 May 2016 02:29:41 +0000 (22:29 -0400)]
Merge: nitcatalog: count warnings per 1000 lines of code (w/kloc)
The raw number of warnings is not that useful.
Number of warnings per 1000 lines of code make it more semantic.
Signed-off-by: Jean Privat <jean@pryen.org>
Pull-Request: #2108
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Jean Privat [Fri, 20 May 2016 02:29:34 +0000 (22:29 -0400)]
Merge: Popcorn
# Popcorn
**Why endure plain corn when you can pop it?!**
Popcorn is a minimal yet powerful nit web application framework that provides cool
features for lazy developpers.
Popcorn is built over nitcorn to provide a clean and user friendly interface
without all the boiler plate code.
## What does it taste like?
Set up is quick and easy as 10 lines of code.
Create a file `app.nit` and add the following code:
~~~nit
import popcorn
class HelloHandler
super Handler
redef fun get(req, res) do res.html "<h1>Hello World!</h1>"
end
var app = new App
app.use("/", new HelloHandler)
# app.listen("localhost", 3000)
~~~
The Popcorn app listens on port 3000 for connections.
The app responds with "Hello World!" for requests to the root URL (`/`) or **route**.
For every other path, it will respond with a **404 Not Found**.
The `req` (request) and `res` (response) parameters are the same that nitcorn provides
so you can do anything else you would do in your route without Popcorn involved.
Run the app with the following command:
~~~bash
nitc app.nit && ./app
~~~
Then, load [http://localhost:3000](http://localhost:3000) in a browser to see the output.
This is why we love popcorn!
## Basic routing
**Routing** refers to determining how an application responds to a client request
to a particular endpoint, which is a URI (or path) and a specific HTTP request
method GET, POST, PUT or DELETE (other methods are not suported yet).
Each route can have one or more handler methods, which are executed when the route is matched.
Route handlers definition takes the following form:
~~~nit
import popcorn
class MyHandler
super Handler
redef fun METHOD(req, res) do end
end
~~~
Where:
* `MyHandler` is the name of the handler you will add to the app.
* `METHOD` can be replaced by `get`, `post`, `put` or `delete`.
The following example responds with `Hello World!` to GET and POST requests:
~~~nit
import popcorn
class MyHandler
super Handler
redef fun get(req, res) do res.send "Got a GET request"
redef fun post(req, res) do res.send "Got a POST request"
end
~~~
To make your handler responds to a specific route, you have to add it to the app.
Respond to POST request on the root route (`/`), the application's home page:
~~~nit
var app = new App
app.use("/", new MyHandler)
~~~
Respond to a request to the `/user` route:
~~~nit
app.use("/user", new MyHandler)
~~~
For more details about routing, see the routing section.
## Serving static files with Popcorn
To serve static files such as images, CSS files, and JavaScript files, use the
Popcorn built-in handler `StaticHandler`.
Pass the name of the directory that contains the static assets to the StaticHandler
init method to start serving the files directly.
For example, use the following code to serve images, CSS files, and JavaScript files
in a directory named `public`:
~~~nit
app.use("/", new StaticHandler("public/"))
~~~
Now, you can load the files that are in the `public` directory:
~~~raw
http://localhost:3000/images/trollface.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/hello.html
~~~
Popcorn looks up the files relative to the static directory, so the name of the
static directory is not part of the URL.
To use multiple static assets directories, add the `StaticHandler` multiple times:
~~~nit
app.use("/", new StaticHandler("public/"))
app.use("/", new StaticHandler("files/"))
~~~
Popcorn looks up the files in the order in which you set the static directories
with the `use` method.
To create a virtual path prefix (where the path does not actually exist in the file system)
for files that are served by the `StaticHandler`, specify a mount path for the
static directory, as shown below:
~~~nit
app.use("/static/", new StaticHandler("public/"))
~~~
Now, you can load the files that are in the public directory from the `/static`
path prefix.
~~~raw
http://localhost:3000/static/images/trollface.jpg
http://localhost:3000/static/css/style.css
http://localhost:3000/static/js/app.js
http://localhost:3000/static/hello.html
~~~
However, the path that you provide to the `StaticHandler` is relative to the
directory from where you launch your app.
If you run the app from another directory, it’s safer to use the absolute path of
the directory that you want to serve.
## Advanced Routing
**Routing** refers to the definition of application end points (URIs) and how
they respond to client requests. For an introduction to routing, see the Basic routing
section.
The following code is an example of a very basic route.
~~~nit
import popcorn
class HelloHandler
super Handler
redef fun get(req, res) do res.send "Hello World!"
end
var app = new App
app.use("/", new HelloHandler)
~~~
### Route methods
A **route method** is derived from one of the HTTP methods, and is attached to an
instance of the Handler class.
The following code is an example of routes that are defined for the GET and the POST
methods to the root of the app.
~~~nit
import popcorn
class GetPostHandler
super Handler
redef fun get(req, res) do res.send "GET request to the homepage"
redef fun post(req, res) do res.send "POST request to the homepage"
end
var app = new App
app.use("/", new GetPostHandler)
~~~
Popcorn supports the following routing methods that correspond to HTTP methods:
get, post, put, and delete.
The request query string is accessed through the `req` parameter:
~~~nit
import popcorn
import template
class QueryStringHandler
super Handler
redef fun get(req, res) do
var tpl = new Template
tpl.addn "URI: {req.uri}"
tpl.addn "Query string: {req.query_string}"
for name, arg in req.get_args do
tpl.addn "{name}: {arg}"
end
res.send tpl
end
end
var app = new App
app.use("/", new QueryStringHandler)
# app.listen("localhost", 3000)
~~~
Post parameters can also be accessed through the `req` parameter:
~~~nit
import popcorn
import template
class PostHandler
super Handler
redef fun post(req, res) do
var tpl = new Template
tpl.addn "URI: {req.uri}"
tpl.addn "Body: {req.body}"
for name, arg in req.post_args do
tpl.addn "{name}: {arg}"
end
res.send tpl
end
end
var app = new App
app.use("/", new PostHandler)
# app.listen("localhost", 3000)
~~~
There is a special routing method, `all(res, req)`, which is not derived from any
HTTP method. This method is used to respond at a path for all request methods.
In the following example, the handler will be executed for requests to "/user"
whether you are using GET, POST, PUT, DELETE, or any other HTTP request method.
~~~nit
import popcorn
class AllHandler
super Handler
redef fun all(req, res) do res.send "Every request to the homepage"
end
~~~
Using the `all` method you can also implement other HTTP request methods.
~~~nit
import popcorn
class MergeHandler
super Handler
redef fun all(req, res) do
if req.method == "MERGE" then
# handle that method
else super # keep handle GET, POST, PUT and DELETE methods
end
end
~~~
### Route paths
**Route paths**, in combination with a request handlers, define the endpoints at
which requests can be made.
Route paths can be strings, parameterized strings or glob patterns.
Query strings such as `?q=foo`are not part of the route path.
Popcorn uses the `Handler::match(uri)` method to match the route paths.
Here are some examples of route paths based on strings.
This route path will match requests to the root route, `/`.
~~~nit
import popcorn
class MyHandler
super Handler
redef fun get(req, res) do res.send "Got a GET request"
end
var app = new App
app.use("/", new MyHandler)
~~~
This route path will match requests to `/about`.
~~~nit
app.use("/about", new MyHandler)
~~~
This route path will match requests to `/random.text`.
~~~nit
app.use("/random.text", new MyHandler)
~~~
During the query/response process, routes are matched by order of declaration
through the `App::use` method.
The app declared in this example will try to match the routes in this order:
1. `/`
2. `/about`
3. `/random.text`
### Route parameters
**Route parameters** are variable parts of a route path. They can be used to path
arguments within the URI.\13
Parameters in a route are prefixed with a colon `:` like in `:userId`, `:year`.
The following example declares a handler `UserHome` that responds with the `user`
name.
~~~nit
import popcorn
class UserHome
super Handler
redef fun get(req, res) do
var user = req.param("user")
if user != null then
res.send "Hello {user}"
else
res.send("Nothing received", 400)
end
end
end
var app = new App
app.use("/:user", new UserHome)
# app.listen("localhost", 3000)
~~~
The `UserHome` handler listen to every path matching `/:user`. This can be `/Morriar`,
`/10`, ... but not `/Morriar/profile` since route follow the strict matching rule.
### Glob routes
**Glob routes** are routes that match only on a prefix, thus accepting a wider range
of URI.
Glob routes end with the symbol `*`.
Here we define a `UserItem` handler that will respond to any URI matching the prefix
`/user/:user/item/:item`.
Note that glob route are compatible with route parameters.
~~~nit
import popcorn
class UserItem
super Handler
redef fun get(req, res) do
var user = req.param("user")
var item = req.param("item")
if user == null or item == null then
res.send("Nothing received", 400)
else
res.send "Here the item {item} of the use {user}."
end
end
end
var app = new App
app.use("/user/:user/item/:item/*", new UserItem)
# app.listen("localhost", 3000)
~~~
## Response methods
The methods on the response object (`res`), can is used to manipulate the
request-response cycle.
If none of these methods are called from a route handler, the client request will
receive a `404 Not found` error.
* `res.html()` Send a HTML response.
* `res.json()` Send a JSON response.
* `res.redirect()` Redirect a request.
* `res.send()` Send a response of various types.
* `res.error()` Set the response status code and send its message as the response body.
## Middlewares
### Overview
**Middleware** handlers are handlers that typically do not send `HttpResponse` responses.
Middleware handlers can perform the following tasks:
* Execute any code.
* Make changes to the request and the response objects.
* End its action and pass to the next handler in the stack.
If a middleware handler makes a call to `res.send()`, it provoques the end the
request-response cycle and the response is sent to the client.
### Ultra simple logger example
Here is an example of a simple “Hello World” Popcorn application.
We add a middleware handler to the application called MyLogger that prints a simple
log message in the app stdout.
~~~nit
import popcorn
class MyLogger
super Handler
redef fun all(req, res) do print "Request Logged!"
end
class HelloHandler
super Handler
redef fun get(req, res) do res.send "Hello World!"
end
var app = new App
app.use("/*", new MyLogger)
app.use("/", new HelloHandler)
# app.listen("localhost", 3000)
~~~
By using the `MyLogger` handler to the route `/*` we ensure that every requests
(even 404 ones) pass through the middleware handler.
This handler just prints “Request Logged!” when a request is received.
The order of middleware loading is important: middleware functions that are loaded first are also executed first.
In the above example, `MyLogger` will be executed before `HelloHandler`.
### Ultra cool, more advanced logger example
Next, we’ll create a middleware handler called “LogHandler” that prints the requested
uri, the response status and the time it took to Popcorn to process the request.
~~~nit
import popcorn
import realtime
redef class HttpRequest
# Time that request was received by the Popcorn app.
var timer: nullable Clock = null
end
class RequestTimeHandler
super Handler
redef fun all(req, res) do req.timer = new Clock
end
class LogHandler
super Handler
redef fun all(req, res) do
var timer = req.timer
if timer != null then
print "{req.method} {req.uri} {res.color_status} ({timer.total})"
else
print "{req.method} {req.uri} {res.color_status}"
end
end
end
class HelloHandler
super Handler
redef fun get(req, res) do res.send "Hello World!"
end
var app = new App
app.use("/*", new RequestTimeHandler)
app.use("/", new HelloHandler)
app.use("/*", new LogHandler)
# app.listen("localhost", 3000)
~~~
First, we attach a new attribute `timer` to every `HttpRequest`.
Doing so we can access our data from all handlers that import our module, directly
from the `req` parameter.
We use the new middleware called `RequestTimeHandler` to initialize the request timer.
Finally, our `LogHandler` will display a bunch of data and use the request `timer`
to display the time it took to process the request.
The app now uses the `RequestTimeHandler` middleware for every requests received
by the Popcorn app.
The page is processed the `HelloHandler` to display the index page.
And, before every response is sent, the `LogHandler` is activated to display the
log line.
Because you have access to the request object, the response object, and all the
Popcorn API, the possibilities with middleware functions are endless.
### Built-in middlewares
Starting with version 0.1, Popcorn provide a set of built-in middleware that can
be used to develop your app faster.
* `RequestClock`: initializes requests clock.
* `ConsoleLog`: displays resquest and response status in console (can be used with `RequestClock`).
* `SessionInit`: initializes requests session (see the `Sessions` section).
* `StaticServer`: serves static files (see the `Serving static files with Popcorn` section).
* `Router`: a mountable mini-app (see the `Mountable routers` section).
## Mountable routers
Use the `Router` class to create modular, mountable route handlers.
A Router instance is a complete middleware and routing system; for this reason,
it is often referred to as a “mini-app”.
The following example creates a router as a module, loads a middleware handler in it,
defines some routes, and mounts the router module on a path in the main app.
~~~nit
import popcorn
class AppHome
super Handler
redef fun get(req, res) do res.send "Site Home"
end
class UserLogger
super Handler
redef fun all(req, res) do print "User logged"
end
class UserHome
super Handler
redef fun get(req, res) do res.send "User Home"
end
class UserProfile
super Handler
redef fun get(req, res) do res.send "User Profile"
end
var user_router = new Router
user_router.use("/*", new UserLogger)
user_router.use("/", new UserHome)
user_router.use("/profile", new UserProfile)
var app = new App
app.use("/", new AppHome)
app.use("/user", user_router)
# app.listen("localhost", 3000)
~~~
The app will now be able to handle requests to /user and /user/profile, as well
as call the `Time` middleware handler that is specific to the route.
## Error handling
**Error handling** is based on middleware handlers.
Define error-handling middlewares in the same way as other middleware handlers:
~~~nit
import popcorn
class SimpleErrorHandler
super Handler
redef fun all(req, res) do
if res.status_code != 200 then
print "An error occurred! {res.status_code})"
end
end
end
class HelloHandler
super Handler
redef fun get(req, res) do res.send "Hello World!"
end
var app = new App
app.use("/", new HelloHandler)
app.use("/*", new SimpleErrorHandler)
# app.listen("localhost", 3000)
~~~
In this example, every non-200 response is caught by the `SimpleErrorHandler`
that print an error in stdout.
By defining multiple middleware error handlers, you can take multiple action depending
on the kind of error or the kind of interface you provide (HTML, XML, JSON...).
Here an example of the 404 custom error page in HTML:
~~~nit
import popcorn
import template
class HtmlErrorTemplate
super Template
var status: Int
var message: nullable String
redef fun rendering do add """
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{{message or else status}}}</title>
</head>
<body>
<h1>{{{status}}} {{{message or else ""}}}</h1>
</body>
</html>"""
end
class HtmlErrorHandler
super Handler
redef fun all(req, res) do
if res.status_code != 200 then
res.send(new HtmlErrorTemplate(res.status_code, "An error occurred!"))
end
end
end
var app = new App
app.use("/*", new HtmlErrorHandler)
# app.listen("localhost", 3000)
~~~
## Sessions
**Sessions** can be used thanks to the built-in `SessionMiddleware`.
Here a simple example of login button that define a value in the `req` session.
~~~nit
import popcorn
redef class Session
var is_logged = false
end
class AppLogin
super Handler
redef fun get(req, res) do
res.html """
<p>Is logged: {{{req.session.as(not null).is_logged}}}</p>
<form action="/" method="POST">
<input type="submit" value="Login" />
</form>"""
end
redef fun post(req, res) do
req.session.as(not null).is_logged = true
res.redirect("/")
end
end
var app = new App
app.use("/*", new SessionInit)
app.use("/", new AppLogin)
# app.listen("localhost", 3000)
~~~
Notice the use of the `SessionInit` on the `/*` route. You must use the
`SessionInit` first to initialize the request session.
Without that, your request session will be set to `null`.
If you don't use sessions in your app, you do not need to include that middleware.
## Database integration
### Mongo DB
If you want to persist your data, Popcorn works well with MongoDB.
In this example, we will show how to store and list user with a Mongo database.
First let's define a handler that access the database to list all the user.
The mongo database reference is passed to the UserList handler through the `db` attribute.
Then we define a handler that displays the user creation form on GET requests.
POST requests are used to save the user data.
~~~nit
import popcorn
import mongodb
import template
class UserList
super Handler
var db: MongoDb
redef fun get(req, res) do
var users = db.collection("users").find_all(new JsonObject)
var tpl = new Template
tpl.add "<h1>Users</h1>"
tpl.add "<table>"
for user in users do
tpl.add """<tr>
<td>{{{user["login"] or else "null"}}}</td>
<td>{{{user["password"] or else "null"}}}</td>
</tr>"""
end
tpl.add "</table>"
res.html tpl
end
end
class UserForm
super Handler
var db: MongoDb
redef fun get(req, res) do
var tpl = new Template
tpl.add """<h1>Add a new user</h1>
<form action="/new" method="POST">
<input type="text" name="login" />
<input type="password" name="password" />
<input type="submit" value="save" />
</form>"""
res.html tpl
end
redef fun post(req, res) do
var json = new JsonObject
json["login"] = req.post_args["login"]
json["password"] = req.post_args["password"]
db.collection("users").insert(json)
res.redirect "/"
end
end
var mongo = new MongoClient("mongodb://localhost:27017/")
var db = mongo.database("mongo_example")
var app = new App
app.use("/", new UserList(db))
app.use("/new", new UserForm(db))
# app.listen("localhost", 3000)
~~~
## Angular.JS integration
Loving [AngularJS](https://angularjs.org/)? Popcorn is made for Angular and for you!
Using the StaticHandler with a glob route, you can easily redirect all HTTP requests
to your angular controller:
~~~nit
import popcorn
var app = new App
app.use("/*", new StaticHandler("my-ng-app/"))
# app.listen("localhost", 3000)
~~~
See the examples for a more detailed use case working with a JSON API.
Pull-Request: #2094
Reviewed-by: Istvan SZALAÏ <istvan.szalai@savoirfairelinux.com>
Reviewed-by: Jean Privat <jean@pryen.org>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>