* TODO refactor by event sourcing


** DONE demo


# event
#   express by json data instead of type
#   # global share
#   register event json data


# event's event(can recursive)



emit event layer
  support sync and async?


handle event layer


control event layer


register event layer

  # one app only has one extension(protocol define type)
  one app only has one extension protocol define type
    event name: enum
    type: event input data, event output data(support sync and async)
  # (empty extension implement?)
  extension implement is control event?
  define all posible events





# low level

# high level
event sourcing

  event store
    only add, no update and delete

    # should store: event and event config(direction, type, ...) and input data(except state)(data = outside data + domain model)(if data is Big Immutable Data, use id instead) 

    should store: event data + outside data
      event data = event and event config(direction, type, ...) and input data(except state)(data = outside data id + domain model)


    # + Big Immutable Data(only add, no delete or edit)
      # e.g. first event can be: load with input data: pacakge id

    # store Big Immutable Data(e.g. GLB asset, Image), generated unqiue id for each one
    if outside data is Big Data(e.g. GLB asset, Image), generated unqiue id for each one
    state should store id of Big Data
    store them in another extension's state(only add, no delete or edit)(if is Mutable, need deep copy and store; else, not copy and directly store)


  register event:
    forward
      handle
    backward
      handle

    only need one direction's input, output data type

    handle can use deepCopy, restore


  # event add flag:
  #   # e.g. need_redo_undo
  #   e.g. main(means need redo undo)

  # event add read/write type
  #   only write event need implement backward handle

  event can has parent->children
    e.g. dispose gameObject is parent event, dispose gameObjects' component is its children events
    this usage is to only redo/undo the top event(has no parent)

engine demo can choose not use event sourcing?



when backward, invoke each event's backward handle in event store(children->parent)


# ** TODO demo2: event data add type=write

# perf: if is read, forward/backward just ignore it!

# ** TODO demo: init,update pipeline add job event
** DONE demo: add event after init



** DONE apply event sourcing
action,ui control use event sourcing


redo-undo:
  forward/backward events
    ////add backward event to event store instead of edit events in event store! 

    ignore pipeline job event 

# run->redo/undo: 
#   backward before run

debug:
  get all events to restore env 
    how to restore backend data?(no need because of different version?)
  can show all events


multi edit demo:
  solve conflict


  # TODO learn websocket


  # TODO split update view and add event, now update view(forward new events) once in each frame

  ////TODO inject hook



  ////TODO update redo/undo


  TODO implement
    # - load glb
    # - for multi edit
    # - for debug
    - for redo/undo
    - other actions(include import/export)
    - consider scene(import/export)

  TODO remove output data


  TODO on->backwardHandleFunc can be ?(use undo for default implement)


profile:
  get cost time of each event grouped by each frame

TODO implement



add some event handles before(get inputData-return inputData)/after(get outputData-return outputData) specify event?



publish->app:
  load scene

  debug

  save/load: e.g. continue last saved game

  timeline backward or forward(redo-undo)

  multi thread


# ** TODO min implement


* TODO implement event sourcing

TODO add event sourcing extension

TODO remove events, define them in each action protocols

TODO remove output data

# TODO on->backwardHandleFunc can be ?(use undo for default implement)

TODO on: add priority


TODO remove parent




# ** TODO update current extensions, contributes



TODO action add init to on


TODO update entry extension


TODO run test: add a cube(only scene view)
  publish all

TODO need publish:
# meta3d-event
# meta3d-editor-webgl1-three-run-engine-sceneview


TODO more:
run/stop->restore
  three:
    restore add a cube(not clean)

  # fix: refresh gameview 
  fix: add two cubes
TODO need publish:
stop
run
add

dispose a cube
  three: fix scenegraph scene view dispose event(use eventsourcing.on event)
    remove "scenegraph gameview->on dispose event"
export/import scene(use rescript)(add bdd test)
  # TODO reset/not reset
  not reset
TODO need publish:
export
import


//TODO fix: no export

//TODO fix: run,stop: should stop



TODO run test: debug
  //TODO fix import/export event
  TODO run test: debug with import not empty

TODO run test: debug for app
  TODO fix: not show


TODO need publish:
# meta3d-editor-webgl1-three-run-engine-sceneview



publish
  engine not use event sourcing

  TODO run test


TODO feat: add upgrade in dependency graph for package, app assemble
  # from entry
  protocol->same implement package name 
  package,extension,contribute
  package: keep id

  TODO fix import

  TODO update iconBase64

  TODO pass run test
    TODO finish contribute

    # TODO finish ap assemble

    # TODO change databse?

    TODO run test multiple packages, extensions, contributes -> publish app
      # TODO fix: stored in app package should upgrade


  TODO fix: should refresh dependency after upgrade
     
  TODO add bdd test


  # TODO fix: create old version, new disappear?


# TODO feat: add select all in package,ap assemble





TODO feat: finish publish



TODO refactor: remove debugger


# TODO fix: should always loop scene view and game view together


# TODO refactor: empty inputData should be null?


# ** TODO perf: can skip events in frames that all are pipeline job event(no other event(e.g. action event)) when update view(e.g. import event data)





# * TODO future: platform use event sourcing

# * TODO refactor: remove api



# * TODO refactor: protocol's dependents should add to check

# TODO add to package.json->dependents

# TODO check in DependencyGraph



# * TODO fix: import: should import element contribute

# * TODO feat: overwrite app


* TODO publish


* TODO write blog: 《Web3D编辑器实现事件溯源》

multi edit demo