<commit_before>util = require './util'
TextRenderer = require './TextRenderer'
lineEndCapShapes = require './lineEndCapShapes.coffee'
{defineCanvasRenderer, renderShapeToContext} = require './canvasRenderer'
{defineSVGRenderer, renderShapeToSVG} = require './svgRenderer'

shapes = {}


defineShape = (name, props) ->
  Shape = (args...) ->
    props.constructor.call(this, args...)
    this
  Shape.prototype.className = name
  Shape.fromJSON = props.fromJSON

  # support old style of defining canvas drawing methods on shapes
  if props.draw
    legacyDrawFunc = props.draw
    legacyDrawLatestFunc = props.draw or (ctx, bufferCtx, retryCallback) ->
      @draw(ctx, bufferCtx, retryCallback)
    drawFunc = (ctx, shape, retryCallback) ->
      legacyDrawFunc.call(shape, ctx, retryCallback)
    drawLatestFunc = (ctx, bufferCtx, shape, retryCallback) ->
      legacyDrawLatestFunc.call(shape, ctx, bufferCtx, retryCallback)
    delete props.draw 
    delete props.drawLatest if props.drawLatest

    defineCanvasRenderer(name, drawFunc, drawLatestFunc)

  # support old style of defining SVG drawing methods on shapes
  if props.toSVG
    legacySVGFunc = props.toSVG
    svgFunc = (shape) -> legacySVGFunc.call(shape)
    delete props.toSVG
    defineSVGRenderer(name, svgFunc)

  Shape.prototype.draw = (ctx, retryCallback) ->
    renderShapeToContext(ctx, this, {retryCallback})
  Shape.prototype.drawLatest = (ctx, bufferCtx, retryCallback) ->
    renderShapeToContext(
      ctx, this, {retryCallback, bufferCtx, shouldOnlyDrawLatest: true})
  Shape.prototype.toSVG = ->
    renderShapeToSVG(this)

  for k of props
    if k != 'fromJSON'
      Shape.prototype[k] = props[k]

  shapes[name] = Shape
  Shape


createShape = (name, args...) ->
  s = new shapes[name](args...)
  s.id = util.getGUID()
  s


JSONToShape = ({className, data, id}) ->
  if className of shapes
    shape = shapes[className].fromJSON(data)
    if shape
      shape.id = id if id
      return shape
    else
      console.log 'Unreadable shape:', className, data<commit_msg>Improve performance of shape creation<commit_after>util = require './util'
TextRenderer = require './TextRenderer'
lineEndCapShapes = require './lineEndCapShapes.coffee'
{defineCanvasRenderer, renderShapeToContext} = require './canvasRenderer'
{defineSVGRenderer, renderShapeToSVG} = require './svgRenderer'

shapes = {}


defineShape = (name, props) ->
  # improve Chrome JIT perf by not using arguments object
  Shape = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) ->
    props.constructor.call(this, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
    this
  Shape.prototype.className = name
  Shape.fromJSON = props.fromJSON

  # support old style of defining canvas drawing methods on shapes
  if props.draw
    legacyDrawFunc = props.draw
    legacyDrawLatestFunc = props.draw or (ctx, bufferCtx, retryCallback) ->
      @draw(ctx, bufferCtx, retryCallback)
    drawFunc = (ctx, shape, retryCallback) ->
      legacyDrawFunc.call(shape, ctx, retryCallback)
    drawLatestFunc = (ctx, bufferCtx, shape, retryCallback) ->
      legacyDrawLatestFunc.call(shape, ctx, bufferCtx, retryCallback)
    delete props.draw 
    delete props.drawLatest if props.drawLatest

    defineCanvasRenderer(name, drawFunc, drawLatestFunc)

  # support old style of defining SVG drawing methods on shapes
  if props.toSVG
    legacySVGFunc = props.toSVG
    svgFunc = (shape) -> legacySVGFunc.call(shape)
    delete props.toSVG
    defineSVGRenderer(name, svgFunc)

  Shape.prototype.draw = (ctx, retryCallback) ->
    renderShapeToContext(ctx, this, {retryCallback})
  Shape.prototype.drawLatest = (ctx, bufferCtx, retryCallback) ->
    renderShapeToContext(
      ctx, this, {retryCallback, bufferCtx, shouldOnlyDrawLatest: true})
  Shape.prototype.toSVG = ->
    renderShapeToSVG(this)

  for k of props
    if k != 'fromJSON'
      Shape.prototype[k] = props[k]

  shapes[name] = Shape
  Shape


# improve Chrome JIT perf by not using arguments object
createShape = (name, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) ->
  s = new shapes[name](a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
  s.id = util.getGUID()
  s


JSONToShape = ({className, data, id}) ->
  if className of shapes
    shape = shapes[className].fromJSON(data)
    if shape
      shape.id = id if id
      return shape
    else
      console.log 'Unreadable shape:', className, data
{'fraction_non_alphanumeric': 0.11529732183386292, 'fraction_numerical': 0.0, 'mean_word_length': 3.5763239875389408, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7450104', 'n_tokens_mistral': 1432, 'n_tokens_neox': 1416, 'n_words': 407}