Difference between revisions of "Peerd.c"

From Organic Design wiki
(set the node constants from trieGetValue())
m
 
(34 intermediate revisions by 2 users not shown)
Line 1: Line 1:
// [[[[http://www.organicdesign.co.nz/peerd|peerd]]]] - nodal p2p wiki daemon
+
{{legacy}}
// This article and all its includes are licenced under LGPL
+
<source lang="c">
// GPL: [[[[http://www.gnu.org/copyleft/lesser.html]]]]
+
// http://www.organicdesign.co.nz/peerd - nodal p2p wiki daemon
// SRC: [[[[http://www.organicdesign.co.nz/nodeSpace.c]]]]
+
// Source: http://www.organicdesign.co.nz/peerd/files/C - the C language version for *ix,OSX,NT platforms
// included in [[[[http://www.organicdesign.co.nz/category:peerd/files/C|peerd]]]][[[[http://www.organicdesign.co.nz/peerd.c|/peerd.c]]]]
+
// This article and all its includes are licenced under http://www.gnu.org/copyleft/lesser.html
 +
// Compiled in Win32 by peerd.c/win32-makefile to http://www.organicdesign.co.nz/wiki/images/a/a2/Peerd.msi
 +
// Compiled in Linux and OSX by rp to peerd.deb and peerd.dmg
  
typedef int node;       // node: a type for referring to nodes
+
// Globals
typedef void (code)(); // code: a type for executing functions from pointer
+
int this = 0,parent,grandpa,port = 80;
 +
char *peer = "default";
 +
char *file = (char*)0;
  
 
// Reserved nodes used by nodal reduction process (tmp)
 
// Reserved nodes used by nodal reduction process (tmp)
// - doesn't matter that these node indexes conflict with 128 ascii nodes
+
#define nodeTRUE  1  // [[[[nodeTRUE]]]]
//   because these will not currently need anything stored in them
+
#define nodeNEXT  1  // [[[[nodeNEXT]]]]
#define nodeLOOP 1
+
#define nodePREV  2  // [[[[nodePREV]]]]
#define nodeTRUE 1
+
#define nodeCODE  3  // [[[[nodeCODE]]]] is a [[[[association|pseudo node-value]]]] to determine is the nodes non-nodal-data is a function-ref
#define nodeNEXT 2
+
#define nodePARENT 4  // [[[[nodePARENT]]]] updated by [[[[nodal reduction]]]], the node for which thsi is the [[[[focus]]]]
#define nodePREV 3
+
#define nodeTRIE  5  // [[[[nodeTRIE]]]] use a different root for trie/hash so it can't interfere with serialisation of nodal-root
#define nodeCODE 4
+
#define nodeFIRST  6  // [[[[nodeFIRST]]]]
 +
#define nodeLAST  7  // [[[[nodeLAST]]]]
 +
#define nodeMAKE  8  // [[[[nodeMAKE]]]]
 +
#define nodeINIT  9  // [[[[nodeINIT]]]]
 +
#define nodeMAIN  10 // [[[[nodeMAIN]]]]
 +
#define nodeEXIT  11 // [[[[nodeEXIT]]]]
  
// Runtime nodes
 
node this;              // this: the current node, like cwd
 
  
// stateless
+
#include <unistd.h>
node nodeINTERFACE;
+
#include <stdlib.h>
node nodeSTREAMS;
+
#include <stdio.h>
 +
#include <string.h>
 +
#include <errno.h>
 +
#include <math.h>
 +
#include <stdarg.h>
 +
#include <time.h>
 +
#include <regex.h>
 +
#include "util.h"          // [[[[util.c]]]]: General utils, file,log,string etc
  
// function ref
+
// List & Node Space
node nodeEVENTS;
+
#include "listSpace.h"      // [[[[listSpace.c]]]]: listSpace and some C-specific extras: hash, trie, linked-list
node nodeIO;
+
#include "nodeSpace.h"      // [[[[nodeSpace.c]]]]: NodeSpace function declarations and initialisation
node nodeSERVER;
+
#include "serialise.h"      // [[[[serialise.c]]]]: Nodal-to-text and visa-versa
node nodeDESKTOP;
 
  
// pointer to struct
+
// Interface related
node nodeSTREAM;
+
#include "SDL.h"
node nodeWINDOW;
+
#include "SDL_image.h"
 +
#include "SDL_ttf.h"
 +
//#include "SDL_opengl.h"    // OpenGL example [[[[http://www.libsdl.org/cgi/docwiki.cgi/OpenGL_20Full_20Example|here]]]]
 +
#include "interface.h"      // [[[[interface.c]]]]: Layer model, video, audio, input, OpenGL
  
 +
// Peer daemon setup
 +
#if __WIN32__
 +
#include "servicate.h"      // [[[[servicate.c]]]]
 +
#elif __APPLE__
 +
#include "launchd.h"        // [[[[launchd.c]]]]
 +
#elif __unix__
 +
#include "daemonise.h"      // [[[[daemonise.c]]]]
 +
#endif
  
// Prototypes
+
// [[[[Communications]]]] related
node nodeTraverse(node subject,node key);
+
#if __WIN32__
node nodeGetValue(node subject,node key);
+
#include <winsock.h>
node nodeSetValue(node subject,node key,node value);
+
#else
node nodeInsertKey(node subject,node key);
+
#include <sys/socket.h>    // see [[[[http://www.opengroup.org/onlinepubs/009695399/functions/select.html|select()]]]]
node nodeRemoveKey(node subject,node key);
+
#include <sys/select.h>
node nodeLoopInsert(node subject,node insert);
+
#include <netinet/in.h>
node nodeLoopRemove(node subject);
+
#include <sys/time.h>      // for select() related stuff
void **nodeGetState(node subject,node key);
+
#include <fcntl.h>          // O_RDWR, O_NONBLOCK, F_GETFL, F_SETFL
int nodeInit();
+
#include <netdb.h>          // for [[[[http://www.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html|hostent struct]]]]
void nodeExit();
+
#endif
void nodeReduce();
+
#include "io.h"            // [[[[io.c]]]]: Main server and stream setup and functions
  
 +
int main(int argc, char **argv) {
  
// ----------------------------------------------------------------------------------------- //
+
logAdd("");            // Blank line in log to separate peerd sessions
// nodeSpace.c
+
peerdInit();            // Set up as a daemon or service
 +
listInit();            // Initialise list-space and hash/trie functions
 +
nodeInit();            // Set up initial nodal structure for reduction loop
 +
args(argc,argv);        // Handle command-line args and globals like peer and port
 +
ifInit();              // Initialise interface aspects (video, audio, input, OpenGL)
 +
ioInit();              // Set up listening socket on specified port
  
// - use array-of-node path?
+
// Main [[[[nodal reduction]]]] loop
node nodeTraverse(node subject,node key) {
+
// - maintains [[[[this]]]], [[[[parent]]]] and [[[[grandpa]]]] globals
return listTraverse((item)subject,(item)key);
+
logAdd("Handing program execution over to nodal reduction...");
}
+
while(1) nodeReduce();
 
 
// set nodal value of node/path
 
// - allows null key
 
node nodeGetValue(node subject,node key) {
 
return listGetValue(key?listTraverse((item)subject,(item)key):(item)subject);
 
}
 
 
 
node nodeSetValue(node subject,node key,node value) {
 
// todo: onChange
 
return listSetValue(key?listTraverse((item)subject,(item)key):(item)subject, (item)value);
 
}
 
 
 
// Returns a newly created node
 
node nodeInsert() {
 
return (node)listInsert();
 
}
 
 
 
// Returns newly created node
 
// - this is just traverse() but with an event raised
 
node nodeInsertKey(node subject,node key) {
 
// todo: onInstall
 
node i = nodeTraverse(subject,key);
 
return i;
 
}
 
 
 
// Returns the node that was removed
 
node nodeRemoveKey(node subject,node key) {
 
// todo: onRemove
 
node i = nodeTraverse(subject,key);
 
// todo: delete
 
return i;
 
}
 
 
 
// Returns the inserted node as the new loop pointer
 
// - this allows it to act as a stack if nodeLOOP (current-loop-node) is updated with returned node
 
// - either can be 0 on entry (for new loop and/or new node)
 
node nodeLoopInsert(node subject,node insert) {
 
if (insert == 0) insert = nodeInsert();
 
if (subject == 0) subject = insert;
 
node next = nodeGetValue(subject,nodeNEXT);
 
nodeSetValue(insert,nodeNEXT,next);
 
nodeSetValue(subject,nodeNEXT,insert);
 
nodeSetValue(insert,nodePREV,subject);
 
return nodeSetValue(next,nodePREV,insert);
 
}
 
 
 
// Returns the new loop pointer so nodeLOOP can be removed and updated
 
node nodeLoopRemove(node subject) {
 
node prev = nodeGetValue(subject,nodePREV);
 
node next = nodeGetValue(subject,nodeNEXT);
 
nodeSetValue(next,nodePREV,prev);
 
return nodeSetValue(prev,nodeNEXT,next);
 
}
 
 
 
void **nodeState(node subject,node key) {
 
return hash(itob(key?(int)listTraverse((item)subject,(item)key):(int)subject,nssBuf));
 
}
 
 
 
// Clean up all the mess and exit
 
void nodeExit() {
 
logAdd("Gracefully exiting.");
 
ifExit();
 
ioExit();
 
listExit();
 
exit(EXIT_SUCCESS);
 
}
 
 
 
 
 
// Set up initial nodal structure
 
// - todo: this structure should be read from [[[[nodeSpace.txt]]]]
 
char *serialise(node);
 
void deserialise(char*);
 
int nodeInit() {
 
 
 
char *file = "*[[0|root]]\n*[[1000|io]];[[1001|interface]];\n*[[io]]\n*[[1002|server]];[[1003|streams]];\n*[[1004|stream]]\n*[[interface]]\n*[[1005|events]];[[1006|desktop]];\n*[[1007|window]]\n";
 
 
 
/* nodeIO = nodeLoopInsert(0,0);
 
nodeINTERFACE = nodeLoopInsert(nodeIO,0);
 
nodeSERVER = nodeLoopInsert(0,0);
 
nodeSTREAMS = nodeLoopInsert(nodeSERVER,0);
 
nodeSTREAM = nodeInsert();
 
nodeEVENTS = nodeLoopInsert(0,0);
 
nodeDESKTOP = nodeLoopInsert(nodeEVENTS,0);
 
nodeWINDOW = nodeInsert();
 
nodeSetValue(0,nodeLOOP,nodeIO);
 
nodeSetValue(nodeIO,nodeLOOP,nodeSERVER);
 
nodeSetValue(nodeINTERFACE,nodeLOOP,nodeEVENTS); */
 
 
 
deserialise(file);
 
 
 
nodeIO        = trieGetValue("io"); logAdd("nodeIO = %d",nodeIO);
 
nodeINTERFACE = trieGetValue("interface"); logAdd("nodeINTERFACE = %d",nodeINTERFACE);
 
nodeSERVER    = trieGetValue("server"); logAdd("nodeSERVER = %d",nodeSERVER);
 
nodeSTREAMS  = trieGetValue("streams"); logAdd("nodeSTREAMS = %d",nodeSTREAMS);
 
nodeSTREAM    = trieGetValue("stream"); logAdd("nodeSTREAM = %d",nodeSTREAM);
 
nodeEVENTS    = trieGetValue("events"); logAdd("nodeEVENTS = %d",nodeEVENTS);
 
nodeDESKTOP  = trieGetValue("desktop"); logAdd("nodeDESKTOP = %d",nodeDESKTOP);
 
nodeWINDOW    = trieGetValue("window"); logAdd("nodeWINDOW = %d",nodeWINDOW);
 
 
 
return EXIT_SUCCESS;
 
}
 
  
// Moves "this" to current loop item if exists then rotates loop and executes or reduces the item
 
// - THEN may not be needed since by default things should stay the same
 
//  ie. a function would have to set THEN to change, so why not change loop directly itself?
 
void nodeReduce() {
 
if (this = nodeGetValue(loop = nodeTraverse(this,nodeLOOP),0)) {            // this = current loop item
 
nodeSetValue(loop,0,nodeGetValue(this,nodeNEXT));                      // Rotate loop
 
nodeGetValue(this,nodeCODE)?((code*)*nodeState(this,0))():nodeReduce(); // Exec or reduce item
 
}
 
 
}
 
}
 +
</source>
 +
[[Category:C]]

Latest revision as of 15:17, 6 July 2015

Legacy.svg Legacy: This article describes a concept that has been superseded in the course of ongoing development on the Organic Design wiki. Please do not develop this any further or base work on this concept, now this page is for historic record only.
// http://www.organicdesign.co.nz/peerd - nodal p2p wiki daemon
// Source: http://www.organicdesign.co.nz/peerd/files/C - the C language version for *ix,OSX,NT platforms
// This article and all its includes are licenced under http://www.gnu.org/copyleft/lesser.html
// Compiled in Win32 by peerd.c/win32-makefile to http://www.organicdesign.co.nz/wiki/images/a/a2/Peerd.msi
// Compiled in Linux and OSX by rp to peerd.deb and peerd.dmg

// Globals
int this = 0,parent,grandpa,port = 80;
char *peer = "default";
char *file = (char*)0;

// Reserved nodes used by nodal reduction process (tmp)
#define nodeTRUE   1  // [[[[nodeTRUE]]]]
#define nodeNEXT   1  // [[[[nodeNEXT]]]]
#define nodePREV   2  // [[[[nodePREV]]]]
#define nodeCODE   3  // [[[[nodeCODE]]]] is a [[[[association|pseudo node-value]]]] to determine is the nodes non-nodal-data is a function-ref
#define nodePARENT 4  // [[[[nodePARENT]]]] updated by [[[[nodal reduction]]]], the node for which thsi is the [[[[focus]]]]
#define nodeTRIE   5  // [[[[nodeTRIE]]]] use a different root for trie/hash so it can't interfere with serialisation of nodal-root
#define nodeFIRST  6  // [[[[nodeFIRST]]]]
#define nodeLAST   7  // [[[[nodeLAST]]]]
#define nodeMAKE   8  // [[[[nodeMAKE]]]]
#define nodeINIT   9  // [[[[nodeINIT]]]]
#define nodeMAIN   10 // [[[[nodeMAIN]]]]
#define nodeEXIT   11 // [[[[nodeEXIT]]]]


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <stdarg.h>
#include <time.h>
#include <regex.h>
#include "util.h"           // [[[[util.c]]]]: General utils, file,log,string etc

// List & Node Space
#include "listSpace.h"      // [[[[listSpace.c]]]]: listSpace and some C-specific extras: hash, trie, linked-list
#include "nodeSpace.h"      // [[[[nodeSpace.c]]]]: NodeSpace function declarations and initialisation
#include "serialise.h"      // [[[[serialise.c]]]]: Nodal-to-text and visa-versa

// Interface related
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
//#include "SDL_opengl.h"     // OpenGL example [[[[http://www.libsdl.org/cgi/docwiki.cgi/OpenGL_20Full_20Example|here]]]]
#include "interface.h"      // [[[[interface.c]]]]: Layer model, video, audio, input, OpenGL

// Peer daemon setup
#if __WIN32__
#include "servicate.h"      // [[[[servicate.c]]]]
#elif __APPLE__
#include "launchd.h"        // [[[[launchd.c]]]]
#elif __unix__
#include "daemonise.h"      // [[[[daemonise.c]]]]
#endif

// [[[[Communications]]]] related
#if __WIN32__
#include <winsock.h>
#else
#include <sys/socket.h>     // see [[[[http://www.opengroup.org/onlinepubs/009695399/functions/select.html|select()]]]]
#include <sys/select.h>
#include <netinet/in.h>
#include <sys/time.h>       // for select() related stuff
#include <fcntl.h>          // O_RDWR, O_NONBLOCK, F_GETFL, F_SETFL
#include <netdb.h>          // for [[[[http://www.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html|hostent struct]]]]
#endif
#include "io.h"             // [[[[io.c]]]]: Main server and stream setup and functions

int main(int argc, char **argv) {

	logAdd("");             // Blank line in log to separate peerd sessions
	peerdInit();            // Set up as a daemon or service
	listInit();             // Initialise list-space and hash/trie functions
	nodeInit();             // Set up initial nodal structure for reduction loop
	args(argc,argv);        // Handle command-line args and globals like peer and port
	ifInit();               // Initialise interface aspects (video, audio, input, OpenGL)
	ioInit();               // Set up listening socket on specified port

	// Main [[[[nodal reduction]]]] loop
	// - maintains [[[[this]]]], [[[[parent]]]] and [[[[grandpa]]]] globals
	logAdd("Handing program execution over to nodal reduction...");
	while(1) nodeReduce();

	}