Skip to content

lib-finBlockProgramming 库参考 ​

原文: https://finproducts.atlassian.net/wiki/spaces/JIDD3/pages/34793816316/FIN+5.3.1+lib-finBlockProgramming 中文整理基于 FIN 5.3.1

导读: FIN 块编程

以下为 API 参考,保留英文以便对照源码;目录已列出(英文标题便于检索);概述已尽量中译。


目录(导读) ​

  • lib
  • meta
  • funcs
  • def
  • addStateMachineVars(programId, names)
  • addVarIds(programId)
  • deleteMacro(macroName)
  • deleteVar(programId, variableName)
  • deleteVarById(programId, variableId)
  • finAddProjectGlobalVar(varsNames, programId)
  • finBLineSnippets()
  • finBlockSuggestion(args)
  • finBlockSuggestionHelper(args, type)
  • finBlocksCombineVars(programId, curVars)
  • finReadBlockProgram(id)
  • getAllMacros()
  • getMacroByName(macroName)
  • renameVar(programId, varName, newDisplayName)
  • renameVarById(programId, variableId, newDisplayName)
  • saveMacro(macroName, macroData)

概述(中译) ​

FIN 块编程


API 正文(英文) ​

funcs ​

addStateMachineVarsAxon function
addVarIdsAxon function
deleteMacroAxon function
deleteVarAxon function
deleteVarByIdAxon function
finAddProjectGlobalVarAxon function
finBLineSnippetsAxon function
finBlockSuggestionAxon function
finBlockSuggestionHelperAxon function
finBlocksCombineVarsAxon function
finReadBlockProgramAxon function
getAllMacrosAxon function
getMacroByNameAxon function
renameVarAxon function
renameVarByIdAxon function
saveMacroAxon function


def ​

func:addStateMachineVars ​

addStateMachineVars(programId, names) ​

Axon function


meta ​

deffunc:addStateMachineVars
isfunc
liblib:finBlockProgramming
nameaddStateMachineVars

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(programId, names) => do
  program : read(id == programId)
  vars : program->programVars.ioReadZinc
  newVars : []

  vars.each(v => do
    newVars = newVars.add(v)
  end)

  names.each(currentName => do
    v: vars.find(e => e->name == currentName)

    if(v == null) do
      newVars = newVars.add({name:currentName, kind:"Str"})
    end

  end)

  program.diff({programVars: newVars.ioWriteZinc("")}).commit()
end


def ​

func:addVarIds ​

addVarIds(programId) ​

Axon function


meta ​

deffunc:addVarIds
isfunc
liblib:finBlockProgramming
nameaddVarIds

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(programId) => do

  program : read(id == programId)
  vars : program->programVars.ioReadZinc
  newVars : vars.map((row) => if(row["varId"] != null) row else do

    newId :  "" + now()
    (0..10).each((a) => do
       newId = newId + random(0..9)
    end)

    row.set("varId", newId)
  end)

  program.diff({programVars: newVars.ioWriteZinc("")}).commit()
end


def ​

func:deleteMacro ​

deleteMacro(macroName) ​

Axon function


meta ​

deffunc:deleteMacro
isfunc
liblib:finBlockProgramming
namedeleteMacro

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(macroName) => do
  savedMacro:read(name == macroName and bLineSavedMacro)
  commit(diff(savedMacro, {}, {remove}))
end


def ​

func:deleteVar ​

deleteVar(programId, variableName) ​

Axon function


meta ​

deffunc:deleteVar
isfunc
liblib:finBlockProgramming
namedeleteVar

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(programId, variableName) => do

  program : read(id == programId)
  vars : program->programVars.ioReadZinc
  remainingVars : vars.findAll(row => row->name != variableName)

  program.diff({programVars: remainingVars.ioWriteZinc("")}).commit()

  programAfterChange : read(id == programId)
  {name: variableName, mod: programAfterChange->mod}
end


def ​

func:deleteVarById ​

deleteVarById(programId, variableId) ​

Axon function


meta ​

deffunc:deleteVarById
isfunc
liblib:finBlockProgramming
namedeleteVarById

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(programId, variableId) => do

  program : read(id == programId)
  vars : program->programVars.ioReadZinc
  remainingVars : vars.findAll(row => (row["varId"] == null or row->varId != variableId))

  program.diff({programVars: remainingVars.ioWriteZinc("")}).commit()
  variableId
end


def ​

func:finAddProjectGlobalVar ​

finAddProjectGlobalVar(varsNames, programId) ​

Axon function


meta ​

deffunc:finAddProjectGlobalVar
isfunc
liblib:finBlockProgramming
namefinAddProjectGlobalVar

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(varsNames, programId) => do

  program: readById(programId)
  curVars: program->programVars.ioReadZinc()

  varsToAdd: varsNames.map(varName => do

    if(not curVars.any(v => v["name"] == varName)) do

      globalVar: taskVarTree(programId).finGridFilter(type == "var" and shared == "<proj>" and name == varName)[0]
      newVar: { name: globalVar["name"], kind: globalVar["kind"], shared: "<proj>" }

      if(globalVar.has("unit")) do
        newVar = newVar.set("unit", globalVar->unit)
      end

      if(globalVar.has("defVal")) do
        newVar = newVar.set("defVal", globalVar->defVal)
      end

      if(globalVar.has("dis") and globalVar.dis != globalVar["name"]) do
        newVar = newVar.set("display", globalVar.dis)
      end

      return newVar
    end
  end)

  try
    program.diff({programVars: curVars.addRows(varsToAdd).ioWriteZinc("")}).commit
  catch (error) do
    finFormAlertOk(toLocale("finStackExt::regError"), toLocale("finStackMobileExt::addingVarTagsToPhrase")+" " + program.dis + " "+toLocale("finStackMobileExt::hasFailed")+".")
    throw error
  end
end


def ​

func:finBLineSnippets ​

finBLineSnippets() ​

Axon function


meta ​

deffunc:finBLineSnippets
isfunc
liblib:finBlockProgramming
namefinBLineSnippets

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  [
    {
      trigger:"code-if",
      content:"if(condition) {\n\n}"
    },
    {
      trigger:"code-if-else",
      content:"if(condition) {\n\n}\nelse {\n\n}"
    },
  ]
end


def ​

func:finBlockSuggestion ​

finBlockSuggestion(args) ​

Axon function


meta ​

deffunc:finBlockSuggestion
isfunc
liblib:finBlockProgramming
namefinBlockSuggestion

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(args) => do
  pid: try readAll(args->program->id[1..-1].parseRef.readById->programOn.parseFilter)[0]->id catch args->program->id[1..-1].parseRef
  data: "finBlocks()"
  opts: finBlocks().map(r => r.set("variable", false))
  varType: null
  comboPrompt: toLocale("finBlockProgrammingExt::chooseVarOrBlockTitle")
  variables: finBlocksCombineVars(pid, args->variables.findAll(v => (not v.has("variable") or not v->variable) or v->variable)).map(r => r.set("dis", (if (r.has("displayName")) r->displayName else r->name)))
  varBlockType: "get"
  commitAct: ""
  linkType: "data"

  searchVars: (typeList) => do
    vars: []

    typeList.each type => do
      if(type == "bool") vars = vars.addAll(variables.findAll(v=> v->type == "boolean"))
      else if(type == "str") vars = vars.addAll(variables.findAll(v=> v->type == "string"))
      else if(type == "dateTime") vars = vars.addAll(variables.findAll(v=> v->type == "datetime"))
      else vars = vars.addAll(variables.findAll(v=> v->type == type))
    end

    return vars
  end

  if(variables.find(v => v->type == "grid") != null and variables.find(v => v->name == "it") == null) variables = variables.add({dis: "it", name: "it", type: "string", variable: true, id: "new"})

  //if from an in or out socket
  if(args->startSocketType == "out" or args->startSocketType == "in") do
    opts = variables.toGrid.addRows(opts.finGridFilter(stmt and name !="comment" and name != "alarm" and name != "do" and name != "exprStmt")).map(r => r.set("socketIndex", 0))
    comboPrompt = "Choose a statement block to add:"
    varBlockType = "set"
    linkType = "exec"
  end

  //if from an output socket
  else if(args->startSocketType == "output") do
    opts = opts.findAll(v => v.has("category"))
    varBlockType = "set"
    inputType: ""
    blockList: []

    //if from a variable "get" block
    if(args->startBlockType == "get") do
      inputType = args->startVariableInfo->type

      if(inputType == "boolean") inputType = "bool"
      else if(inputType == "string") inputType = "str"
      else if(inputType == "datetime") inputType = "dateTime"

      //search for blocks whose inputs match
      opts.each block => do
        props: block->props.ioReadZinc()
        match: eachWhile(props)((v, i) => if(v.has("takes") and (v->takes.contains(inputType) or v->takes == "obj")) i)

        if(match != null) blockList = blockList.add(block.set("socketIndex", match))
      end //end search

      //add vars
      blockList = variables.findAll(v=> v->type == args->startVariableInfo->type).map(r => r.set("socketIndex", 0)).addAll(blockList)
    end //end if get

    //if non-var block
    else do
      inputType = opts.find(v => v->name == args->startBlockType).finFindMarkers.findAll(v => v != "block") // and v!= "obj"

      //search for matching blocks
      opts.each block => do
        props: block->props.ioReadZinc()
        found: false

        match: eachWhile(props)((v, i) => do
          if(v.has("takes")) do
            inputType.each x => if(v->takes.contains(x)) found = true

            if(found) i
          end
        end)

        if(match != null) blockList = blockList.add(block.set("socketIndex", match))
      end //end search

      blockList = searchVars(inputType).map(r => r.set("socketIndex", 0)).addAll(blockList)
    end //end if a non-variable block

    opts = blockList
  end //end if output

  //if from an input socket
  else if(args->startSocketType == "input") do
    opts = opts.findAll(v => v.has("category") or v->name=="alarm")
    varBlockType = "get"
    outputType: ""
    blockList: []

    //if from a variable "set" block
    if(args->startBlockType == "set") do
      outputType = args->startVariableInfo->type

      if(outputType == "boolean") outputType = "bool"
      else if(outputType == "string") outputType = "str"
      else if(outputType == "datetime") outputType = "dateTime"

      //search for blocks whose outputs match
      opts.each block => do
        markers: block.finFindMarkers()

        if(outputType == "str" and (markers.contains("str") or markers.contains("string"))) blockList = blockList.add(block.set("socketIndex", 0))
        else if(markers.contains(outputType)) blockList = blockList.add(block.set("socketIndex", 0))
      end //end search

      //add vars
      blockList = variables.findAll(v=> v->type == args->startVariableInfo->type).map(r => r.set("socketIndex", 0)).addAll(blockList)
    end //end if set

    //if non-var block
    else do
      outputType = try opts.find(v => v->name == args->startBlockType)->props.ioReadZinc()[args->startSocketIndex]->takes.trim.replace(" or ", "|").split("|") catch [] //.replace("or obj", "")

      if(outputType.isEmpty) do
        args=args.set("startBlockType","alarm")
        temp: opts.find(v => v->name == args->startBlockType)->props.ioReadZinc()
        if(args->startSocketIndex >= temp.size and temp[0]->type == "Block[]")
          outputType = try opts.find(v => v->name == args->startBlockType)->props.ioReadZinc()[0]->takes.trim.replace(" or ", "|").split("|") catch [] //.replace("or obj", "")
      end

      opts.each block => do
        blockOutputs: block.finFindMarkers.findAll(v => v != "block") // and v!= "obj"
        found: false

        outputType.each type => do
          if(type == "str" and (blockOutputs.contains("str") or blockOutputs.contains("string"))) found = true
          else if(type == "obj" and ((blockOutputs.size == 1 or outputType.size == 1) and blockOutputs.contains(type))) found = true
          else if(blockOutputs.contains(type)) found = true
        end

        if(found) blockList = blockList.add(block.set("socketIndex", 0))
      end

      blockList = searchVars(outputType).map(r => r.set("socketIndex", 0)).addAll(blockList)
    end

    opts = blockList
  end //end if input

  opts = opts.map(r => do
    if(not r.has("dis")) r = r.set("dis", r->name)
 if(r->dis.size > 0 and r->dis[0..0] == "@") r = r.set("dis", r->name)
 if(r.has("displayName") and r->displayName.size > 0 and r->displayName[0..0].contains("@")) r = r.set("displayName", r->displayName.toAxonCode)
    if(r.has("shared")) r.set("group", "Project Variables").set("icon", "wi-owm-902")
    else if(r->variable) r.set("group", "Current Variables").set("icon", "wi-moon-full")
    else
      try r.set("group", r->category.capitalize + " Blocks").set("icon", "icon-media-stop")
      catch r.set("group", "Blocks").set("icon", "icon-media-stop")
  end).toRecList

body:[
{
name:"blockCombo",
editorType: "ractive",
ractiveType: "multiselect",
prompt: comboPrompt,
data:opts,
autoClose: true,
selectedValueTags: "name, id, variable",
},

{
name:"radioGroup",
editorType:"group",
prompt:toLocale("finBlockProgrammingExt::orAddNewTitle"),
children: [
{ name:"newRad", editorType: "radio", label: toLocale("finStackExt::tag"), group: "radioGrp", selectedValue: "tag" },
{ name:"newRad", editorType: "radio", label: toLocale("finStackExt::point"), group: "radioGrp", selectedValue: "point" },
{ name:"newRad", editorType: "radio", label: toLocale("finBlockProgrammingExt::variableTitle"), group: "radioGrp", selectedValue: "var" },
{ name:"newRad", editorType: "radio", label: toLocale("finBlockProgrammingExt::absolutePointTitle"), group: "radioGrp", selectedValue: "abs" }
]
},

{ name:"cancelButton", editorType:"button", label:toLocale("finStackExt::cancel"), controlBar:true },
{ name:"commitButton", editorType:"button", label:toLocale("finStackExt::okay"), controlBar:true }
] //end body

  commitAct = "if((\$newRad).isStr or not (\$blockCombo)[0].has(\"id\")) finBlockSuggestionHelper("+args.set("blockType", varBlockType).toAxonCode+",\$newRad)"

  newBlockLinkedSocket: 0;
  newBlockType: "\$blockCombo";
  fromBlockId: "";
  toBlockId: "";

completeAction: ["var newBlock = "+newBlockType+";",
"if(\$newRad == false) {",
  "var frames = document.querySelectorAll('iframe'), app;",
  "for(var i = 0; i < frames.length; i++) {",
    "var f = frames[i];",
    "var win = f.contentWindow;",
    "if(win.app && win.app.loadProgram && win.app.addBlock) {",
      "app = win.app;",
      "break;",
    "}",
  "}",
  "if(app)",
  "{",
    "var id;",
    "const projectVarsNames = [];",
    "const menuSettings = " + blineTaskMenuSettings(args->equipRef).set("funcCall", "blineTaskMenu(" + args->equipRef.replace("\"","") + ",'" + args->program->name + "', true)").toAxonCode + ";",
    "for (prop in menuSettings) {",
        "if(typeof menuSettings[prop] == 'string') menuSettings[prop] = menuSettings[prop].replace(/\\\"/g, '');",
    "}",
    "for(let i = 0; i < newBlock.length; i++)",
    "{",
        "if(newBlock[i].variable)",
        "{",
            "if(newBlock[i].id == 'new' || newBlock[i].id === undefined)",
            "{",
                "let newVarId;",
                "if(newBlock[i].id == 'new') newVarId = app.addVariable({name: 'it', type: 'string', displayName: 'it'});",
                "else newVarId = app.addVariable({name: newBlock[i].name, type: newBlock[i].type, displayName: newBlock[i].displayName?.replace(/\\\"/g,'') });",
                "id = app.addBlock({type: '"+varBlockType+"', x: "+args->x+" + (i*50), y: "+args->y+", variableInfo: {}, owner: newVarId});",
                "if (newBlock[i].shared === '<proj>')",
                "{",
                    "projectVarsNames.push(newBlock[i].name);",
                "}",
             "}",
             "else",
             "{",
                 "id = app.addBlock({type: '"+varBlockType+"', x: "+args->x+" + (i*50), y: "+args->y+", owner: newBlock[i].id});",
             "}",
        "}",
        "else",
        "{",
            "id = app.addBlock({type: newBlock[i].name, x: "+args->x+" + (i*50), y: "+args->y+"});",
        "}",
    "}",
    "app.addLink({block: '"+args->startBlockId+"', socket:"+args->startSocketIndex+", socketType: '"+args->startSocketType+"'},",
      "{block: id, socket:newBlock[0].socketIndex},",
    "'"+linkType+"', undefined, 'linkHelper');",
    "if (projectVarsNames.length)",
    "{",
      "finstack.eval('finAddProjectGlobalVar([' + projectVarsNames.map(projVar => \"\\\"\" + projVar + \"\\\"\") + '], " + args->program->id + ")').finally(() => { ",
          "setTimeout(() => { window.top.app.ObtainMenu(null, null, 'taskData', menuSettings); }, 1000);",
      "});",
    "}",
  "}",
"}",
"if(\$newRad == 'var'){",
  "setTimeout(function(){var sel=document.querySelector('.form-container');sel.querySelector('input[type=\"radio\"]').checked=true;[{dis:languageManager[\"number\"],val:\"Number\"},{dis:languageManager[\"boolean\"],val:\"Bool\"},{dis:languageManager[\"string\"],val:\"Str\"},{dis:languageManager[\"blineDate\"],val:\"Date\"},{dis:languageManager[\"debugMenuTime\"],val:\"Time\"},{dis:languageManager[\"folioQueryDateTime\"],val:\"Date Time\"}].forEach(function(itm){var opt=document.createElement(\"option\");opt.innerHTML=itm.dis;opt.value=JSON.stringify(itm);sel.querySelector('select').appendChild(opt);});},500)",
"}"
]

{
"dis":toLocale("finBlockProgrammingExt::addPointsToProgramTitle"),
"name":"finBlineCreateProg",
"body":body.toJSON,
"width": 450,
"cancelButton": "\$cancelButton",
"commitButton":"\$commitButton",
"commitAction": commitAct,
"completeAction": completeAction.concat(),
"finForm": marker()
}.toGrid.addMeta({formExecute: marker()})
end


def ​

func:finBlockSuggestionHelper ​

finBlockSuggestionHelper(args, type) ​

Axon function


meta ​

deffunc:finBlockSuggestionHelper
isfunc
liblib:finBlockProgramming
namefinBlockSuggestionHelper

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(args, type) => do
  if(type == "tag")
    blineCreateProgramTagVars(args, type, args->program->name) //add args->name or whatever and program id
  else if(type == "point") do
    target: read(readById(parseRef(args->program->id[1..-1]))->programOn.parseFilter)->id
    blineAddPointsForm(target, parseRef(args->program->id[1..-1]), args->program->name, args)
  end else if(type == "var")
    blineCreateProgramVars(args, type, args->program->name)
  else if(type == "abs")
    blineAddAbsolutePointForm(args, type)
end


def ​

func:finBlocksCombineVars ​

finBlocksCombineVars(programId, curVars) ​

Axon function


meta ​

deffunc:finBlocksCombineVars
isfunc
liblib:finBlockProgramming
namefinBlocksCombineVars

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(programId, curVars) => do
  globalVars: taskVarTree(programId).finGridFilter(type =="var" and shared == "<proj>").removeCol("type")
    .map(r =>
      if(r->kind=="Str") r.set("kind", "string")
      else if(r->kind=="Bool") r.set("kind", "boolean")
      else r)

  globalToShow: []

  globalVars.each x => do
    if(curVars.find(v => v->name == x->name and v->type == x->kind.lower) == null)
      globalToShow = globalToShow.add(x.set("type", x->kind.lower).set("displayName", x.dis))
  end

  return curVars.addAll(globalToShow.map(r => r.set("variable", true)))
end


def ​

func:finReadBlockProgram ​

finReadBlockProgram(id) ​

Axon function


meta ​

deffunc:finReadBlockProgram
isfunc
liblib:finBlockProgramming
namefinReadBlockProgram

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(id) => do

    rec: readById(id)

    if( rec.has("programSource") ) do
        rec = rec.set("programSource", finReadBinTag(rec, "programSource"))
    end

    return rec

end


def ​

func:getAllMacros ​

getAllMacros() ​

Axon function


meta ​

deffunc:getAllMacros
isfunc
liblib:finBlockProgramming
namegetAllMacros

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

() => do
  readAll(bLineSavedMacro)
end


def ​

func:getMacroByName ​

getMacroByName(macroName) ​

Axon function


meta ​

deffunc:getMacroByName
isfunc
liblib:finBlockProgramming
namegetMacroByName

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(macroName) => do
  read(name == macroName and bLineSavedMacro)
end


def ​

func:renameVar ​

renameVar(programId, varName, newDisplayName) ​

Axon function


meta ​

deffunc:renameVar
isfunc
liblib:finBlockProgramming
namerenameVar

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

 (programId, varName, newDisplayName) => do

   program : read(id == programId)
   vars : program->programVars.ioReadZinc
newVariableName: newDisplayName.toEscapedTagName
   newVars : vars.map(row => do

       if(row->name != varName)
         row
       else
         row.set("display", newDisplayName).set("name", newVariableName)
   end)

   program.diff({programVars: newVars.ioWriteZinc("")}).commit()
   { varName: varName, newDisplayName: newDisplayName, newVariableName: newVariableName }
 end


def ​

func:renameVarById ​

renameVarById(programId, variableId, newDisplayName) ​

Axon function


meta ​

deffunc:renameVarById
isfunc
liblib:finBlockProgramming
namerenameVarById

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(programId, variableId, newDisplayName) => do

  program : read(id == programId)
  vars : program->programVars.ioReadZinc
  newVars : vars.map(row => do
      if(row["varId"] != variableId)
        row
      else
        row.set("display", newDisplayName)
  end)

  program.diff({programVars: newVars.ioWriteZinc("")}).commit()
  {varId: variableId, newName: newDisplayName}
end


def ​

func:saveMacro ​

saveMacro(macroName, macroData) ​

Axon function


meta ​

deffunc:saveMacro
isfunc
liblib:finBlockProgramming
namesaveMacro

supertypes ​

featureFeature namespace of definitions formatted as feature:name
funcAxon function

src ​

(macroName, macroData) => do
  savedMacro: readAll(bLineSavedMacro and name == macroName)

  if(savedMacro.size > 0)
    commit(diff(savedMacro[0], {data:macroData}))
  else
    commit(diff(null, {name:macroName, data:macroData, bLineSavedMacro, macro}, {add}))
end