From: Jean Privat Date: Sat, 21 May 2016 05:40:41 +0000 (-0400) Subject: Merge: gamnit: miscellaneous services and a few fixes X-Git-Url: http://nitlanguage.org?hp=dfe118fc99a04e4f8b706758e9624c586c17d2b5 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 --- diff --git a/src/nitweb.nit b/src/nitweb.nit index b924ec2..c055ee9 100644 --- a/src/nitweb.nit +++ b/src/nitweb.nit @@ -47,15 +47,15 @@ private class NitwebPhase var host = toolcontext.opt_host.value or else "localhost" var port = toolcontext.opt_port.value - var srv = new NitServer(host, port.to_i) - srv.routes.add new Route("/random", new RandomAction(srv, model)) - srv.routes.add new Route("/doc/:namespace", new DocAction(srv, model, modelbuilder)) - srv.routes.add new Route("/code/:namespace", new CodeAction(srv, model, modelbuilder)) - srv.routes.add new Route("/search/:namespace", new SearchAction(srv, model)) - srv.routes.add new Route("/uml/:namespace", new UMLDiagramAction(srv, model, mainmodule)) - srv.routes.add new Route("/", new TreeAction(srv, model)) + var app = new App + app.use("/random", new RandomAction(model)) + app.use("/doc/:namespace", new DocAction(model, modelbuilder)) + app.use("/code/:namespace", new CodeAction(model, modelbuilder)) + app.use("/search/:namespace", new SearchAction(model)) + app.use("/uml/:namespace", new UMLDiagramAction(model, mainmodule)) + app.use("/", new TreeAction(model)) - srv.listen + app.listen(host, port.to_i) end end diff --git a/src/platform/app_annotations.nit b/src/platform/app_annotations.nit index 62fbbb0..1d60f15 100644 --- a/src/platform/app_annotations.nit +++ b/src/platform/app_annotations.nit @@ -88,8 +88,6 @@ redef class AAnnotation return "" else for arg in args do - var format_error = "Syntax Eror: `{name}` expects its arguments to be of type Int or a call to `git_revision`." - var value value = arg.as_int if value != null then @@ -107,7 +105,13 @@ redef class AAnnotation # Get Git short revision var proc = new ProcessReader("git", "rev-parse", "--short", "HEAD") proc.wait - assert proc.status == 0 + if proc.status != 0 then + # Fallback if this is not a git repository or git bins are missing + version_fields.add "0" + modelbuilder.warning(self, "git_revision", "Warning: `git_revision` used outside of a git repository or git binaries not available") + continue + end + var lines = proc.read_all var revision = lines.split("\n").first @@ -122,6 +126,7 @@ redef class AAnnotation continue end + var format_error = "Syntax Error: `{name}` expects its arguments to be of type Int or a call to `git_revision`." modelbuilder.error(self, format_error) return "" end diff --git a/src/web/web_actions.nit b/src/web/web_actions.nit index 60d39c2..e9198ae 100644 --- a/src/web/web_actions.nit +++ b/src/web/web_actions.nit @@ -22,10 +22,10 @@ import uml class TreeAction super ModelAction - redef fun answer(request, url) do - var model = init_model_view(request) + redef fun get(req, res) do + var model = init_model_view(req) var view = new HtmlHomePage(model.to_tree) - return render_view(view) + res.send_view(view) end end @@ -34,18 +34,20 @@ class SearchAction super ModelAction # TODO handle more than full namespaces. - redef fun answer(request, url) do - var namespace = request.param("namespace") - var model = init_model_view(request) + redef fun get(req, res) do + var namespace = req.param("namespace") + var model = init_model_view(req) var mentity = find_mentity(model, namespace) if mentity == null then - return render_error(404, "No mentity found") + res.error(404) + return end - if request.is_json_asked then - return render_json(mentity.to_json) + if req.is_json_asked then + res.json(mentity.to_json) + return end var view = new HtmlResultPage(namespace or else "null", [mentity]) - return render_view(view) + res.send_view(view) end end @@ -56,15 +58,16 @@ class CodeAction # Modelbuilder used to access sources. var modelbuilder: ModelBuilder - redef fun answer(request, url) do - var namespace = request.param("namespace") - var model = init_model_view(request) + redef fun get(req, res) do + var namespace = req.param("namespace") + var model = init_model_view(req) var mentity = find_mentity(model, namespace) if mentity == null then - return render_error(404, "No mentity found") + res.error(404) + return end var view = new HtmlSourcePage(modelbuilder, mentity) - return render_view(view) + res.send_view(view) end end @@ -75,16 +78,21 @@ class DocAction # Modelbuilder used to access sources. var modelbuilder: ModelBuilder - # TODO handle more than full namespaces. - redef fun answer(request, url) do - var namespace = request.param("namespace") - var model = init_model_view(request) + redef fun get(req, res) do + var namespace = req.param("namespace") + var model = init_model_view(req) var mentity = find_mentity(model, namespace) if mentity == null then - return render_error(404, "No mentity found") + res.error(404) + return + end + if req.is_json_asked then + res.json(mentity.to_json) + return end + var view = new HtmlDocPage(modelbuilder, mentity) - return render_view(view) + res.send_view(view) end end @@ -95,12 +103,13 @@ class UMLDiagramAction # Mainmodule used for hierarchy flattening. var mainmodule: MModule - redef fun answer(request, url) do - var namespace = request.param("namespace") - var model = init_model_view(request) + redef fun get(req, res) do + var namespace = req.param("namespace") + var model = init_model_view(req) var mentity = find_mentity(model, namespace) if mentity == null then - return render_error(404, "No mentity found") + res.error(404) + return end var dot @@ -112,10 +121,11 @@ class UMLDiagramAction var uml = new UMLModel(model, mentity) dot = uml.generate_package_uml.write_to_string else - return render_error(404, "No diagram matching this namespace.") + res.error(404) + return end var view = new HtmlDotPage(dot, mentity.as(not null).html_name) - return render_view(view) + res.send_view(view) end end @@ -123,11 +133,10 @@ end class RandomAction super ModelAction - # TODO handle more than full namespaces. - redef fun answer(request, url) do - var n = request.int_arg("n") or else 10 - var k = request.string_arg("k") or else "modules" - var model = init_model_view(request) + redef fun get(req, res) do + var n = req.int_arg("n") or else 10 + var k = req.string_arg("k") or else "modules" + var model = init_model_view(req) var mentities: Array[MEntity] if k == "modules" then mentities = model.mmodules.to_a @@ -138,14 +147,15 @@ class RandomAction end mentities.shuffle mentities = mentities.sub(0, n) - if request.is_json_asked then + if req.is_json_asked then var json = new JsonArray for mentity in mentities do json.add mentity.to_json end - return render_json(json) + res.json(json) + return end var view = new HtmlResultPage("random", mentities) - return render_view(view) + res.send_view(view) end end diff --git a/src/web/web_base.nit b/src/web/web_base.nit index f37bdb4..258ec60 100644 --- a/src/web/web_base.nit +++ b/src/web/web_base.nit @@ -17,77 +17,11 @@ module web_base import model::model_views import model::model_json -import nitcorn - -# Nitcorn server runned by `nitweb`. -# -# Usage: -# -# ~~~nitish -# var srv = new NitServer("localhost", 3000) -# srv.routes.add new Route("/", new MyAction) -# src.listen -# ~~~ -class NitServer - - # Host to bind. - var host: String - - # Port to use. - var port: Int - - # Routes knwon by the server. - var routes = new Array[Route] - - # Start listen on `host:port`. - fun listen do - var iface = "{host}:{port}" - print "Launching server on http://{iface}/" - - var vh = new VirtualHost(iface) - for route in routes do vh.routes.add route - - var fac = new HttpFactory.and_libevent - fac.config.virtual_hosts.add vh - fac.run - end -end - -# Specific nitcorn Action for nitweb. -class NitAction - super Action - - # Link to the NitServer that runs this action. - var srv: NitServer - - # Build a custom http response for errors. - fun render_error(code: Int, message: String): HttpResponse do - var response = new HttpResponse(code) - var tpl = new Template - tpl.add "

Error {code}

" - tpl.add "
{message.html_escape}
" - response.body = tpl.write_to_string - return response - end - - # Render a view as a HttpResponse 200. - fun render_view(view: NitView): HttpResponse do - var response = new HttpResponse(200) - response.body = view.render(srv).write_to_string - return response - end - - # Return a HttpResponse containing `json`. - fun render_json(json: Jsonable): HttpResponse do - var response = new HttpResponse(200) - response.body = json.to_json - return response - end -end +import popcorn # Specific nitcorn Action that uses a Model class ModelAction - super NitAction + super Handler # Model to use. var model: Model @@ -116,7 +50,12 @@ end # A NitView is rendered by an action. interface NitView # Renders this view and returns something that can be written to a HTTP response. - fun render(srv: NitServer): Writable is abstract + fun render: Writable is abstract +end + +redef class HttpResponse + # Render a NitView as response. + fun send_view(view: NitView, status: nullable Int) do send(view.render, status) end redef class HttpRequest diff --git a/src/web/web_views.nit b/src/web/web_views.nit index 7273187..58016e2 100644 --- a/src/web/web_views.nit +++ b/src/web/web_views.nit @@ -27,7 +27,7 @@ class HtmlHomePage # Loaded model to display. var tree: MEntityTree - redef fun render(srv) do + redef fun render do var tpl = new Template tpl.add new Header(1, "Loaded model") tpl.add tree.html_list @@ -45,7 +45,7 @@ class HtmlResultPage # Result set var results: Array[MEntity] - redef fun render(srv) do + redef fun render do var tpl = new Template tpl.add new Header(1, "Results for {query}") if results.is_empty then @@ -76,7 +76,7 @@ class HtmlSourcePage # HiglightVisitor used to hilight the source code var hl = new HighlightVisitor - redef fun render(srv) do + redef fun render do var tpl = new Template tpl.add new Header(1, "Source Code") tpl.add render_source @@ -103,7 +103,7 @@ end class HtmlDocPage super HtmlSourcePage - redef fun render(srv) do + redef fun render do var tpl = new Template tpl.add new Header(1, mentity.html_name) tpl.add "

" @@ -130,7 +130,7 @@ class HtmlDotPage # Page title. var title: String - redef fun render(srv) do + redef fun render do var tpl = new Template tpl.add new Header(1, title) tpl.add render_dot