/* Copyright 2010 Aaron J. Radke Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package cc.drx //to be determined essential features of a dynamic Sketch with functions of functions aggregated trait Sketch extends Shape{ //whoah a Sketch can itself be a shape! nice composability private val drawMap:TrieMap[Int, DrawContext => Unit] = TrieMap.empty // TODO make the drawFunction fundemental type first class so a reference id can be used grab it from the graph // TODO make the drawContext return a shape that should be drawn if nothing then UnitShape /**safely add new draw functions*/ //private def unitize(f:DrawContext => Unit):DrawContext => Shape = {g:DrawContext => f(g); Shape.empty} ////deprecated("use +=(DrawContext => Shape) intead to encourage functional notions") //final def +=(f:DrawContext => Unit):Sketch = {drawMap += (drawMap.size -> unitize(f)); this} final def +=(f:DrawContext => Unit):Sketch = {drawMap += (drawMap.size -> f); this} // /**alias to safely add new draw functions*/ // final def add(f:DrawContext => Unit):Sketch = this += f final def :=(f:DrawContext => Unit):Sketch = {clear; +=(f)} /**remove all draw functions */ final def clear:Unit = drawMap.clear() /**safely access the iterator over all drawFunctions*/ final def drawFunctions = drawMap.values /**the interface of any Shape that can be sent to a render * the fact that a Sketch itself can be a shape provides nice composability * */ final def draw(implicit g:DrawContext):Unit = g ! this } // FIXME figure out how to make this work easily with some implicit rendercontext again // object Sketch{ // def apply(title:String)(implicit sketchApp:SketchApp):Sketch = ??? // } abstract class SketchApp extends Sketch { //--override-able def size:Vec = Vec(600,400) def title:String = super.toString.takeWhile(_ != '$').reverse.takeWhile(_ != '.').reverse //"cc.drx.SketchApp" def icon:ImgFile = Img find File(title + ".png") getOrElse Img("drx.png") def maxFPS:Option[Int] = Some(60) def transparent:Boolean = false def clearEachFrame:Boolean = true def background:Color = Transparent override def toString:String = s"Sketch($title, $size)" protected[drx] var _args:Array[String] = Array() def args:Array[String] = _args //--sketch function /** alias to '+=' (add) a draw function, this is a helper function to reduce boiler plate; (adds return of unit ()) when only a single draw funtion is desired in an automatic app*/ // 2017-07-30("TODO remove in favor of '+=' to make the scala collections like to lead to the scala collections like interface","dk") final def onDraw(f:DrawContext => Unit):Unit = {clear; this += f; ()} /**alias to this so a SketchApp can be easily and automatically constructed*/ def sketch:SketchApp = this //--implemented def main(args:Array[String]):Unit = {_args = args; launch(args)} //singleton launcher.. final def launch(implicit ec:ExecutionContext):Future[Unit] = Future(launch(Array[String]()))(ec) final def launch():Future[Unit] = launch(Implicit.ec) //--required def launch(args:Array[String]):Unit //= ??? //FIXME add a default java implementation or make this a trait }