The Object Network Types are a set of formats for common object types and their interactions and behaviours.
Since the set of types is open-ended, any implementation needs a plugin or dynamic code-loading mechanism to enable it to generate, render and enable interaction with new types.
This will have the effect of commoditising common types that may currently be locked in to proprietary applications and services, such as chat or messaging, photo sharing, and so on.
You can re-use a map or calendar for anything you're doing, instead of having a separate map and calendar for every isolated application. Similarly, you only have one AR or VR view, which can handle multiple, even quite independent AR layers, or several unbounded, connected virtual worlds. You only have one user identity instead of one for every separate application.
The types include one for laying out 2D user interface panels in 3D space and getting input from the user. Hence, while waiting for a new candidate common type to settle and need a plugin, there will always be the option of an Object Network ruleset to convert that type to and from this user interface or 'gui' type. Similarly, there are basic 3D scenegraph and mesh types, allowing higher level but still common object types (like 'leaf') to initially be defined via a rule mapping.
The main property is "is
" - which is a list of labels giving the object a
type. There may be many types "mixed in" to an object, raising expectations of (a) the
presence of certain properties (b) the presence of certain behaviours, and/or (c) the
ability to react to, or interest in observing, certain peer types.
Most fields will be defined within the type or format that an object "is", but many will
stand alone. For example, "title
" is something that will mean the same in any
format, as will "location
", and other common fields, such as "created
"
and "author
".
The semantics, if not the exact syntax, of certain fields will usually be declared in the Object Network as being defined in some other standard (e.g. events by iCalendar). Almost by definition we don't have namespacing in the Object Net Types. The whole point is to encourage discussion and agreement, not isolation.
The remainder of this page shows a number of examples, applications and patterns using the Object Network Type formats in ONF format, and using the ONR Language.
Event
An Event type carries a time period and optional location for an event. It can be used for calendar events, and can be mapped onto iCalendar:
{ UID: http://object.network/events/uid-f330a3-4011e.cyr is: attendable event title: "The Object Network Conference" content: "This year is expected to be the best yet!" start: "30 Sep 2016 09:00:00 GMT" end: " 1 Oct 2016 23:00:00 GMT" location: http://bletchleypark.org/address.cyr attendees: uid-0fe6-7d5d }An Event type may normally be just "
event
", but here it's an "attendable event
", because it's expecting RSVPs. Theattendable
type is a "mixin" that indicates the type of object this object is interested in.The "
start
" and "end
" properties map onto iCalendar's "DTSTART" and "DTEND".The "
location
" is the UID of a contact type (is: contact
). The "attendees
" property is a list of links to the contact objects of the attendees.
RSVP
Since this Event is
attendable
, you know you can reply, to be hopefully added to the list of attendees, with an RSVP type:{ UID: http://fred.info/o/uid-8a95-22bc0f7.cyr Notify: http://object.network/events/uid-f330a3-4011e.cyr is: rsvp event: http://object.network/events/uid-f330a3-4011e.cyr person: http://.. attending: yes }This RSVP is hosted on
fred.info
, notobject.network
like the event itself. It is a persistent, updatable state, that isNotify
ing itself to the event.
Language Rule
When this RSVP is received at the event, there can be a Rule type to handle it that may look like this:
{ UID: http://object.network/rules/uid-34-234-23-23.cyr is: attendable event rule when: "RSVP attending received ensure user is in attendees" Alerted: { is: rsvp event: @ attending: yes } attendees: => @. with @Alerted }The
Alerted
property is the other end ofNotify
- it's a link to the RSVP, and in the rule, you can jump right into the content to match its properties. Itsevent
property is@
, which means a link to the current object. Theattendees
property becomes (=>
) itself (@.
) but with theAlerted
link if it's not already thereHere's the rule for removing someone who is no longer attending:
{ UID: http://object.network/rules/uid-fa82-a11-003.cyr is: attendable event rule when: "RSVP not attending ensure user not in attendees" attendees: { attending: no } => # }The link to an RSVP that is no longer attending becomes nothing (
#
).The rules are attached to the event they animate by links:
{ UID: http://object.network/events/uid-f330a3-4011e.cyr is: attendable event Rules: uid-34-234-23-23 uid-fa82-a11-003 title: "The Object Network Conference" : }
Nested Event
An Event can have sub-events - for example, a conference has many talks. These are represented by the sub-objects/within pattern that is available for all types:
{ UID: uid-0112-09a9-3f54-b720 is: attendable event title: "Geek Speak December" text: "Europe's Top Tech" start: "Wed 12 Dec 2012 18:00:00 GMT" end: "Wed 12 Dec 2012 23:00:00 GMT" sub-objects: uid-3e0e-a630-b669-23d7 uid-0a01-cec7-61b7-a770 } { UID: uid-3e0e-a630-b669-23d7 is: event title: "My Love of Clojure" text: "Long ago, I fell in love with Lisp.." start: "Wed 12 Dec 2012 18:00:00 GMT" end: "Wed 12 Dec 2012 19:00:00 GMT" within: uid-0112-09a9-3f54-b720 }
Reviewable Event
An Event can be ratable and reviewable by adding
is: rateable
and a gui view:{ UID: uid-3e0e-a630-b669-23d7 is: rateable gui event title: "My Love of Clojure" text: "Long ago, I fell in love with Lisp.." start: "Wed 12 Dec 2012 18:00:00 GMT" end: "Wed 12 Dec 2012 19:00:00 GMT" within: uid-0112-09a9-3f54-b720 view: { email: { input: textfield label: "Your Email:" } comments: { input: textfield label: "Comments:" } pres-style: { input: rating label: "Presentation Style:" } } }This expects an RSVP/form type back:
{ UID: uid-3e0e-a630-b669-23d7 is: rsvp form event: uid-3e0e-a630-b669-23d7 within: http://.. rating: 5 form:{ email: foo@bar.com comments: "A good show.." pres-style: 4 } }
Contact
The Contact type is based on vCard:
A minimal contact:
{ is: contact name: { given: Duncan middle: Beaumont family: Cragg } address: { locality: "Kingston-upon-Thames" region: Surrey postal-code: "KT1" country: UK } email: demo@cilux.org }A maximal contact:
{ is: contact name: { given: Duncan middle: Beaumont family: Cragg } full-name: "Mr Duncan Cragg" address: { locality: "Kingston-upon-Thames" region: Surrey postal-code: "KT1" country: UK } email: demo@cilux.org organisation: { full-name: "ThoughtWorks (UK) Ltd" web-view: http://www.thoughtworks.com More: http://forest-roa.org/567-890.json } birthday: 1964-01-01 web-view: http://duncan-cragg.org/blog/ http://twitter.com/duncancragg publications: http://rd.springer.com/export-citation/chapter/10.1007/978-1-4419-8303-9_7.json http://object.network/111-111.json http://duncan-cragg.org/blog/atom.cyr http://duncan-cragg.org/blog/ bio: "Creator of the [Object Network][http://object.network] and Object-Mash" attending: http://object.network/123-456.json http://api2.object.network/lanyrd/2013/overtheair.json employer: http://forest-roa.org/567-890.json inspirations: http://api2.object.network/dbpedia/Tim_Berners-Lee.json http://api2.object.network/dbpedia/Alan_Turing.json More: http://api2.object.network/twitter/duncancragg.json }
Land
The Land type describes a physical area on a map:
{ UID: ... is: land title: "My Holding" area: 321.123 shape: { lat: 54.106037, lon: -1.579163 } { lat: 54.106039, lon: -1.579231 } { lat: 54.106039, lon: -1.579232 } { lat: 54.106036, lon: -1.579162 } }
Article
The Article type is used for blog entries, etc. It's partly based on Atom:
{ UID: http://duncan-cragg.org/blog/post/building-object-network/atom.cyr is: article title: "Building The Object Network" published: 2014-01-27T11:36:00Z updated: 2014-01-27T11:36:00Z web-view: http://duncan-cragg.org/blog/post/building-object-network/ within: http://duncan-cragg.org/blog/atom.cyr tags: architecture declarative forest netmash cyrus object-network IoT text: "I've started another blog called [Building The Object Network][http://object-network.blogspot.co.uk/], about how I'm experimenting with Augmented Reality for the Internet of Things using the Object Network approach.", "So far I've been [blogging][http://object-network.blogspot.co.uk/2014/01/the-internet-of-3d-sensors-and-actuators.html] [every][http://object-network.blogspot.co.uk/2014/01/augmented-reality-and-magic.html] [day][http://object-network.blogspot.co.uk/2014/01/android-sensors-for-ar.html]." "Do subscribe! " }
Article List
The Article List type is basically a feed, again based partly on Atom:
{ UID: http://duncan-cragg.org/blog/atom.cyr is: queryable article list title: "What Not How" sub-title: "Duncan Cragg on Declarative Architectures" author: http://duncan-cragg.org/blog/777-777.json id: http://duncan-cragg.org/blog/ logo: http://duncan-cragg.org/favicon.gif icon: http://duncan-cragg.org/favicon.ico rights: "All content including photos and images by Duncan Cragg. Copyright (c) Duncan Cragg." generator: "Duncan Cragg's Django Blog" web-view: http://duncan-cragg.org/blog/ atom: http://duncan-cragg.org/blog/atom/ updated: 2014-01-27T11:36:00Z list: { is: article title: "Building The Object Network" published: 2014-01-27T11:36:00Z web-view: http://duncan-cragg.org/blog/post/building-object-network/ More: http://duncan-cragg.org/blog/post/building-object-network/atom.cyr }{ is: article title: "Cyrus in 2013" published: 2013-01-16T17:09:00Z web-view: http://duncan-cragg.org/blog/post/cyrus-2013/ More: http://duncan-cragg.org/blog/post/cyrus-2013/atom.cyr } }It has a
queryable
"mixin", indicating that you can send a query..
Query
The Query Type can be notified to a
queryable list
, in this case, the above article list:{ UID: http:// is: article query querying: http://duncan-cragg.org/blog/atom.cyr match: { published: >= 2013-01-16T17:09:00Z } }It returns another, smaller article list than the one being queried, with a link to this query ("
query
").Here is simple a rule that can run this query and return the response:
{ UID: http:// is: article list rule Alerted: { is: article query target: @ } list: maybe @Alerted:match latest-response: => { UID: new Notify: @Alerted is: article list title: "Query results" source: @ query: @Alerted list: @=list } }There are many query parameters that can be added. Here's a query that uses most of them:
{ UID: http:// is: article query querying: http://duncan-cragg.org/blog/atom.cyr match: { tags: architecture cyrus } page-size: 4 page-start: 2 order-by: { published: > } inline: true results: tracking }Setting
inline: true
brings the results inline to the list, along withMore:
links to the individual result entries. Theresults: tracking
parameter means that this response will be kept up-to-date as the matching results set changes.This could return:
{ UID: http://duncan-cragg.org/.. is: article list list: { is: article title: "Building The Object Network" published: 2014-01-27T11:36:00Z updated: 2014-01-27T11:36:00Z web-view: http://duncan-cragg.org/blog/post/building-object-network/ within: http://duncan-cragg.org/blog/atom.cyr tags: architecture declarative forest netmash cyrus object-network IoT text: "I've started another blog called [Building The Object Network][http://object-network.blogspot.co.uk/], about how I'm experimenting with Augmented Reality for the Internet of Things using the Object Network approach.", "So far I've been [blogging][http://object-network.blogspot.co.uk/2014/01/the-internet-of-3d-sensors-and-actuators.html] [every][http://object-network.blogspot.co.uk/2014/01/augmented-reality-and-magic.html] [day][http://object-network.blogspot.co.uk/2014/01/android-sensors-for-ar.html]." "Do subscribe! " More: http://duncan-cragg.org/blog/post/building-object-network/atom.cyr }{ is: article title: "Cyrus in 2013" published: 2013-01-16T17:09:00Z web-view: http://duncan-cragg.org/blog/post/cyrus-2013/ : More: http://duncan-cragg.org/blog/post/cyrus-2013/atom.cyr } }
GUI
The GUI type is a 2D layout with form elements can be defined as follows:
{ UID: .. is: gui title: "Page Title" view: { logo: http://.. text: ".." xxx: { input: button label: "Push me" } yyy: { input: chooser label: "xxx:" range: { a: "A a" b: "B b" c: "C c" } } zzz: { input: textfield label: ".." } mmm: { input: checkbox label: ".." } mmm: { input: rating label: ".." } } }
Form
The Form type is sent back to the GUI object - when a client sees and renders a GUI with form elements then if there are input elements it can allow the user to create a form object:
{ UID: http:// is: form gui: http://... user: http://... form: { pushed: xxx yyy: b } }
Calculator example
Here is a simple calculator using the gui/form types:
{ UID: uid-7356-dfcc-2173-4525 is: editable gui title: Calculator local: { acc: 0 num: 0 op: + } Rules: { is: gui rule Alerted: { is: form } local: { key: => @Alerted:form:pushed } } { is: gui rule local: { key: /[0-9]/ num: => join (@. @local:key) } } { is: gui rule local: { key: dp num: => if (not @. contains .) then (join (@. .)) else @. } } { is: gui rule local: { key: cl num: => 0 }} { is: gui rule local: { key: /pl|mi|ti|di|eq/ acc: => if (@local:num set) then (@. @local:op @local:num) else @. op: => { pl: + mi: - ti: × di: ÷ eq: + } select @local:key num: => # } } { is: gui rule local: { key: cs num: # acc: => @. × -1 } } { is: gui rule local: { key: cs num: * => @. × -1 } } { is: gui rule local: { key: ms mem: => if (@local:num set) then @local:num else @local:acc } } { is: gui rule local: { key: mr num: => if (@local:mem set) then @local:mem else @. } } { is: gui rule local: { key: * => # } view: { result: { value: => if (@local:num set) then @local:num else @local:acc }}} view: { result: { is: style direction: horizontal } { input: textfield value: 0 } buttons: { style: { is: style direction: horizontal } 7: { input: button label: 7 } 8: { input: button label: 8 } 9: { input: button label: 9 } ti: { input: button label: × } cs: { input: button label: +/- } } { style: { is: style direction: horizontal } 4: { input: button label: 4 } 5: { input: button label: 5 } 6: { input: button label: 6 } di: { input: button label: ÷ } ms: { input: button label: MS } } { style: { is: style direction: horizontal } 1: { input: button label: 1 } 2: { input: button label: 2 } 3: { input: button label: 3 } pl: { input: button label: + } mr: { input: button label: MR } } { style: { is: style direction: horizontal } 0: { input: button label: 0 } dp: { input: button label: . } cl: { input: button label: C } mi: { input: button label: - } eq: { input: button label: = } } } }
Supplier
The Supplier type lists offerings (products, services, etc.) and links to outstanding order or application trackers of those offerings:
{ UID: http://coffee-shop.com/baristas is: coffee shop supplier products: { title: "Espresso" More: /prod/esp1 } { title: "Cappuccino" More: /prod/cap2 } trackers: http://coffee-shop.com/track111 http://coffee-shop.com/track110 http://coffee-shop.com/track109 }The trackers list may be kept in a separate list object. Lists of services are tagged
services
instead ofproducts
.
Product/Service
The Product type is linked to by a supplier and describes the products on offer:
{ UID: http://coffee-shop.com/prod/esp1 is: coffee product gui supplier: http://coffee-shop.com/baristas title: "Espresso" description: "A shot of pure coffee" view: { shots: { input: textfield label: "Shots" range: 1 .. 5 } ristretto: { input: checkbox label: "Ristretto" } } price-text: "£1.50 single £2.50 double" }Being also a GUI type means it has a customisation gui allowing various fields to be added to the order.
There is also an equivalent
service
type, which is basically the same.
Order/Application
The Order type lists products requested from a supplier:
{ UID: http://my-orders.com/ordr321 is: coffee order products: { product: http:/coffee-shop.com/prod/esp1 quantity: 1 shots: 2 ristretto: false } { product: http:/coffee-shop.com/prod/cap2 quantity: 3 shots: 1 } supplier: http://coffee-shop.com/baristas tracker: http://coffee-shop.com/track111 payment: http://my-orders.com/paym432 }An order can have a list of product line items with link to product and quantity. The GUI form values are sent alongside the product link to which they refer.
There is also an equivalent
application
type, which is basically the same, but is used for requests for services or products where there is an assessment or eligibility aspect to supply of that service. It may have aservices
link instead ofproducts
, and hasassessment
instead oftracker
.An order may have invoice and delivery addresses as well as a general contact, which are links to contact objects:
{ UID: http://my-orders.com/ordr5422 is: book order products: { product: /prod/book498239872 quantity: 1 } supplier: http://book-shop.com/ tracker: http://book-shop.com/track1a40 contact: http://my-orders.com/addr4332424 invoice: http://my-orders.com/addr4332424 delivery: http://my-orders.com/addr4332424 }
OrderTracker/Assessment
The OrderTracker type is owned by the supplier and tracks fulfilment of an order:
{ UID: http://coffee-shop.com/track111 is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 1 ristretto: false } price: "£1.50" status: waiting { coffee: running milk: frothing } priority-order }The
status
property may be complex: it may be a list of strings and/or sub-objects.There is also an equivalent
assessment
type, which is used to evaluate and trackapplications
rather thanorders
. It has a link toapplication
instead oforder
, and may have aservices
link instead ofproducts
:{ UID: http://barista-training.com/assess123123 is: barista assessment application: http://barista-joe.com/application-to-pret contact: http://barista-joe.com/contact-card documents: http://visas.gov.uk/right-to-work/a7b3300.json http://barista-joe.com/CV.html services: { service: /barista-training/course32132 grade: master } price: "£150" status: { ristretto-quality: pass frothy-ferns: 3.5 cleaning-up: under-evaluation } }Here, the contact link has been copied over from the application, but it can be found indirectly through the cached application link. There is also a link for supporting documentation that may be needed for an assessement.
Coffee Shop Example
There is a tradition in the distributed systems or integration community to use the example of ordering coffee to demonstrate your asynchronous system integration or distribution model.
It started with Gregor Hohpe's article about asynchronous messaging, then was continued by Jim Webber as "RESTbucks" to discuss his REST interpretation in an open forum and subsequently used to describe a refined version of the approach in the book by Jim and Ian Robinson.
Here's the Object Network version. It's based on the Foreign Exchange ordering example I used in my FOREST paper, which in turn was actually a coffee ordering scenario in its first drafts.
------------------------------------------------- { UID: http://coffee-shop.com/baristas is: coffee shop supplier products: { title: "Espresso" More: /prod/esp1 } { title: "Cappuccino" More: /prod/cap2 } trackers: http://coffee-shop.com/track110 http://coffee-shop.com/track109 } ------------------------------------------------- { UID: http://coffee-shop.com/prod/esp1 is: coffee product gui supplier: http://coffee-shop.com/baristas title: "Espresso" description: "A shot of pure coffee" view: { shots: { input: textfield label: "Shots" range: 1 .. 5 } ristretto: { input: checkbox label: "Ristretto" } } price-text: "£1.50 single £2.50 double" } ------------------------------------------------- { UID: http://my-orders.com/ordr321 Notify: http://coffee-shop.com/baristas is: coffee order products: { product: http://coffee-shop.com/prod/esp1 quantity: 1 shots: 1 ristretto: false } supplier: http://coffee-shop.com/baristas } { is: coffee shop supplier rule Alerted: { is: coffee order supplier: @ } trackers: not { order: @Alerted } => @. with { UID: new Notify: @Alerted is: coffee order-tracker order: @Alerted products: @Alerted:products price: .. status: waiting } } ------------------------------------------------- { is: coffee shop supplier products: { title: "Espresso" More: /prod/esp1 } { title: "Cappuccino" More: /prod/cap2 } trackers: http://coffee-shop.com/track111 http://coffee-shop.com/track110 http://coffee-shop.com/track109 } { UID: http://coffee-shop.com/track111 Notify: http://my-orders.com/ordr321 is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 1 ristretto: false } price: "£1.50" status: waiting } ------------------------------------------------- { UID: http://my-orders.com/ordr321 Notify: http://coffee-shop.com/track111 is: coffee order products: { product: http://coffee-shop.com/prod/esp1 quantity: 1 shots: 2 ristretto: false } supplier: http://coffee-shop.com/baristas tracker: http://coffee-shop.com/track111 } { is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 2 ristretto: false } price: "£2.50" status: waiting } ------------------------------------------------- { is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 2 ristretto: false } price: "£2.50" status: filled } ------------------------------------------------- { is: coffee order products: { product: http://coffee-shop.com/prod/cap2 quantity: 1 shots: 2 } supplier: http://coffee-shop.com/baristas tracker: http://coffee-shop.com/track111 } { is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 2 ristretto: false } price: "£2.50" status: filled not-as-ordered } ------------------------------------------------- { is: coffee order products: cancelled supplier: http://coffee-shop.com/baristas tracker: http://coffee-shop.com/track111 } { is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 2 ristretto: false } price: "£0.00" status: cancelled } ------------------------------------------------- { is: coffee order products: { product: http://coffee-shop.com/prod/esp1 quantity: 1 shots: 2 ristretto: false } supplier: http://coffee-shop.com/baristas tracker: http://coffee-shop.com/track111 } { is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 2 ristretto: false } price: "£2.50" status: filled } ------------------------------------------------- { is: coffee order products: { product: http://coffee-shop.com/prod/esp1 quantity: 1 shots: 2 ristretto: false } supplier: http://coffee-shop.com/baristas tracker: http://coffee-shop.com/track111 payment: http://my-orders.com/paym432 } ------------------------------------------------- { UID: http://my-orders.com/paym432 is: payment invoice: http://coffee-shop.com/track111 order: http://my-orders.com/ordr321 amount: £2.50 account: { .. } } ------------------------------------------------- { is: coffee order-tracker order: http://my-orders.com/ordr321 products: { product: /prod/esp1 quantity: 1 shots: 2 ristretto: false } price: "£2.50" status: paid payment: http://my-orders.com/paym432 } -------------------------------------------------
3D Objects
3D Object type :
{ UID: http://../uid-7794-3aa8-2192-7a60 is: 3d mesh title: Avatar rotation: 0 45 0 scale: 1 1 1 vertices: ( 1 0 0 ) ( 1 0 1 ) ( 0 0 1 ) ( 0 0 0 ) ( 1 1 0 ) ( 1 1 1 ) ( 0 1 1 ) ( 0 1 0 ) texturepoints: ( 0.0 0.0 ) ( 1.0 0.0 ) ( 1.0 1.0 ) ( 0.0 1.0 ) normals: ( -1.0 0.0 0.0 ) ( 1.0 0.0 0.0 ) ( 0.0 -1.0 0.0 ) ( 0.0 1.0 0.0 ) ( 0.0 0.0 -1.0 ) ( 0.0 0.0 1.0 ) faces: ( 5/1/5 1/2/5 4/3/5 ) ( 5/1/5 4/3/5 8/4/5 ) ( 3/1/1 7/2/1 8/3/1 ) ( 3/1/1 8/3/1 4/4/1 ) ( 2/1/6 6/2/6 3/4/6 ) ( 6/2/6 7/3/6 3/4/6 ) ( 1/1/2 5/2/2 2/4/2 ) ( 5/2/2 6/3/2 2/4/2 ) ( 5/1/4 8/2/4 6/4/4 ) ( 8/2/4 7/3/4 6/4/4 ) ( 1/1/3 2/2/3 3/3/3 ) ( 1/1/3 3/3/3 4/4/3 ) textures: http://fc08.deviantart.net/fs51/i/2009/284/5/e/IMVU_eye_texture_by_lilylisete.png vertex-shader: http://10.0.2.2:8081/o/uid-ff5d-1ef4-cfa5-5f92.json fragment-shader: http://10.0.2.2:8081/o/uid-1ff8-59e9-6dac-9b56.json }Here is how shaders are published:
{ is: 3d vertex shader string list title: "Dynamic Phong Vertex Shader" list: "uniform mat4 mvpm, mvvm;" "attribute vec4 pos;" "attribute vec2 tex;" "attribute vec3 nor;" "varying vec3 mvvp;" "varying vec2 texturePt;" "varying vec3 mvvn;" "void main(){" "texturePt = tex;" "mvvp = vec3(mvvm*pos);" "mvvn = vec3(mvvm*vec4(nor,0.0));" "gl_Position = mvpm*pos;" "}" }
User
The User Type represents the live, dynamic user that is active in a wearable device, etc:
{ UID: http:// is: user saying: " .. " within: .. position: 0.0 0.0 0.0 avatar: http:// location: { lat: 54.106037, lon: -1.579163 } contact: http:// homeusers: http:// private: { viewing: http:// editing: http:// viewas: gui links: .. links-around: history: .. contacts: .. responses: { } position: { } orientation: { } } }Users may have current status ("
saying
"), a virtual place they're "within
", a position in that place, an avatar object, a GPS location, a contact object, etc. The "homeusers
" link is to a serverside "home" to which the user's state can be pushed, since users will typically be run asymmetrically, without the ability to be directly published.The "
private
" section is all content that won't be pushed or published either because it's private data or because it's changing too fast and is too low-level for public use - it should be stripped off and kept only inside the device. It includes what the user is currently viewing, how they are viewing it (as a GUI, a map or raw data), their viewing history, contacts list, orientation of the device, etc.
Internet of Things example
This is the code from my 60 Days of Things project.
{ UID: uid-41b6-5f8f-f143-b30d Class: cyrus.types.PresenceTracker is: place 3d mesh editable title: "Room of Things" sub-items: { item: uid-52e0-e5c3-0ed1-6ed3 position: 15 1 10 } scale: 20 20 20 vertices: ( 1 0 0 ) ( 1 0 1 ) ( 0 0 1 ) ( 0 0 0 ) texturepoints: ( 0 0 ) ( 5 0 ) ( 5 5 ) ( 0 5 ) normals: ( 0 1 0 ) faces: ( 2/3/1 1/2/1 4/1/1 ) ( 2/3/1 4/1/1 3/4/1 ) textures: http://www.textures123.com/free-texture/sand/sand-texture4.jpg vertex-shader: uid-ff5d-1ef4-cfa5-5f92 fragment-shader: uid-1ff8-59e9-6dac-9b56 x: 7 }This is the room object where it all happens. It has a link to the following light sensor:
{ UID: uid-52e0-e5c3-0ed1-6ed3 is: 3d cuboid editable light-sensor title: "Light Level" scale: 0.3 0.3 0.3 within: uid-41b6-5f8f-f143-b30d textures: http://www.textures123.com/free-texture/sand/sand-texture4.jpg light-level: 100 }There is a light on another server that links to the room/place object it is within:
{ Rules: http://netmash.net/o/uid-16bd-140a-8862-41cd.cyr http://netmash.net/o/uid-6f1a-4c7c-d111-2679.cyr http://netmash.net/o/uid-9011-94df-9feb-e3c2.cyr http://netmash.net/o/uid-2f18-945a-c460-9bd7.cyr is: 3d cuboid editable title: Light rotation: 45 45 45 scale: 1 1 1 light: 1 1 1 position: 0 0 0 within: http://10.0.2.2:8081/o/uid-41b6-5f8f-f143-b30d.json }It has four rules. First, how to set its colour on touch by the user:
{ UID: http://netmash.net/o/uid-16bd-140a-8862-41cd.cyr is: 3d rule when: "touched, set light colour" Alerted: { is: user touching: { item: @ } } light: => @Alerted:touching:position * 1.4 }Next, telling the room/place that it's here on start-up/discovery:
{ UID: http://netmash.net/o/uid-6f1a-4c7c-d111-2679.cyr is: 3d rule when: "starting, notify place within" Notify: => @. with @within }Getting a link to the light level sensor in the room, if any:
{ UID: http://netmash.net/o/uid-9011-94df-9feb-e3c2.cyr is: 3d rule when: "starting, get light-sensor" within: { sub-items: { item: { is: light-sensor } } } light-sensor: # => @=within:sub-items:item }And responding to the light level:
{ UID: http://netmash.net/o/uid-2f18-945a-c460-9bd7.cyr is: 3d rule when: "it gets dark, turn light on" light-sensor: { light-level: < 100 } light: => 1 1 1 }This is a sketch of how to set a light brightness according to a dimmer object:
{ UID: uid-1 Rules: uid-3 is: light colour: 1 1 0 light: 0.5.0.5 0 dimmer: http://../uid-2 } { UID: uid-2 is: dimmer setting: 0.5 } { UID: uid-3 is: light rule light: => @colour × @dimmer:setting }
Editable
The Editable type is a "mixin" type that means this object is happy to accept rules to update it:
{ UID: http://.. Version: 33 is: editable thing thing-prop: a }Here is what a typical edit rule may look like:
{ is: editable rule when: edited editable: http://.. user: http://.. : { Version: 33 } => as-is { is: editable thing thing-prop: b } }This rewrites the whole object (matching the single colon) matching version 33 to the given right-hand side. Of course, you could have a rule that rewrites just part of the target.
Contact me and/or subscribe to my blog and/or follow me on Twitter.