Skip to content

Instantly share code, notes, and snippets.

@kenwebb
Last active September 23, 2024 15:26
Show Gist options
  • Save kenwebb/7d71e5fb775e139ded0b6a8e3b58f01c to your computer and use it in GitHub Desktop.
Save kenwebb/7d71e5fb775e139ded0b6a8e3b58f01c to your computer and use it in GitHub Desktop.
Digestive System
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Mon Sep 23 2024 11:25:43 GMT-0400 (Eastern Daylight Time)-->
<XholonWorkbook>
<Notes><![CDATA[
Xholon
------
Title: Digestive System
Description:
Url: http://www.primordion.com/Xholon/gwt/
InternalName: 7d71e5fb775e139ded0b6a8e3b58f01c
Keywords:
My Notes
--------
22 Sept 2024
This is intended as a stand-alone workbook that can be composed with other workbooks, for example with my existing "Homeostasis - Glucose Control" workbook.
Amongst other things, this workbook will generate Glucose.
There will be a mechanism (or mechanisms) for sharing this Glucose with other models.
For now, each model will be in a separate tab in the same browser.
Interactions will use BroadcastChannel, which I have not used before.
This workbook models the mammal/human digestive system, as described in ref[1];
Be able to send a message in JSON format, for example:
{glucose: 2}
### References
(1) my book: The Physiology Coloring Book, Wynn Kapit, Robert I. Macey, Esmail Meisami, 1987
section 67 - Organization and Function of the Digestive System
(2) search: communication between browser tabs
() https://stackoverflow.com/questions/28230845/communication-between-tabs-or-windows#28230846
Communication between tabs or windows
Asked 9 years, 7 months ago (2015)
I was searching for a way how to communicate between multiple tabs or windows in a browser (on the same domain, not CORS) without leaving traces. There were several solutions:
- using the window object
- postMessage
- cookies
- localStorage
The first is probably the worst solution - you need to open a window from your current window and then you can communicate only as long as you keep the windows open. If you reload the page in any of the windows, you most likely lose the communication.
The second approach, using postMessage, probably enables cross-origin communication, but it suffers the same problem as the first approach. You need to maintain a window object.
The third way, using cookies, store some data in the browser, which can effectively look like sending a message to all windows on the same domain, but the problem is that you can never know if all tabs read the "message" already or not before cleaning up. You have to implement some sort of timeout to read the cookie periodically. Furthermore, you are limited by the maximum cookie length, which is 4 KB.
The fourth solution, using localStorage, seemed to overcome the limitations of cookies, and it can be even listen-to using events. How to use it is described in the accepted answer.
-----
a 2023 answer:
There is a modern API dedicated for this purpose - Broadcast Channel
It is as easy as:
```
var bc = new BroadcastChannel('test_channel');
bc.postMessage('This is a test message.'); /* send */
bc.onmessage = function (ev) { console.log(ev); } /* receive */
```
Data sent to the channel is serialized using the structured clone algorithm. That means you can send a broad variety of data objects safely without having to serialize them yourself.
It is supported on all major browser, but you can find a polyfill that uses localStorage.
- KSW the answers include other useful concepts, tools
-----
() https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API
The Broadcast Channel API allows basic communication between browsing contexts (that is, windows, tabs, frames, or iframes) and workers on the same origin.
() https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel
]]></Notes>
<_-.XholonClass>
<DigestiveSystem/>
<!-- test use of BroadcastChannel -->
<BrChannelTestS superClass="Script"/> <!-- sender -->
<BrChannelTestR superClass="Script"/> <!-- receiver -->
<BrChannelGlucoseS superClass="Script"/> <!-- Glucose sender -->
<Food/>
<!-- from complex food substances to simple digestable food substances -->
<!-- proteins -->
<Protein>
<Oligopeptide/>
<Dipeptide/>
<AminoAcid/>
</Protein>
<!-- carbohydrates -->
<Carbohydrate>
<Polysaccharide>
<Starch/>
</Polysaccharide>
<Disaccharide>
<Lactose/>
<Sucrose/>
</Disaccharide>
<Monosaccharide> <!-- simple sugars -->
<Glucose/>
<Galactose/>
<Fructose/>
</Monosaccharide>
</Carbohydrate>
<!-- fats -->
<Fat>
<Triglyceride/>
<FattyAcid/>
<Glycerol/>
</Fat>
<DigestiveActivity>
<MechanicalDigestion/>
<ChemicalDigestion/>
</DigestiveActivity>
<Lumen>
<!--
the DigestiveSystem is a tube (the lumen) which is open at both ends; it's an extension of the environment
The food enters at one end,
the lining of the tube absorbs the usable substances, and
the waste products leave from the other end.
-->
</Lumen>
<DigestiveGland>
<SalivaryGland/> <!-- in the Mouth -->
</DigestiveGland>
<Mouth/>
<Saliva/>
<Throat/> <!-- pharynx -->
<Esophagus/>
<Stomach>
<!-- acts as a reservoir to receive all the food at once; delivers to the intestines in intervals -->
</Stomach>
<SmallIntestine>
<!-- the only place where the chemically digested food is absorbed -->
</SmallIntestine>
<LargeIntestine/>
<Rectum/>
<!-- other organs; outside the Lumen -->
<Liver/>
<GallBladder/>
<Pancreas/>
</_-.XholonClass>
<xholonClassDetails>
<!--<Block>
<port name="height" connector="Height"/>
</Block>-->
</xholonClassDetails>
<DigestiveSystem>
<!-- sender -->
<BrChannelTestS roleName="Sender"><![CDATA[
var me, bc, count, beh = {
postConfigure: function() {
me = this.cnode;
me.println(me.name()); //("R^^^^^"));
console.log(me.name());
count = 0;
bc = new BroadcastChannel('test_channel');
bc.postMessage(`This is test message ${count}.`);
count++;
},
act: function() {
me.println(me.name());
bc.postMessage(`This is test message ${count}.`);
count++;
}
}
//# sourceURL=BrChannelTestS.js
]]></BrChannelTestS>
<!-- receiver -->
<BrChannelTestR roleName="Receiver"><![CDATA[
var me, bc, beh = {
postConfigure: function() {
me = this.cnode;
me.println(me.name());
console.log(me.name());
bc = new BroadcastChannel('test_channel');
bc.onmessage = (event) => {
console.log(event);
me.println(event.data);
};
},
act: function() {
me.println(me.name());
}
}
//# sourceURL=BrChannelTestR.js
]]></BrChannelTestR>
<!-- Glucose sender -->
<BrChannelGlucoseS roleName="GlucoseSender"><![CDATA[
var me, bc, count, beh = {
postConfigure: function() {
me = this.cnode;
me.println(me.name()); //("R^^^^^"));
console.log(me.name());
count = 0;
bc = new BroadcastChannel('glucose_channel');
bc.postMessage(`{"Glucose": ${count}}`);
count++;
},
act: function() {
me.println(me.name());
bc.postMessage(`{"Glucose": ${count}}`); // '{"Glucose": 67}'
count++;
}
}
//# sourceURL=BrChannelGlucoseS.js
]]></BrChannelGlucoseS>
<!-- the tube from start to finish; the tube projects through all of these places -->
<Lumen>
<Mouth>
<Food amount="0"/>
</Mouth>
<Throat/>
<Esophagus/>
<Stomach/>
<SmallIntestine/>
<LargeIntestine/>
<Rectum/>
</Lumen>
</DigestiveSystem>
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Broadcast Channel - Sender</title>
<rect id="DigestiveSystem/BrChannelTestS" fill="#98FB98" height="50" width="50" x="25" y="0"/>
<g>
<title>Lumen</title>
<rect id="DigestiveSystem/Lumen" fill="#6AB06A" height="50" width="10" x="80" y="0"/>
</g>
</g>
</svg>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
</XholonWorkbook>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment