Page 1 of 1

Templates

Posted: 17 Feb 2018, 02:31
by Lobby
A common issue in writing plugins is code duplication as you use the same code over and over again to define similar things. A solution to this problem are templates.

Let's say your code (simplified) looks something like this :json

Code: Select all

[
  {
    "id":"$myid00",
    "type":"something",
    "author":"anyone",
    "A":1,
    "B":2,
    "C":[1,2,3,4]
  },
  {
    "id":"$myid01",
    "type":"something",
    "author":"anyone",
    "A":1,
    "B":2,
    "C":[1,2,3,4],
    "D":"Test"  // Additional attribute
  },
  {
    "id":"$myid02",
    "type":"something",
    "author":"anyone",
    "A":8,  // Different value for A
    "B":2,
    "C":[1,2,3,4]
  }
]
As you might notice there's some duplication here. Templates can help to extract common definitions into a single object. Here that would look like :json

Code: Select all

[
  {
    "id":"$mytemplate00",
    "type":"template",
    "author":"anyone",
    "A":1,
    "B":2,
    "C":[1,2,3,4]
   },//<<--was missing
  {
    "id":"$myid00",
    "type":"something",
    "template":"$mytemplate00"  // Reference to template, no author, A, B, C needed here anymore
  },
  {
    "id":"$myid01",
    "type":"something",
    "template":"$mytemplate00"  // Reference to template
    "D":"Test"  // Additional attribute can still be applied
  },
  {
    "id":"$myid02",
    "type":"something",
    "template":"$mytemplate00"  // Reference to template
    "A":8  // Override value of A
  }
]
So templates are of type "template"

Code: Select all

"type":"template"
and can predefine anything that can be defined in plugin objects (except id and type for obvious reasons). To use a template just add

Code: Select all

"template":"$templateid"
to your using objects. As usual, order matters. So in order to use a template you have to ensure that it is already defined. You can overwrite definitions provided by a template by just redefining it. Templates can reference to other templates. Any object can only reference to one template at max.

For convenience it can be useful to inherit from multiple templates, you can do so by providing an array of template ids:

Code: Select all

"template":["$templateid0", "$templateid1", ...]

Re: Templates

Posted: 17 Feb 2018, 03:49
by cesareborgia94
Hello @Lobby,

I have difficulty understanding in how templates can be used in plugins. The only thing I understand is that templates can simplify code duplication. The only thing I do not understand is when to use templates in writing codes, or how to apply templates in plugin making?

Can you show an example in graphics, so that we could understand the uses of templates in plugin creation?

Re: Templates

Posted: 17 Feb 2018, 20:21
by Lobby
I added it to make bus code easier to read. Here's how the code for a single bus would look like without templates :json

Code: Select all

{
  "id":"$bus00",
  "type":"car",
  "frames":[{"x":0,"y":0,"w":10,"h":8,"count":4,"offset x":1024,"offset y":3328}],
  "overlay frames":[{"x":0,"y":0,"w":10,"h":8,"count":4,"offset x":1112,"offset y":3328}],
  "v2":[4,1,3,-1],
  "auto colorize":true,            // These attributes will be needed by any bus
  "flag normal":false,             //
  "flag bus":true,                 //
  "meta":{"tags":{"idle bus":{}}}  //
}
This code wouldn't be an issue if you have just a few busses, but here 9 different bus types are needed, so templates were introduced. The template :json

Code: Select all

{
  "id":"$template_bus00",
  "type":"template",
  "auto colorize":true,
  "flag normal":false,
  "flag bus":true,
  "meta":{"tags":{"idle bus":{}}}
},
The code that's now needed for each bus :json

Code: Select all

{
  "id":"$bus00",
  "type":"car",
  "template":"$template_bus00",
  "frames":[{"x":0,"y":0,"w":10,"h":8,"count":4,"offset x":1024,"offset y":3328}],
  "overlay frames":[{"x":0,"y":0,"w":10,"h":8,"count":4,"offset x":1112,"offset y":3328}],
  "v2":[4,1,3,-1]
},
I don't have an example for graphics, but let's assume you need the same frames for multiple buildings, you could then just define this in a template.

Re: Templates

Posted: 17 Feb 2018, 20:30
by CommanderABab
May the template include a reference to a predefined animation?

Re: Templates

Posted: 17 Feb 2018, 21:06
by Lobby
Sure, templates don't really know their content, it will just be copy'n'pasted into plugins that reference to the template.

Re: Templates

Posted: 05 Jun 2020, 03:11
by ian`
Hey, i want to ask.

Can 2 animations be combined with a template? so I want to make 1 basic animation and 1 additional animation so that I can save on using frames. I want to combine 1 basic animation with 3-4 additional animations, so that it becomes 4 plugin frames.

*edited
Fyi, 1 basic animation is contains 20+ frame animations and 1 additional animation is contains 2-4 frame animations.

Re: Templates

Posted: 05 Jun 2020, 09:25
by Lobby
I'm afraid you cannot, templates don't merge arrays (and animations are defined in arrays).

Re: Templates

Posted: 05 Jun 2020, 11:01
by ian`
Alright, I will merge into one template. I think with Lua, that can merge arrays, but I amnot an expert on using Lua. :bt

Re: Templates

Posted: 06 Jun 2020, 02:05
by Bearbear76
distian wrote:
05 Jun 2020, 11:01
Alright, I will merge into one template. I think with Lua, that can merge arrays, but I amnot an expert on using Lua. :bt
Yep you can merge tables (arrays) in Lua.

Re: Templates

Posted: 06 Jun 2020, 05:40
by ian`
Ølsken wrote:
06 Jun 2020, 02:05
distian wrote:
05 Jun 2020, 11:01
Alright, I will merge into one template. I think with Lua, that can merge arrays, but I amnot an expert on using Lua. :bt
Yep you can merge tables (arrays) in Lua.
But i don't understand how to convert/export lua arrays to json. What is that use print(tostring("animation") ?

Re: Templates

Posted: 06 Jun 2020, 08:35
by Bearbear76
If you have a Lua table that you want to convert to json you would use Runtime.toJson().
But that's probably not what you want to do.
If I understand correctly you want to add animations to a base animation (merge).
The best I could do is a function that would take 2 json arrays and merge the frames into a new json array

Code: Select all

{
	//new animation with merged frames
	"id": "$new_animation",
	"type": "animation",
	"frames": [{"bmp": "image.png", "count": 12}] //creates 12 slots to override
}


basically the count would represent the amount of frames for the combined frame.
For example if you have a base animation with 20 frames and an additional animation that has 5 frames you would need to set 25 frames.

Code: Select all

"frames": [{"bmp": "image.png", "count": 25}]
Then using the Draft.setFrame() twice, first to override 20 frames from the base animation then
override the remaining 5 frames to the additional frames.

Lua:

Code: Select all

--- merge 2 json arrays
-- function to merge frames from 2 json arrays and put inside another json array
-- @param json array with base animations
-- @param json array with additional animations
-- @param json array to merge animations into
local function add_frames(base, new_frames, product)
  local base_count = 0
  for i = 1, base:getFrameCount() do 
    product:setFrame(i, base:getFrame(i))
    base_count = base_count + 1
  end
  for i = 1, new_frames:getFrameCount() do
    product:setFrame(base_count + i, new_frames:getFrame(i))
  end
end
The downside to this is that you have to declare how many frames you want to use.
I tried to make one that doesn't need a predefined amount of frames but since frames use userdata I can really do nothing to edit (add frames) it.

The last method I tried is using Draft.append() but it tells me it's a nil value. I took a look at the _G table a while ago but I don't think I saw it. :?
Maybe it's not added yet?

If you are confused: I can't figure out a good way to merge 2 json arrays.

:jb: bear out!

Re: Templates

Posted: 06 Jun 2020, 13:11
by ian`
Ølsken wrote:
06 Jun 2020, 08:35
Thanks for the advice, I'll try it first. I became interested in using lua. :lua: :calc