aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-01-03 00:06:41 +1000
committerDavid Walter Seikel2016-01-03 00:06:41 +1000
commitd7bc357b2d1ec596e1b7fc982d0e299db3b4135c (patch)
treec429506e16efc4df624c12086c60cc47a2e9e069
parentRejig the build, test, and kill scripts a little bit. (diff)
downloadSledjHamr-d7bc357b2d1ec596e1b7fc982d0e299db3b4135c.zip
SledjHamr-d7bc357b2d1ec596e1b7fc982d0e299db3b4135c.tar.gz
SledjHamr-d7bc357b2d1ec596e1b7fc982d0e299db3b4135c.tar.bz2
SledjHamr-d7bc357b2d1ec596e1b7fc982d0e299db3b4135c.tar.xz
Beat the server connection manegement into shape.
-rw-r--r--src/GuiLua/GuiLua.h2
-rw-r--r--src/LuaSL/LuaSL.h1
-rw-r--r--src/extantz/extantz.c181
-rw-r--r--src/extantz/extantz.h4
-rw-r--r--src/libraries/Runnr.h6
-rw-r--r--src/libraries/SledjHamr.c513
-rw-r--r--src/libraries/SledjHamr.h21
-rw-r--r--src/love/love.c577
-rw-r--r--src/purkle/purkle.c7
9 files changed, 670 insertions, 642 deletions
diff --git a/src/GuiLua/GuiLua.h b/src/GuiLua/GuiLua.h
index d82d244..0e13c84 100644
--- a/src/GuiLua/GuiLua.h
+++ b/src/GuiLua/GuiLua.h
@@ -22,7 +22,7 @@ typedef struct _GuiLua
22 winFang *us; // Our window, if it exists. 22 winFang *us; // Our window, if it exists.
23 winFang *parent; // Our parent window, if it exists. 23 winFang *parent; // Our parent window, if it exists.
24 EPhysics_World *world; // Our world, if it exists. 24 EPhysics_World *world; // Our world, if it exists.
25 Ecore_Con_Server *server; 25 Connection *server;
26 int inDel; 26 int inDel;
27 27
28 Eina_Clist node; 28 Eina_Clist node;
diff --git a/src/LuaSL/LuaSL.h b/src/LuaSL/LuaSL.h
index dba6550..d93298b 100644
--- a/src/LuaSL/LuaSL.h
+++ b/src/LuaSL/LuaSL.h
@@ -16,7 +16,6 @@ typedef struct _gameGlobals gameGlobals; // Define this here, so LuaSL_threads.h
16 16
17struct _gameGlobals 17struct _gameGlobals
18{ 18{
19 Ecore_Con_Server *server;
20 Eina_Hash *names; 19 Eina_Hash *names;
21 const char *address; 20 const char *address;
22 int port; 21 int port;
diff --git a/src/extantz/extantz.c b/src/extantz/extantz.c
index 5a7d030..49e2ebe 100644
--- a/src/extantz/extantz.c
+++ b/src/extantz/extantz.c
@@ -12,7 +12,6 @@ static void on_pixels(void *data, Evas_Object *obj);
12 12
13int logDom = -1; // Our logging domain. 13int logDom = -1; // Our logging domain.
14globals ourGlobals; 14globals ourGlobals;
15static Eina_Strbuf *serverStream;
16//static char *myKey = "12345678-1234-4321-abcd-0123456789ab"; 15//static char *myKey = "12345678-1234-4321-abcd-0123456789ab";
17//static char *myName = "onefang rejected"; 16//static char *myName = "onefang rejected";
18 17
@@ -22,8 +21,8 @@ static Eina_Bool _add(void *data, int type, Ecore_Con_Event_Server_Add *ev)
22{ 21{
23 globals *ourGlobals = data; 22 globals *ourGlobals = data;
24 23
25 PI("Connected to love server."); 24 PI("Spread the love.");
26 ourGlobals->server = ev->server; 25 ourGlobals->server = ecore_con_server_data_get(ev->server);
27 if (ourGlobals->LSLGuiMess) ourGlobals->LSLGuiMess->server = ourGlobals->server; 26 if (ourGlobals->LSLGuiMess) ourGlobals->LSLGuiMess->server = ourGlobals->server;
28 if (ourGlobals->purkle) ourGlobals->purkle->server = ourGlobals->server; 27 if (ourGlobals->purkle) ourGlobals->purkle->server = ourGlobals->server;
29 28
@@ -33,110 +32,86 @@ static Eina_Bool _add(void *data, int type, Ecore_Con_Event_Server_Add *ev)
33 return ECORE_CALLBACK_RENEW; 32 return ECORE_CALLBACK_RENEW;
34} 33}
35 34
36static Eina_Bool _data(void *data, int type, Ecore_Con_Event_Server_Data *ev) 35static Eina_Bool clientParser(void *data, Connection *connection, char *SID, char *command, char *arguments)
37{ 36{
38 globals *ourGlobals = data; 37 globals *ourGlobals = data;
39 char buf[PATH_MAX]; 38 char buf[PATH_MAX];
40 char SID[PATH_MAX];
41 const char *command;
42 char *ext;
43 39
44 eina_strbuf_append_length(serverStream, ev->data, ev->size); 40 if ((0 == strncmp(command, "llOwnerSay(", 11))
45 command = eina_strbuf_string_get(serverStream); 41 || (0 == strncmp(command, "llWhisper(", 10))
46 while ((ext = index(command, '\n'))) 42 || (0 == strncmp(command, "llSay(", 6))
43 || (0 == strncmp(command, "llShout(", 8)))
47 { 44 {
48 int length = ext - command;
49 45
50 strncpy(SID, command, length + 1); 46 sprintf(buf, "%s: %s", SID, command);
51 SID[length] = '\0'; 47 if (ourGlobals->purkle)
52 eina_strbuf_remove(serverStream, 0, length + 1);
53 ext = index(SID, '.');
54 if (ext)
55 { 48 {
56 ext[0] = '\0'; 49 int _P;
57 command = ext + 1; 50
58 if ((0 == strncmp(command, "llOwnerSay(", 11)) 51 lua_getfield(ourGlobals->purkle->L, LUA_REGISTRYINDEX, ourGlobals->purkle->name);
59 || (0 == strncmp(command, "llWhisper(", 10)) 52 _P = lua_gettop(ourGlobals->purkle->L);
60 || (0 == strncmp(command, "llSay(", 6)) 53 push_lua(ourGlobals->purkle->L, "@ ( $ )", _P, "append", buf, 0);
61 || (0 == strncmp(command, "llShout(", 8))) 54 }
62 { 55 else
63 56 PW("No purkle to put - %s", buf);
64 sprintf(buf, "%s: %s", SID, command); 57 }
65 if (ourGlobals->purkle) 58 else if (0 == strncmp(command, "llDialog(", 9))
66 { 59 {
67 int _P; 60 if (ourGlobals->LSLGuiMess)
68 61 {
69 lua_getfield(ourGlobals->purkle->L, LUA_REGISTRYINDEX, ourGlobals->purkle->name); 62 int _M;
70 _P = lua_gettop(ourGlobals->purkle->L); 63
71 push_lua(ourGlobals->purkle->L, "@ ( $ )", _P, "append", buf, 0); 64 lua_getfield(ourGlobals->LSLGuiMess->L, LUA_REGISTRYINDEX, ourGlobals->LSLGuiMess->name);
72 } 65 _M = lua_gettop(ourGlobals->LSLGuiMess->L);
73 else 66
74 PW("No purkle to put - %s", buf); 67 // TODO - Somewhere in the chain the new lines that MLP likes to put into llDialog's message munge things. Fix that.
75 } 68 push_lua(ourGlobals->LSLGuiMess->L, "@ ( $ )", _M, "doLua", command, 0);
76 else if (0 == strncmp(command, "llDialog(", 9)) 69 }
77 { 70 else
78 if (ourGlobals->LSLGuiMess) 71 PE("No LSLGuiMess to send - %s", command);
79 { 72
80 int _M; 73 }
81 74 else if (0 == strncmp(command, "loadSim(", 8))
82 lua_getfield(ourGlobals->LSLGuiMess->L, LUA_REGISTRYINDEX, ourGlobals->LSLGuiMess->name); 75 {
83 _M = lua_gettop(ourGlobals->LSLGuiMess->L);
84
85 // TODO - Somewhere in the chain the new lines that MLP likes to put into llDialog's message munge things. Fix that.
86 push_lua(ourGlobals->LSLGuiMess->L, "@ ( $ )", _M, "doLua", command, 0);
87 }
88 else
89 PE("No LSLGuiMess to send - %s", command);
90
91 }
92 else if (0 == strncmp(command, "loadSim(", 8))
93 {
94#if USE_EVAS_3D 76#if USE_EVAS_3D
95 char *p, *t; 77 char *p, *t;
96 int scenriLua; 78 int scenriLua;
97#endif 79#endif
98 80
99 // Pretend we logged in. Actually in the case of a local love server, we realy have logged in now. 81 // Pretend we logged in. Actually in the case of a local love server, we realy have logged in now.
100 strcpy(ourGlobals->uuid, SID); 82 strcpy(ourGlobals->uuid, SID);
101 PI("Your UUID is %s.", ourGlobals->uuid); 83 PI("Your UUID is %s.", ourGlobals->uuid);
102#if USE_EVAS_3D 84#if USE_EVAS_3D
103 strcpy(buf, &command[8]); 85 strcpy(buf, &command[8]);
104 p = buf; 86 p = buf;
105 while ('"' == p[0]) 87 while ('"' == p[0])
106 p++; 88 p++;
107 while ('\'' == p[0]) 89 while ('\'' == p[0])
108 p++; 90 p++;
109 t = p; 91 t = p;
110 while (('"' != p[0]) && ('\'' != p[0])) 92 while (('"' != p[0]) && ('\'' != p[0]))
111 p++; 93 p++;
112 p[0] = '\0'; 94 p[0] = '\0';
113 // TODO - For now, assume it's a file:// URL. 95 // TODO - For now, assume it's a file:// URL.
114 t += 7; 96 t += 7;
115 //strcat(t, "/index.omg"); 97 //strcat(t, "/index.omg");
116 strcpy(ourGlobals->scene->sim, t); 98 strcpy(ourGlobals->scene->sim, t);
117 PI("Loading local sim from %s", t); 99 PI("Loading local sim from %s", t);
118 100
119 // TODO - Later do the same with eet files in C code, but keep both implementations. 101 // TODO - Later do the same with eet files in C code, but keep both implementations.
120 lua_getglobal(ourGlobals->scene->L, "package"); 102 lua_getglobal(ourGlobals->scene->L, "package");
121 lua_getfield(ourGlobals->scene->L, lua_gettop(ourGlobals->scene->L), "loaded"); 103 lua_getfield(ourGlobals->scene->L, lua_gettop(ourGlobals->scene->L), "loaded");
122 lua_remove(ourGlobals->scene->L, -2); // Removes "package" 104 lua_remove(ourGlobals->scene->L, -2); // Removes "package"
123 lua_getfield(ourGlobals->scene->L, lua_gettop(ourGlobals->scene->L), "scenriLua"); 105 lua_getfield(ourGlobals->scene->L, lua_gettop(ourGlobals->scene->L), "scenriLua");
124 lua_remove(ourGlobals->scene->L, -2); // Removes "loaded" 106 lua_remove(ourGlobals->scene->L, -2); // Removes "loaded"
125 scenriLua = lua_gettop(ourGlobals->scene->L); 107 scenriLua = lua_gettop(ourGlobals->scene->L);
126 108
127 push_lua(ourGlobals->scene->L, "@ ( $ )", scenriLua, "loadSim", t, 0); 109 push_lua(ourGlobals->scene->L, "@ ( $ )", scenriLua, "loadSim", t, 0);
128 PI("Loaded local sim from %s", t); 110 PI("Loaded local sim from %s", t);
129#endif 111#endif
130 }
131 else
132 {
133 PI("Some random command %s", command);
134 }
135 }
136
137 // Get the next blob to check it.
138 command = eina_strbuf_string_get(serverStream);
139 } 112 }
113 else
114 PI("Some random command %s", command);
140 115
141 return ECORE_CALLBACK_RENEW; 116 return ECORE_CALLBACK_RENEW;
142} 117}
@@ -144,26 +119,12 @@ static Eina_Bool _data(void *data, int type, Ecore_Con_Event_Server_Data *ev)
144static Eina_Bool _del(void *data, int type, Ecore_Con_Event_Server_Del *ev) 119static Eina_Bool _del(void *data, int type, Ecore_Con_Event_Server_Del *ev)
145{ 120{
146 globals *ourGlobals = data; 121 globals *ourGlobals = data;
147 static int count = 0;
148 122
149 ourGlobals->server = NULL; 123 ourGlobals->server = NULL;
150 124
151 // Let it fail a couple of times during startup, then try to start our own love server.
152 count++;
153 if (1 < count)
154 {
155 char buf[PATH_MAX];
156
157 PW("Failed to connect to a world server, starting our own.");
158
159 // TODO - Should use Ecore_Exe for this sort of thing.
160 sprintf(buf, "%s/love &", prefix_bin_get());
161 system(buf);
162 count = 0;
163 }
164
165 if (ourGlobals->running) 125 if (ourGlobals->running)
166 return ECORE_CALLBACK_RENEW; 126 return ECORE_CALLBACK_RENEW;
127
167 return ECORE_CALLBACK_CANCEL; 128 return ECORE_CALLBACK_CANCEL;
168} 129}
169 130
@@ -710,8 +671,6 @@ EAPI_MAIN int elm_main(int argc, char **argv)
710 ephysics_world_del(ourGlobals.world); 671 ephysics_world_del(ourGlobals.world);
711 ephysics_shutdown(); 672 ephysics_shutdown();
712 673
713 if (ourGlobals.server) ecore_con_server_del(ourGlobals.server);
714
715 if (ourGlobals.win) 674 if (ourGlobals.win)
716 { 675 {
717 ecore_animator_del(ourGlobals.animator); 676 ecore_animator_del(ourGlobals.animator);
diff --git a/src/extantz/extantz.h b/src/extantz/extantz.h
index c7edc07..2eddeb6 100644
--- a/src/extantz/extantz.h
+++ b/src/extantz/extantz.h
@@ -254,8 +254,8 @@ typedef struct _globals
254 GuiLua *purkle; 254 GuiLua *purkle;
255 GuiLua *LSLGuiMess; 255 GuiLua *LSLGuiMess;
256 256
257 Ecore_Con_Server *server; 257 Connection *server;
258 char uuid[42]; 258 char uuid[42];
259 259
260} globals; 260} globals;
261 261
diff --git a/src/libraries/Runnr.h b/src/libraries/Runnr.h
index a2098d9..b44dca4 100644
--- a/src/libraries/Runnr.h
+++ b/src/libraries/Runnr.h
@@ -12,6 +12,8 @@
12#include <lualib.h> 12#include <lualib.h>
13#include <lauxlib.h> 13#include <lauxlib.h>
14 14
15#include "SledjHamr.h"
16
15// Stick with Plan C for now. 17// Stick with Plan C for now.
16// TODO - Should make this choosable at run time after more testing of Ecore_Thead. 18// TODO - Should make this choosable at run time after more testing of Ecore_Thead.
17#define THREADIT 0 19#define THREADIT 0
@@ -41,7 +43,7 @@ typedef struct _LuaCompile
41{ 43{
42 char *file, *SID, *luaName; 44 char *file, *SID, *luaName;
43 int bugCount; 45 int bugCount;
44 Ecore_Con_Client *client; 46 Connection *client;
45 compileCb parser; 47 compileCb parser;
46 compileCb cb; 48 compileCb cb;
47 boolean doConstants; 49 boolean doConstants;
@@ -69,7 +71,7 @@ typedef struct _script
69 runnrStatus status; 71 runnrStatus status;
70 RunnrServerCb send2server; 72 RunnrServerCb send2server;
71 Eina_Clist messages; 73 Eina_Clist messages;
72 Ecore_Con_Client *client; 74 Connection *client;
73 Ecore_Timer *timer; 75 Ecore_Timer *timer;
74} script; 76} script;
75 77
diff --git a/src/libraries/SledjHamr.c b/src/libraries/SledjHamr.c
index 3445e52..10eeca5 100644
--- a/src/libraries/SledjHamr.c
+++ b/src/libraries/SledjHamr.c
@@ -5,15 +5,6 @@
5#include "SledjHamr.h" 5#include "SledjHamr.h"
6 6
7 7
8struct _conct
9{
10 char *address;
11 int port;
12 void *pointer;
13 Ecore_Event_Handler_Cb addCb, dataCb, delCb;
14 Ecore_Event_Handler *add, *data, *del;
15};
16
17struct _message 8struct _message
18{ 9{
19 Eina_Clist node; 10 Eina_Clist node;
@@ -21,48 +12,6 @@ struct _message
21}; 12};
22 13
23 14
24static Eina_Bool _add(void *data, int type, Ecore_Con_Event_Server_Del *ev)
25{
26 struct _conct *this = data;
27
28 if (this->addCb)
29 this->addCb(this->pointer, type, ev);
30 if (this->dataCb)
31 ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, this->dataCb, this->pointer);
32
33 return ECORE_CALLBACK_RENEW;
34}
35
36static Eina_Bool _delTimer(void *data)
37{
38 struct _conct *this = data;
39
40 reachOut(this->address, this->port, this->pointer, this->addCb, this->dataCb, this->delCb);
41 return ECORE_CALLBACK_CANCEL;
42}
43
44static Eina_Bool _del(void *data, int type, Ecore_Con_Event_Server_Del *ev)
45{
46 struct _conct *this = data;
47
48 printf("FAILED connection to server %s:%d, trying again in a second!\n", this->address, this->port);
49 ecore_event_handler_del(this->add);
50 ecore_event_handler_del(this->del);
51
52 if (this->delCb)
53 {
54 if (ECORE_CALLBACK_RENEW == this->delCb(this->pointer, type, ev))
55 ecore_timer_add(1.0, _delTimer, this);
56 }
57
58 if (ev->server) ecore_con_server_del(ev->server);
59 // TODO - Hmm, I think this is where this should be freed, but it causes a seggie in reachOut's while loop.
60 // Which is odd, so leave it commented for now and investigate later.
61// free(this);
62
63 return ECORE_CALLBACK_CANCEL;
64}
65
66void *addMessage(Eina_Clist *list, size_t size, const char *message, ...) 15void *addMessage(Eina_Clist *list, size_t size, const char *message, ...)
67{ 16{
68 va_list args; 17 va_list args;
@@ -82,10 +31,68 @@ void *addMessage(Eina_Clist *list, size_t size, const char *message, ...)
82 return result; 31 return result;
83} 32}
84 33
85void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, ...) 34static boolean checkConnection(Connection *conn, char *func, connType wanted, boolean isLocal)
35{
36 boolean result = TRUE;
37
38 if ((conn->type != CT_CLIENT) && (conn->type != CT_SERVER))
39 {
40 result = FALSE;
41 printf("CONNECTION OBJECT in %s() is of unknown type %d\n", func, (int) conn->type);
42 }
43 else if (conn->type != wanted)
44 {
45 result = FALSE;
46 switch (wanted)
47 {
48 case CT_CLIENT :
49 if (conn->type == CT_SERVER)
50 printf("INVALID CONNECTION OBJECT in %s(), it might be a server object!\n", func);
51 else
52 printf("INVALID CONNECTION OBJECT in %s(), type is %d!\n", func, (int) conn->type);
53 if (conn->conn.client.myServer == NULL)
54 printf("CONNECTION OBJECT in %s() is a local client, but should be a remote client mirror!\n", func);
55 break;
56
57 case CT_SERVER :
58 if (conn->type == CT_CLIENT)
59 printf("INVALID CONNECTION OBJECT in %s(), it might be a client object!\n", func);
60 else
61 printf("INVALID CONNECTION OBJECT in %s(), type is %d!\n", func, (int) conn->type);
62 if (isLocal)
63 {
64 if (conn->conn.server.clients == NULL)
65 printf("CONNECTION OBJECT in %s() is a remote server mirror, but should be a local server!\n", func);
66 }
67 else
68 {
69 if (conn->conn.server.clients != NULL)
70 printf("CONNECTION OBJECT in %s() is a local server, but should be a remote server mirror!\n", func);
71 }
72 break;
73
74 default :
75 printf("CONNECTION OBJECT in %s(), silly coder asked for an unknown type!""\n", func);
76 break;
77 }
78
79 if (NULL == conn->name)
80 {
81 result = FALSE;
82 printf("CONNECTION OBJECT in %s() has no name!\n", func);
83 }
84 }
85
86//if (result) printf("%s(\"%s\")\n", func, conn->name);
87
88 return result;
89}
90
91void sendBack(Connection *conn, const char *SID, const char *message, ...)
86{ 92{
87 va_list args; 93 va_list args;
88 char buf[PATH_MAX]; 94// Ecore_Con_Client *client = conn->conn.client.client;
95 char buf[PATH_MAX * 2];
89 int length = strlen(SID); 96 int length = strlen(SID);
90 97
91 strncpy(buf, SID, length); 98 strncpy(buf, SID, length);
@@ -95,15 +102,18 @@ void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, ..
95 va_end(args); 102 va_end(args);
96 buf[length++] = '\n'; 103 buf[length++] = '\n';
97 buf[length] = '\0'; 104 buf[length] = '\0';
98// printf("sendBack(%s)", buf); 105// printf("sendBack(%s", buf);
99 ecore_con_client_send(client, buf, length); 106// ecore_con_client_send(client, buf, length);
100 ecore_con_client_flush(client); 107// ecore_con_client_flush(client);
108//Connection *conn = ecore_con_client_data_get(client);
109if (conn) send2(conn, SID, buf); else printf("sendBack() can't find Connection!\n");
101} 110}
102 111
103void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, ...) 112void sendForth(Connection *conn, const char *SID, const char *message, ...)
104{ 113{
105 va_list args; 114 va_list args;
106 char buf[PATH_MAX]; 115// Ecore_Con_Server *server = conn->conn.server.server;
116 char buf[PATH_MAX * 2];
107 int length = strlen(SID); 117 int length = strlen(SID);
108 118
109 strncpy(buf, SID, length); 119 strncpy(buf, SID, length);
@@ -113,123 +123,196 @@ void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, .
113 va_end(args); 123 va_end(args);
114 buf[length++] = '\n'; 124 buf[length++] = '\n';
115 buf[length] = '\0'; 125 buf[length] = '\0';
116// printf("sendForth(%s)", buf); 126// printf("sendForth(%s", buf);
117 ecore_con_server_send(server, buf, length); 127// ecore_con_server_send(server, buf, length);
118 ecore_con_server_flush(server); 128// ecore_con_server_flush(server);
129//Connection *conn = ecore_con_server_data_get(server);
130if (conn) send2(conn, SID, buf); else printf("sendForth() can't find Connection!\n");
119} 131}
120 132
133void send2(Connection *conn, const char *SID, const char *message, ...)
134{
135 va_list args;
136 char buf[PATH_MAX * 2];
137 int length = strlen(SID);
121 138
139length = 0;
140// strncpy(buf, SID, length);
141// buf[length++] = '.';
142 va_start(args, message);
143// length += vsprintf(&buf[length], message, args);
144 va_end(args);
145strcpy(buf, message);
146length = strlen(buf);
147// buf[length++] = '\n';
148 buf[length] = '\0';
122 149
150// TODO - Should check if this is always gonna be local? Likely not.
151 if (checkConnection(conn, "send2", conn->type, FALSE))
152 {
153 switch (conn->type)
154 {
155 case CT_CLIENT :
156// printf("vvv send2(%*s", length, buf);
157 ecore_con_client_send(conn->conn.client.client, strndup(buf, length), length);
158 ecore_con_client_flush(conn->conn.client.client);
159 break;
160
161 case CT_SERVER :
162// printf("^^^ send2(%*s", length, buf);
163 ecore_con_server_send(conn->conn.server.server, strndup(buf, length), length);
164 ecore_con_server_flush(conn->conn.server.server);
165 break;
166
167 default :
168 printf("send2() unable to send to partially bogus Connection object!\n");
169 break;
170 }
171 }
172 else
173 printf("send2() unable to send to bogus Connection object!\n");
174}
123 175
124static Eina_Bool parseStream(void *data, int type, void *evData, int evSize, void *ev) 176static Eina_Bool parseStream(void *data, int type, void *evData, int evSize, void *ev)
125{ 177{
126 Connection *connection = data; 178 Connection *conn = data;
127 char SID[PATH_MAX]; 179 char SID[PATH_MAX];
128 const char *command; 180 const char *command;
129 char *ext; 181 char *ext;
130 182
131 if (NULL == connection->stream) 183//printf("parseStream(%s, \"%*s\")\n", conn->name, evSize, (char *) evData);
132 connection->stream = eina_strbuf_new(); 184 if (NULL == conn->stream)
185 conn->stream = eina_strbuf_new();
133 186
134 eina_strbuf_append_length(connection->stream, evData, evSize); 187 eina_strbuf_append_length(conn->stream, evData, evSize);
135 command = eina_strbuf_string_get(connection->stream); 188 command = eina_strbuf_string_get(conn->stream);
136 while ((ext = index(command, '\n'))) 189 while ((ext = index(command, '\n')))
137 { 190 {
138 int length = ext - command; 191 int length = ext - command;
139 192
140 strncpy(SID, command, length + 1); 193 strncpy(SID, command, length + 1);
141 SID[length] = '\0'; 194 SID[length] = '\0';
142 eina_strbuf_remove(connection->stream, 0, length + 1); 195 eina_strbuf_remove(conn->stream, 0, length + 1);
143 ext = index(SID, '.'); 196 ext = index(SID, '.');
144 if (ext) 197 if (ext)
145 { 198 {
146 ext[0] = '\0'; 199 ext[0] = '\0';
147 command = ext + 1; 200 command = ext + 1;
148 ext = index(SID, '('); 201 ext = index(command, '(');
149 if (ext) 202 if (ext)
150 { 203 {
151 streamParser func = eina_hash_find(connection->commands, command); 204 streamParser func = eina_hash_find(conn->commands, command);
152//PW("COMMAND - %s", command); 205//printf("parseStream(%s>> %s\"\n", conn->name, command);
153
154 ext[0] = '\0';
155 206
207// ext[0] = '\0';
156 // Need a callback if we can't find the command. 208 // Need a callback if we can't find the command.
157 if (NULL == func) 209 if (NULL == func)
158 func = connection->unknownCommand; 210 func = conn->unknownCommand;
159 if (func) 211 if (func)
160 func(data, connection, SID, (char *) command, ext + 1); 212 func(conn->pointer, conn, SID, (char *) command, ext + 1);
213 else
214 printf("parseStream() No function found for command %s!\n", command);
161 } 215 }
162 } 216 }
163 217
164 // Get the next blob to check it. 218 // Get the next blob to check it.
165 command = eina_strbuf_string_get(connection->stream); 219 command = eina_strbuf_string_get(conn->stream);
166 } 220 }
167 221
168 if (connection->_data) 222 if (conn->_data)
169 connection->_data(data, type, ev); 223 conn->_data(conn->pointer, type, ev);
170 224
171 return ECORE_CALLBACK_RENEW; 225 return ECORE_CALLBACK_RENEW;
172} 226}
173 227
174Eina_Bool parseClientStream(void *data, int type, Ecore_Con_Event_Client_Data *ev) 228static Eina_Bool parseClientStream(void *data, int type, Ecore_Con_Event_Client_Data *ev)
175{ 229{
176 // data is the server connection, but we want the client one. 230 Connection *conn = /*data*/ ecore_con_client_data_get(ev->client);
177 return parseStream(ecore_con_client_data_get(ev->client), type, ev->data, ev->size, ev); 231
232 if (checkConnection(conn, "parseClientStream", CT_CLIENT, FALSE))
233 return parseStream(conn, type, ev->data, ev->size, ev);
234 return ECORE_CALLBACK_RENEW;
178} 235}
179 236
180Eina_Bool parseServerStream(void *data, int type, Ecore_Con_Event_Server_Data *ev) 237static Eina_Bool parseServerStream(void *data, int type, Ecore_Con_Event_Server_Data *ev)
181{ 238{
182 return parseStream(data, type, ev->data, ev->size, ev); 239 Connection *conn = /*data*/ ecore_con_server_data_get(ev->server);
183} 240
241 if (checkConnection(conn, "parseServerStream", CT_SERVER, FALSE))
242 return parseStream(conn, type, ev->data, ev->size, ev);
184 243
244 return ECORE_CALLBACK_RENEW;
245}
185 246
186Eina_Bool clientAdd(void *data, int type, Ecore_Con_Event_Client_Add *ev) 247static Eina_Bool clientAdd(void *data, int type, Ecore_Con_Event_Client_Add *ev)
187{ 248{
188 Connection *conn, *connection = data; 249 Connection *conn, *connection = data;
189 250
251 if (checkConnection(connection, "clientAdd", CT_SERVER, TRUE))
252 {
190 ecore_con_client_timeout_set(ev->client, 0); 253 ecore_con_client_timeout_set(ev->client, 0);
191 conn = calloc(1, sizeof(Connection)); 254 conn = calloc(1, sizeof(Connection));
192 conn->type = CT_CLIENT; 255 conn->type = CT_CLIENT;
193 conn->conn.client.client = ev->client; 256 conn->conn.client.client = ev->client;
194 conn->conn.client.myServer = connection; 257 conn->conn.client.myServer = connection;
258 conn->conn.client.server = malloc(sizeof(Eina_Clist));
259 eina_clist_element_init(conn->conn.client.server);
260 eina_clist_add_tail(connection->conn.server.clients, conn->conn.client.server);
195 conn->name = strdup(connection->name); 261 conn->name = strdup(connection->name);
196 conn->address = strdup(connection->address); 262 conn->address = strdup(connection->address);
197 conn->port = connection->port; 263 conn->port = connection->port;
198 conn->pointer = connection->pointer; 264 conn->pointer = connection->pointer;
265 conn->_add = connection->_add;
266 conn->_data = connection->_data;
267 conn->_del = connection->_del;
268 conn->unknownCommand = connection->unknownCommand;
199 conn->commands = eina_hash_string_superfast_new(NULL); 269 conn->commands = eina_hash_string_superfast_new(NULL);
200 ecore_con_client_data_set(ev->client, conn); 270 ecore_con_client_data_set(ev->client, conn);
201 271
202 if (connection->_add) 272 if (connection->_add)
203 return connection->_add(connection->pointer, type, ev); 273 return connection->_add(connection->pointer, type, ev);
204 274
205 return ECORE_CALLBACK_RENEW; 275 }
276
277 return ECORE_CALLBACK_RENEW;
206} 278}
207 279
208Eina_Bool clientDel(void *data, int type, Ecore_Con_Event_Client_Del *ev) 280static Eina_Bool clientDel(void *data, int type, Ecore_Con_Event_Client_Del *ev)
209{ 281{
210 Connection *connection = data; 282 Connection *conn = data;
211 283
284 if (checkConnection(conn, "clientDel", CT_SERVER, TRUE))
285 {
212 if (ev->client) 286 if (ev->client)
213 { 287 {
214 Eina_List const *clients; 288 Eina_List const *clients;
215 289
290 if (conn->_del)
291 conn->_del(conn->pointer, type, ev);
292
293 ecore_con_client_del(ev->client);
294
295
216 // This is only really for testing, normally it just runs 24/7, or until told not to. 296 // This is only really for testing, normally it just runs 24/7, or until told not to.
217 clients = ecore_con_server_clients_get(connection->conn.server.server); 297 // The "- 1" is coz this server is still counted.
298 clients = ecore_con_server_clients_get(conn->conn.server.server) - 1;
218 if (0 == eina_list_count(clients)) 299 if (0 == eina_list_count(clients))
219 printf("No more clients, exiting."); 300 printf("No more clients for %s, exiting.\n", conn->name);
220 else 301 else
221 printf("Some %d more clients, exiting anyway.", eina_list_count(clients)); 302 printf("Some (%d) more clients for %s, exiting anyway.\n", eina_list_count(clients), conn->name);
222
223// TODO - Probably should just keep running, both servers, and go away when all clients are gone for testing.
224 303
225 if (connection->_del) 304 // TODO - the Connection free function should take care of all of this, and we should call it here. ish.
226 connection->_del(connection->pointer, type, ev); 305 eina_clist_remove(conn->conn.client.server);
306 free(conn->conn.client.server);
307 conn->conn.client.server = NULL;
227 308
228 ecore_con_client_del(ev->client); 309// TODO - Probably should just keep running, both servers, and go away when all clients are gone for testing.
229 ecore_main_loop_quit(); 310 ecore_main_loop_quit();
230 } 311 }
312 }
231 313
232 return ECORE_CALLBACK_RENEW; 314 free(conn);
315 return ECORE_CALLBACK_RENEW;
233} 316}
234 317
235Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser) 318Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser)
@@ -238,11 +321,11 @@ Connection *openArms(char *name, const char *address, int port, void *data, Ecor
238 Ecore_Con_Server *server; 321 Ecore_Con_Server *server;
239 322
240 conn->type = CT_SERVER; 323 conn->type = CT_SERVER;
241// conn->conn.server.serverCommand = ; 324 conn->conn.server.clients = malloc(sizeof(Eina_Clist));
325 eina_clist_init(conn->conn.server.clients);
242 conn->name = strdup(name); 326 conn->name = strdup(name);
243 conn->address = strdup(address); 327 conn->address = strdup(address);
244 conn->port = port; 328 conn->port = port;
245
246 conn->pointer = data; 329 conn->pointer = data;
247 conn->_add = _add; 330 conn->_add = _add;
248 conn->_data = _data; 331 conn->_data = _data;
@@ -250,21 +333,23 @@ Connection *openArms(char *name, const char *address, int port, void *data, Ecor
250 conn->unknownCommand = _parser; 333 conn->unknownCommand = _parser;
251 conn->commands = eina_hash_string_superfast_new(NULL); 334 conn->commands = eina_hash_string_superfast_new(NULL);
252 335
253 if ((server = ecore_con_server_add(ECORE_CON_REMOTE_TCP, address, port, data))) 336 conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, (Ecore_Event_Handler_Cb) clientAdd, conn);
337 conn->data = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, (Ecore_Event_Handler_Cb) parseClientStream, conn);
338 conn->del = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, (Ecore_Event_Handler_Cb) clientDel, conn);
339// conn->died = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _serverDied, conn);
340
341 if ((server = ecore_con_server_add(ECORE_CON_REMOTE_TCP, address, port, conn)))
254 { 342 {
255 conn->conn.server.server = server; 343 conn->conn.server.server = server;
256 344 ecore_con_server_timeout_set(server, 0);
257 conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, (Ecore_Event_Handler_Cb) clientAdd, conn); 345 ecore_con_server_client_limit_set(server, -1, 0);
258 conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, (Ecore_Event_Handler_Cb) parseClientStream, conn); 346// ecore_con_server_timeout_set(server, 10);
259 conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, (Ecore_Event_Handler_Cb) clientDel, conn); 347// ecore_con_server_client_limit_set(server, 3, 0);
260 ecore_con_server_timeout_set(server, 0); 348 printf("ACTUALLY created the %s server %s:%d.\n", name, address, port);
261 ecore_con_server_client_limit_set(server, -1, 0);
262 ecore_con_server_data_set(server, conn);
263// ecore_con_server_timeout_set(server, 10);
264// ecore_con_server_client_limit_set(server, 3, 0);
265 } 349 }
266 else 350 else
267 { 351 {
352 // TODO - Connection needs a generic free function. Only reason we are getting away with this is during initial testing, the Connections last the entire run anyway.
268 free(conn->address); 353 free(conn->address);
269 free(conn); 354 free(conn);
270 conn = NULL; 355 conn = NULL;
@@ -273,142 +358,154 @@ Connection *openArms(char *name, const char *address, int port, void *data, Ecor
273 return conn; 358 return conn;
274} 359}
275 360
276Eina_Bool serverAdd(void *data, int type, Ecore_Con_Event_Server_Add *ev) 361static Eina_Bool serverAdd(void *data, int type, Ecore_Con_Event_Server_Add *ev)
277{ 362{
278 Connection *connection = data; 363 Connection *conn = data;
279
280 connection->conn.server.hackyCount++;
281 364
282 // Alledgedly this checks for real conections, but given that the first time it's called, there's no real connection, this is failing somehow. 365 if (checkConnection(conn, "serverAdd", CT_SERVER, FALSE))
283 //if (ecore_con_server_connected_get(ev->server))
284 if (connection->conn.server.hackyCount <= 1)
285 printf("Bogus server ignored.");
286 else
287 { 366 {
288 printf("Connected to %s server.", connection->name); 367 conn->conn.server.hackyCount++;
289 connection->conn.server.server = ev->server; 368 conn->stage++;
290 // In case the server crashed, clear out any waiting data.
291 if (connection->stream)
292 eina_strbuf_reset(connection->stream);
293 369
294 if (connection->_add) 370 if (conn->name)
295 connection->_add(data, type, ev); 371 printf("serverAdd()^^^^^^^^^^^^^^^^^^^^^^^Connected to %s server.\n", conn->name);
372 else
373 printf("serverAdd()^^^^^^^^^^^^^^^^^^^^^^^Connected to UNKNOWN server.\n");
374
375 // In case the server crashed, clear out any waiting data.
376 if (conn->stream)
377 eina_strbuf_reset(conn->stream);
378 if (conn->_add)
379 conn->_add(conn->pointer, type, ev);
296 } 380 }
297 381
298 return ECORE_CALLBACK_RENEW; 382 return ECORE_CALLBACK_RENEW;
299} 383}
300 384
301Eina_Bool serverDel(void *data, int type, Ecore_Con_Event_Server_Del *ev) 385static Eina_Bool serverDel(void *data, int type, Ecore_Con_Event_Server_Del *ev)
302{ 386{
303 Connection *connection = data; 387 Eina_Bool result = ECORE_CALLBACK_RENEW;
388 Connection *conn = data;
304 389
305 connection->conn.server.server = NULL; 390 if (checkConnection(conn, "serverDel", CT_SERVER, FALSE))
306
307// connection->server.hackyCount--;
308 // Let it fail a couple of times during startup, then try to start our own script server.
309 connection->conn.server.count++;
310 if (1 < connection->conn.server.count)
311 { 391 {
312 char buf[PATH_MAX]; 392 conn->conn.server.server = NULL;
313 393 conn->stage = -3;
314 printf("Failed to connect to a %s server, starting our own.", connection->name); 394 if (conn->_del)
315 // TODO - Should use Ecore_Exe for this sort of thing. 395 result = conn->_del(conn->pointer, type, ev);
316 sprintf(buf, "%s/%s &", prefix_bin_get(), connection->conn.server.serverCommand);
317 system(buf);
318 connection->conn.server.count = 0;
319 // TODO - There's also the question of what to do if the connection failed.
320 // Did the server crash, or was it just the connection?
321 // Probably gonna need some smarts, for now we just restart all the scripts.
322 // Which I think gets done on server add.
323 } 396 }
324 397
325 if (connection->_del) 398 return result;
326 connection->_del(data, type, ev); 399}
327
328
329 // TODO - May want to renew even if it's not running the GUI, but then we still need some sort of "shut down" signal, which we don't need during testing.
330// if (ourGlobals->ui)
331 return ECORE_CALLBACK_RENEW;
332
333// ecore_main_loop_quit();
334
335// return ECORE_CALLBACK_CANCEL;
336
337 400
401static Eina_Bool _serverDied(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
402{
403 Connection *conn = data;
404// Ecore_Exe_Event_Data *dataFromProcess = (Ecore_Exe_Event_Data *)event;
338 405
339/* Extantz does this instead of the above returns - 406 conn->stage = -3;
407 conn->conn.server.serverHandle = NULL;
408 conn->conn.server.pid = 0;
340 409
341 if (ourGlobals->running) 410 return ECORE_CALLBACK_DONE;
342 return ECORE_CALLBACK_RENEW;
343 return ECORE_CALLBACK_CANCEL;
344*/
345} 411}
346 412
347 413// TODO - instead of a timer, try to make this event driven. Use jobs, or idler, or something.
348 414static Eina_Bool _reachOutTimer(void *data)
349#if 1
350Ecore_Con_Server *reachOut(char *address, int port, void *data, Ecore_Event_Handler_Cb _addCb, Ecore_Event_Handler_Cb _dataCb, Ecore_Event_Handler_Cb _delCb)
351{ 415{
416 Eina_Bool result = ECORE_CALLBACK_RENEW;
417 Connection *conn = data;
352 Ecore_Con_Server *server = NULL; 418 Ecore_Con_Server *server = NULL;
353 struct _conct *this = malloc(sizeof(struct _conct)); 419
354 int count = 0; 420 switch (conn->stage)
355
356 this->address = address;
357 this->port = port;
358 this->pointer = data;
359 this->addCb = _addCb;
360 this->dataCb = _dataCb;
361 this->delCb = _delCb;
362 // This loop is overkill I think.
363 while ((!server) && (10 > count))
364 { 421 {
365 if ((server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, address, port, this->pointer))) 422 // TODO - Seems Ecore_con now has trouble with my try first, then start method, so start first, then try. Fix this, or do something else.
366 { 423 case -3 :
367 this->add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb) _add, this); 424 printf("Failed to connect to a %s server, starting our own.\n", conn->name);
368 this->del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, (Ecore_Event_Handler_Cb) _del, this); 425 conn->conn.server.serverHandle = ecore_exe_pipe_run(conn->conn.server.serverCommand, ECORE_EXE_NONE /*| ECORE_EXE_TERM_WITH_PARENT*/, conn);
369 } 426 if (conn->conn.server.serverHandle)
370 count++; 427 {
371 } 428 conn->conn.server.pid = ecore_exe_pid_get(conn->conn.server.serverHandle);
429 if (conn->conn.server.pid == -1)
430 fprintf(stderr, "Could not retrive the PID!\n");
431 else
432 fprintf(stdout, "The child process has PID:%u\n", (unsigned int)conn->conn.server.pid);
433 }
434 else
435 fprintf(stderr, "Could not create server process %s!\n", conn->conn.server.serverCommand);
436
437 // TODO - There's also the question of what to do if the connection failed.
438 // Did the server crash, or was it just the connection?
439 // Also, I'm assuming the connection failed here, rather than went away after running for some time. Should differentiate.
440 // Probably gonna need some smarts, for now we just restart all the scripts.
441 // Which I think gets done on server add.
442 break;
443
444// TODO - Alternate strategy : Keep track of if we started a server, then keep pinging it's port until it answers,
445// with a timeout until we kill the server and start again.
446
447 case -2 : // Give the server some time to start up.
448 case -1 : // Give the server some time to start up.
449 // Check if the server is still running here, if not, reset stage to previous -3 (taking into account the increment at the end).
450 if (conn->conn.server.pid)
451 printf("Waiting for %s server to start from command \"%s\"\n", conn->name, conn->conn.server.serverCommand);
452 else
453 conn->stage = -4;
454 break;
455
456 case 0 :
457 printf("Attempting to connect to the %s server %s:%d.\n", conn->name, conn->address, conn->port);
458 // This should only return NULL if something goes wrong with the setup,
459 // you wont know if the connection worked until you get the add callback,
460 // or you get the del calback if it failed.
461 if ((server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, conn->address, conn->port, conn)))
462 printf("MAYBE connecting to the %s server %s:%d.\n", conn->name, conn->address, conn->port);
463 else
464 printf("FAILED to create the connection to the %s server %s:%d!\n", conn->name, conn->address, conn->port);
465 conn->conn.server.server = server;
466 break;
372 467
373 if (!server) 468 case 1 : // This stage is the serverAdd callback.
374 printf("Failed to connect to server %s:%d!\n", this->address, this->port); 469 break;
375 470
376 return server; 471 case 2 : // Give the server a chance to die.
472 break;
473
474 default :
475 if (5 < conn->stage)
476 conn->stage = 2; // loop back to nothing.
477// result = ECORE_CALLBACK_CANCEL;
478 break;
479 }
480 conn->stage++;
481
482 return result;
377} 483}
378#else 484
379Connection *reachOut(char *name, char *command, char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del) 485Connection *reachOut(char *name, char *command, char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser)
380{ 486{
381 Connection *conn = calloc(1, sizeof(Connection)); 487 Connection *conn = calloc(1, sizeof(Connection));
382 Ecore_Con_Server *server = NULL;
383 int count = 0;
384 488
385 conn->type = CT_SERVER; 489 conn->type = CT_SERVER;
386 conn->conn.server.serverCommand = strdup(command); 490 conn->conn.server.serverCommand = strdup(command);
491 // Sure, this is essentially a NOP, but lets be explicit here, this is a remote server, so no list of clients, not just an empty list.
492 conn->conn.server.clients = NULL;
387 conn->name = strdup(name); 493 conn->name = strdup(name);
388 conn->address = strdup(address); 494 conn->address = strdup(address);
389 conn->port = port; 495 conn->port = port;
390 conn->pointer = data; 496 conn->pointer = data;
391 conn-> = _add; 497 conn->_add = _add;
392 conn-> = _data; 498 conn->_data = _data;
393 conn-> = _del; 499 conn->_del = _del;
500 conn->unknownCommand = _parser;
394 conn->commands = eina_hash_string_superfast_new(NULL); 501 conn->commands = eina_hash_string_superfast_new(NULL);
395 502
396 // This loop is overkill I think. 503 conn->add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb) serverAdd, conn);
397 while ((!server) && (10 > count)) 504 conn->data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb) parseServerStream, conn);
398 { 505 conn->del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, (Ecore_Event_Handler_Cb) serverDel, conn);
399 if ((server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, address, port, data))) 506 conn->died = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _serverDied, conn);
400 {
401 conn->add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb) serverAdd, conn);
402 conn->data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb) parseServerStream, conn);
403 conn->del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, (Ecore_Event_Handler_Cb) serverDel, conn);
404 ecore_con_server_data_set(server, conn);
405 }
406 count++;
407 }
408 507
409 if (!server) 508 ecore_timer_add(1.0, _reachOutTimer, conn);
410 printf("Failed to connect to the %s server %s:%d!\n", name, address, port);
411 509
412 return conn; 510 return conn;
413} 511}
414#endif
diff --git a/src/libraries/SledjHamr.h b/src/libraries/SledjHamr.h
index 467fcc6..326e423 100644
--- a/src/libraries/SledjHamr.h
+++ b/src/libraries/SledjHamr.h
@@ -23,12 +23,22 @@ struct _ConnServer
23 Ecore_Con_Server *server; 23 Ecore_Con_Server *server;
24 char *serverCommand; 24 char *serverCommand;
25 int count, hackyCount; 25 int count, hackyCount;
26 // A list of connected remote clients.
27 // A NULL list means this is a remote server stored in a local clients Connection.
28 // An empty list means this is a local server, with no clients.
29 // An actual list means this is a local server, with connected remote clients.
30 Eina_Clist *clients; // HEAD element.
31 Ecore_Exe *serverHandle; // For running the server.
32 pid_t pid;
26}; 33};
27 34
28struct _ConnClient 35struct _ConnClient
29{ 36{
30 Ecore_Con_Client *client; 37 Ecore_Con_Client *client;
38 // If this is a local client, then myServer is a server Connection representing the remote server, and the server list entry element can be NULL.
39 // If this is a remote client, then myServer is NULL, and this Connection is stored in a list in the local server's Connection.
31 Connection *myServer; 40 Connection *myServer;
41 Eina_Clist *server; // Entry element.
32}; 42};
33 43
34struct _Connection 44struct _Connection
@@ -48,16 +58,19 @@ struct _Connection
48 // Callbacks. 58 // Callbacks.
49 void *pointer; 59 void *pointer;
50 Ecore_Event_Handler_Cb _add, _data, _del; 60 Ecore_Event_Handler_Cb _add, _data, _del;
51 Ecore_Event_Handler *add, *data, *del; 61 Ecore_Event_Handler *add, *data, *del, *died;
52 streamParser unknownCommand; 62 streamParser unknownCommand;
63
64 int stage; // Stage of creation for the Connection.
53}; 65};
54 66
55 67
56Ecore_Con_Server *reachOut(char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del);
57void *addMessage(Eina_Clist *list, size_t size, const char *message, ...); 68void *addMessage(Eina_Clist *list, size_t size, const char *message, ...);
58void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, ...); 69void sendBack(Connection *conn, const char *SID, const char *message, ...);
59void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, ...); 70void sendForth(Connection *conn, const char *SID, const char *message, ...);
60 71
72void send2(Connection *conn, const char *SID, const char *message, ...);
61Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser); 73Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser);
74Connection *reachOut(char *name, char *command, char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser);
62 75
63#endif 76#endif
diff --git a/src/love/love.c b/src/love/love.c
index 0465ee5..372141d 100644
--- a/src/love/love.c
+++ b/src/love/love.c
@@ -33,9 +33,8 @@ typedef struct _gameGlobals
33 Evas *canvas; // The canvas for drawing directly onto. 33 Evas *canvas; // The canvas for drawing directly onto.
34 Evas_Object *bg; // Our background edje, also the game specific stuff. 34 Evas_Object *bg; // Our background edje, also the game specific stuff.
35 Evas_Object *edje; // The edje of the background. 35 Evas_Object *edje; // The edje of the background.
36 Ecore_Con_Server *serverLuaSL; 36 Connection *serverLuaSL;
37 Ecore_Con_Server *server; 37 Connection *client; // TODO - Really should be a bunch of these.
38 Ecore_Con_Client *client; // TODO - Really should be a bunch of these.
39 Eina_Hash *scripts; 38 Eina_Hash *scripts;
40 const char *address; 39 const char *address;
41 int port; 40 int port;
@@ -52,7 +51,6 @@ typedef struct _Lscript
52 51
53 52
54int logDom = -1; // Our logging domain. 53int logDom = -1; // Our logging domain.
55static Eina_Strbuf *LuaSLStream;
56static int scriptCount = 0; 54static int scriptCount = 0;
57static int compiledCount = 0; 55static int compiledCount = 0;
58static struct timeval startTime; 56static struct timeval startTime;
@@ -149,12 +147,14 @@ static void dirList_compile(const char *name, const char *path, void *data)
149 } 147 }
150} 148}
151 149
150
152static Eina_Bool _addLuaSL(void *data, int type, Ecore_Con_Event_Server_Add *ev) 151static Eina_Bool _addLuaSL(void *data, int type, Ecore_Con_Event_Server_Add *ev)
153{ 152{
154 gameGlobals *ourGlobals = data; 153 gameGlobals *ourGlobals = data;
155 char buf[PATH_MAX]; 154 char buf[PATH_MAX];
156 155
157 ourGlobals->serverLuaSL = ev->server; 156 PI("LuaSL server added, sending it scripts to compile and run.");
157 ourGlobals->serverLuaSL = ecore_con_server_data_get(ev->server);
158 158
159 // Zero everything. 159 // Zero everything.
160 eina_hash_free(ourGlobals->scripts); 160 eina_hash_free(ourGlobals->scripts);
@@ -191,299 +191,277 @@ char *get_rawline(int fd, long *plen, char end)
191} 191}
192 192
193 193
194static Eina_Bool _dataLuaSL(void *data, int type, Ecore_Con_Event_Server_Data *ev) 194static Eina_Bool LuaSLParser(void *data, Connection *conn, char *SID, char *command, char *arguments)
195{ 195{
196 gameGlobals *ourGlobals = data; 196 gameGlobals *ourGlobals = data;
197
198 char buf[PATH_MAX]; 197 char buf[PATH_MAX];
199 char SID[PATH_MAX]; 198 LoveScript *me;
200 const char *command;
201 char *ext;
202 199
203 eina_strbuf_append_length(LuaSLStream, ev->data, ev->size); 200PW("COMMAND - %s - %s", SID, command);
204 command = eina_strbuf_string_get(LuaSLStream); 201 me = eina_hash_find(ourGlobals->scripts, SID);
205 while ((ext = index(command, '\n'))) 202 if (0 == strncmp(command, "compilerWarning(", 16))
206 { 203 {
207 int length = ext - command; 204 char *temp;
208 205 char *line;
209 strncpy(SID, command, length + 1); 206 char *column;
210 SID[length] = '\0'; 207 char *text;
211 eina_strbuf_remove(LuaSLStream, 0, length + 1); 208
212 ext = index(SID, '.'); 209 strcpy(buf, &command[16]);
213 if (ext) 210 temp = buf;
211 line = temp;
212 while (',' != temp[0])
213 temp++;
214 temp[0] = '\0';
215 column = ++temp;
216 while (',' != temp[0])
217 temp++;
218 temp[0] = '\0';
219 text = ++temp;
220 while (')' != temp[0])
221 temp++;
222 temp[0] = '\0';
223 PW("%s @ line %s, column %s.", text, line, column);
224 if (me)
225 me->warnings++;
226 }
227 else if (0 == strncmp(command, "compilerError(", 14))
228 {
229 char *temp;
230 char *line;
231 char *column;
232 char *text;
233
234 strcpy(buf, &command[14]);
235 temp = buf;
236 line = temp;
237 while (',' != temp[0])
238 temp++;
239 temp[0] = '\0';
240 column = ++temp;
241 while (',' != temp[0])
242 temp++;
243 temp[0] = '\0';
244 text = ++temp;
245 while (')' != temp[0])
246 temp++;
247 temp[0] = '\0';
248 PE("%s @ line %s, column %s.", text, line, column);
249 if (me)
250 me->bugs++;
251 }
252 else if (0 == strcmp(command, "compiled(false)"))
253 {
254// PE("The compile of %s failed!", SID);
255 if (me)
214 { 256 {
215 LoveScript *me; 257 struct timeval now;
216 258
217 ext[0] = '\0'; 259 compiledCount++;
218 command = ext + 1; 260 if (compiledCount == scriptCount)
219 me = eina_hash_find(ourGlobals->scripts, SID);
220 if (0 == strncmp(command, "compilerWarning(", 16))
221 { 261 {
222 char *temp; 262 float total = timeDiff(&now, &startTime);
223 char *line; 263 PD("Compile speed scripts: %d time: %fs total: %f scripts per second", compiledCount, total, compiledCount / total);
224 char *column;
225 char *text;
226
227 strcpy(buf, &command[16]);
228 temp = buf;
229 line = temp;
230 while (',' != temp[0])
231 temp++;
232 temp[0] = '\0';
233 column = ++temp;
234 while (',' != temp[0])
235 temp++;
236 temp[0] = '\0';
237 text = ++temp;
238 while (')' != temp[0])
239 temp++;
240 temp[0] = '\0';
241 PW("%s @ line %s, column %s.", text, line, column);
242 if (me)
243 me->warnings++;
244 } 264 }
245 else if (0 == strncmp(command, "compilerError(", 14)) 265 }
266 }
267 else if (0 == strcmp(command, "compiled(true)"))
268 {
269 if (me)
270 {
271 struct timeval now;
272
273 compiledCount++;
274 if (compiledCount == scriptCount)
246 { 275 {
247 char *temp; 276 float total = timeDiff(&now, &startTime);
248 char *line; 277 PD("Compile speed scripts: %d time: %fs total: %f scripts per second", compiledCount, total, compiledCount / total);
249 char *column;
250 char *text;
251
252 strcpy(buf, &command[14]);
253 temp = buf;
254 line = temp;
255 while (',' != temp[0])
256 temp++;
257 temp[0] = '\0';
258 column = ++temp;
259 while (',' != temp[0])
260 temp++;
261 temp[0] = '\0';
262 text = ++temp;
263 while (')' != temp[0])
264 temp++;
265 temp[0] = '\0';
266 PE("%s @ line %s, column %s.", text, line, column);
267 if (me)
268 me->bugs++;
269 } 278 }
270 else if (0 == strcmp(command, "compiled(false)")) 279 }
271 { 280 PD("About to run %s", me->fileName);
272// PE("The compile of %s failed!", SID); 281 sendForth(ourGlobals->serverLuaSL, SID, "run(%s)", me->fileName);
273 if (me) 282 }
274 { 283 else
275 struct timeval now; 284 {
285 // Send back some random or fixed values for testing.
286 if (0 == strcmp(command, "llGetKey()"))
287 sendForth(ourGlobals->serverLuaSL, SID, "return \"%08lx-%04lx-%04lx-%04lx-%012lx\"", random(), random() % 0xFFFF, random() % 0xFFFF, random() % 0xFFFF, random());
288 else if (0 == strcmp(command, "llGetOwner()"))
289 sendForth(ourGlobals->serverLuaSL, SID, "return \"%s\"", ownerKey);
290 else if (0 == strcmp(command, "llGetPermissionsKey()"))
291 sendForth(ourGlobals->serverLuaSL, SID, "return \"%s\"", ownerKey);
292 else if (0 == strncmp(command, "llRequestPermissions(", 21))
293 PI("Faked %s", command);
294 else if (0 == strcmp(command, "llGetPos()"))
295 sendForth(ourGlobals->serverLuaSL, SID, "return {x=128.0, y=128.0, z=128.0}");
296 else if (0 == strcmp(command, "llGetRot()"))
297 sendForth(ourGlobals->serverLuaSL, SID, "return {x=0.0, y=0.0, z=0.0, s=1.0}");
298 else if (0 == strcmp(command, "llGetFreeMemory()"))
299 sendForth(ourGlobals->serverLuaSL, SID, "return 654321");
300 else if (0 == strcmp(command, "llGetObjectDesc()"))
301 sendForth(ourGlobals->serverLuaSL, SID, "return \"\"");
302 else if (0 == strncmp(command, "llGetAlpha(", 11))
303 sendForth(ourGlobals->serverLuaSL, SID, "return 1.0");
304 else if (0 == strcmp(command, "llGetInventoryNumber(7)"))
305 sendForth(ourGlobals->serverLuaSL, SID, "return 3");
306 else if (0 == strcmp(command, "llGetLinkNumber()"))
307 sendForth(ourGlobals->serverLuaSL, SID, "return 1");
308 else if (0 == strcmp(command, "llGetInventoryName(7, 2)"))
309 sendForth(ourGlobals->serverLuaSL, SID, "return \".readme\"");
310 else if (0 == strcmp(command, "llGetInventoryName(7, 1)"))
311 sendForth(ourGlobals->serverLuaSL, SID, "return \".POSITIONS\"");
312 else if (0 == strcmp(command, "llGetInventoryName(7, 0)"))
313 sendForth(ourGlobals->serverLuaSL, SID, "return \".MENUITEMS\"");
314 else if (0 == strncmp(command, "llListen(", 9))
315 {
316 PI("Faked %s", command);
317 sendForth(ourGlobals->serverLuaSL, SID, "return %d", random());
318 }
319 else if (0 == strncmp(command, "llSameGroup(", 12))
320 sendForth(ourGlobals->serverLuaSL, SID, "return true");
321 else if (0 == strncmp(command, "llKey2Name(", 11))
322 {
323 char *temp;
324
325 strcpy(buf, &command[12]);
326 temp = buf;
327 while (')' != temp[0])
328 temp++;
329 temp[0] = '\0';
330 if (0 == strcmp(buf, ownerKey))
331 temp = ownerName;
332 else
333 temp = "Unknown User";
334 // TODO - Sanitize the name, no telling what weird shit people put in their names.
335 snprintf(buf, sizeof(buf), "return \"%s\"", temp);
336 sendForth(ourGlobals->serverLuaSL, SID, buf);
337 }
338 // Send "back" stuff on to the one and only client.
339 // TODO - All of these output functions should just use one thing to append stuff to either local or an IM tab.
340 // Love filtering out stuff that should not go there.
341 // Extantz registering any channel it wants to listen to, mostly for client side scripts.
342 // Extantz is then only responsible for the registered channels, it can do what it likes with them.
343 // Dialogs, notifications, and other stuff goes through some other functions.
344 else if (0 == strncmp(command, "llOwnerSay(", 11))
345 {
346 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
347 else PW("No where to send %s", command);
348 }
349 else if (0 == strncmp(command, "llWhisper(", 10))
350 {
351 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
352 else PW("No where to send %s", command);
353 }
354 else if (0 == strncmp(command, "llRegionSay(", 12))
355 {
356 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
357 else PW("No where to send %s", command);
358 }
359 else if (0 == strncmp(command, "llSay(", 6))
360 {
361 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
362 else PW("No where to send %s", command);
363 }
364 else if (0 == strncmp(command, "llShout(", 8))
365 {
366 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
367 else PW("No where to send %s", command);
368 // TODO - Temporary so we have a place to log stuff from LSL.
369 PD("SHOUTING %s", command);
370 }
371 else if (0 == strncmp(command, "llDialog(", 9))
372 {
373 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
374 else PW("No where to send %s", command);
375 }
376 else if (0 == strncmp(command, "llMessageLinked(", 16))
377 {
378 Eina_Iterator *scripts;
379 LoveScript *me;
276 380
277 compiledCount++; 381 // TODO - For now, just send it to everyone.
278 if (compiledCount == scriptCount) 382 scripts = eina_hash_iterator_data_new(ourGlobals->scripts);
279 { 383 while(eina_iterator_next(scripts, (void **) &me))
280 float total = timeDiff(&now, &startTime);
281 PD("Compile speed scripts: %d time: %fs total: %f scripts per second", compiledCount, total, compiledCount / total);
282 }
283 }
284 }
285 else if (0 == strcmp(command, "compiled(true)"))
286 { 384 {
287 if (me) 385 sendForth(ourGlobals->serverLuaSL, me->SID, "events.link_message%s", &command[15]);
288 {
289 struct timeval now;
290
291 compiledCount++;
292 if (compiledCount == scriptCount)
293 {
294 float total = timeDiff(&now, &startTime);
295 PD("Compile speed scripts: %d time: %fs total: %f scripts per second", compiledCount, total, compiledCount / total);
296 }
297 }
298 sendForth(ourGlobals->serverLuaSL, SID, "run(%s)", me->fileName);
299 } 386 }
300 else 387 eina_iterator_free(scripts);
388 }
389 else if (0 == strncmp(command, "llGetNotecardLine(", 18))
390 {
391 char *notecard, *temp, *line, key[PATH_MAX];
392 int lineNo, fd;
393
394 strcpy(buf, &command[19]);
395 notecard = buf;
396 temp = notecard;
397 while ('"' != temp[0])
398 temp++;
399 temp[0] = '\0';
400 while (',' != temp[0])
401 temp++;
402 while (' ' != temp[0])
403 temp++;
404 line = temp;
405 while (')' != temp[0])
406 temp++;
407 temp[0] = '\0';
408 lineNo = atoi(line);
409 snprintf(key, sizeof(key), "%s/Test%%20sim/onefang%%27s%%20test%%20bed/%s", prefix_data_get(), notecard);
410
411 fd = open(key, O_RDONLY);
412 if (-1 != fd)
301 { 413 {
302 // Send back some random or fixed values for testing. 414 Eina_Iterator *scripts;
303 if (0 == strcmp(command, "llGetKey()")) 415 LoveScript *me;
304 sendForth(ourGlobals->serverLuaSL, SID, "return \"%08lx-%04lx-%04lx-%04lx-%012lx\"", random(), random() % 0xFFFF, random() % 0xFFFF, random() % 0xFFFF, random()); 416 long len;
305 else if (0 == strcmp(command, "llGetOwner()"))
306 sendForth(ourGlobals->serverLuaSL, SID, "return \"%s\"", ownerKey);
307 else if (0 == strcmp(command, "llGetPermissionsKey()"))
308 sendForth(ourGlobals->serverLuaSL, SID, "return \"%s\"", ownerKey);
309 else if (0 == strncmp(command, "llRequestPermissions(", 21))
310 PI("Faked %s", command);
311 else if (0 == strcmp(command, "llGetPos()"))
312 sendForth(ourGlobals->serverLuaSL, SID, "return {x=128.0, y=128.0, z=128.0}");
313 else if (0 == strcmp(command, "llGetRot()"))
314 sendForth(ourGlobals->serverLuaSL, SID, "return {x=0.0, y=0.0, z=0.0, s=1.0}");
315 else if (0 == strcmp(command, "llGetFreeMemory()"))
316 sendForth(ourGlobals->serverLuaSL, SID, "return 654321");
317 else if (0 == strcmp(command, "llGetObjectDesc()"))
318 sendForth(ourGlobals->serverLuaSL, SID, "return \"\"");
319 else if (0 == strncmp(command, "llGetAlpha(", 11))
320 sendForth(ourGlobals->serverLuaSL, SID, "return 1.0");
321 else if (0 == strcmp(command, "llGetInventoryNumber(7)"))
322 sendForth(ourGlobals->serverLuaSL, SID, "return 3");
323 else if (0 == strcmp(command, "llGetLinkNumber()"))
324 sendForth(ourGlobals->serverLuaSL, SID, "return 1");
325 else if (0 == strcmp(command, "llGetInventoryName(7, 2)"))
326 sendForth(ourGlobals->serverLuaSL, SID, "return \".readme\"");
327 else if (0 == strcmp(command, "llGetInventoryName(7, 1)"))
328 sendForth(ourGlobals->serverLuaSL, SID, "return \".POSITIONS\"");
329 else if (0 == strcmp(command, "llGetInventoryName(7, 0)"))
330 sendForth(ourGlobals->serverLuaSL, SID, "return \".MENUITEMS\"");
331 else if (0 == strncmp(command, "llListen(", 9))
332 {
333 PI("Faked %s", command);
334 sendForth(ourGlobals->serverLuaSL, SID, "return %d", random());
335 }
336 else if (0 == strncmp(command, "llSameGroup(", 12))
337 sendForth(ourGlobals->serverLuaSL, SID, "return true");
338 else if (0 == strncmp(command, "llKey2Name(", 11))
339 {
340 char *temp;
341
342 strcpy(buf, &command[12]);
343 temp = buf;
344 while (')' != temp[0])
345 temp++;
346 temp[0] = '\0';
347 if (0 == strcmp(buf, ownerKey))
348 temp = ownerName;
349 else
350 temp = "Unknown User";
351 // TODO - Sanitize the name, no telling what weird shit people put in their names.
352 snprintf(buf, sizeof(buf), "return \"%s\"", temp);
353 sendForth(ourGlobals->serverLuaSL, SID, buf);
354 }
355 // Send "back" stuff on to the one and only client.
356 // TODO - All of these output functions should just use one thing to append stuff to either local or an IM tab.
357 // Love filtering out stuff that should not go there.
358 // Extantz registering any channel it wants to listen to, mostly for client side scripts.
359 // Extantz is then only responsible for the registered channels, it can do what it likes with them.
360 // Dialogs, notifications, and other stuff goes through some other functions.
361 else if (0 == strncmp(command, "llOwnerSay(", 11))
362 {
363 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
364 else PW("No where to send %s", command);
365 }
366 else if (0 == strncmp(command, "llWhisper(", 10))
367 {
368 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
369 else PW("No where to send %s", command);
370 }
371 else if (0 == strncmp(command, "llRegionSay(", 12))
372 {
373 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
374 else PW("No where to send %s", command);
375 }
376 else if (0 == strncmp(command, "llSay(", 6))
377 {
378 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
379 else PW("No where to send %s", command);
380 }
381 else if (0 == strncmp(command, "llShout(", 8))
382 {
383 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
384 else PW("No where to send %s", command);
385 // TODO - Temporary so we have a place to log stuff from LSL.
386 PD("SHOUTING %s", command);
387 }
388 else if (0 == strncmp(command, "llDialog(", 9))
389 {
390 if (ourGlobals->client) sendBack(ourGlobals->client, SID, command);
391 else PW("No where to send %s", command);
392 }
393 else if (0 == strncmp(command, "llMessageLinked(", 16))
394 {
395 Eina_Iterator *scripts;
396 LoveScript *me;
397 417
398 // TODO - For now, just send it to everyone. 418 temp = NULL;
399 scripts = eina_hash_iterator_data_new(ourGlobals->scripts); 419 do
400 while(eina_iterator_next(scripts, (void **) &me))
401 {
402 sendForth(ourGlobals->serverLuaSL, me->SID, "events.link_message%s", &command[15]);
403 }
404 eina_iterator_free(scripts);
405 }
406 else if (0 == strncmp(command, "llGetNotecardLine(", 18))
407 { 420 {
408 char *notecard, *temp, *line, key[PATH_MAX]; 421 free(temp);
409 int lineNo, fd; 422 temp = get_rawline(fd, &len, '\n');
410 423 if (temp)
411 strcpy(buf, &command[19]);
412 notecard = buf;
413 temp = notecard;
414 while ('"' != temp[0])
415 temp++;
416 temp[0] = '\0';
417 while (',' != temp[0])
418 temp++;
419 while (' ' != temp[0])
420 temp++;
421 line = temp;
422 while (')' != temp[0])
423 temp++;
424 temp[0] = '\0';
425 lineNo = atoi(line);
426 snprintf(key, sizeof(key), "%s/Test%%20sim/onefang%%27s%%20test%%20bed/%s", prefix_data_get(), notecard);
427
428 fd = open(key, O_RDONLY);
429 if (-1 != fd)
430 { 424 {
431 Eina_Iterator *scripts; 425 if (temp[len - 1] == '\n')
432 LoveScript *me; 426 temp[--len] = '\0';
433 long len; 427 }
428 } while (temp && (0 < lineNo--));
434 429
435 temp = NULL; 430 sprintf(key, FAKE_UUID);
436 do 431 sendForth(ourGlobals->serverLuaSL, SID, "return \"%s\"", key);
437 {
438 free(temp);
439 temp = get_rawline(fd, &len, '\n');
440 if (temp)
441 {
442 if (temp[len - 1] == '\n')
443 temp[--len] = '\0';
444 }
445 } while (temp && (0 < lineNo--));
446 432
447 sprintf(key, FAKE_UUID); 433 // TODO - For now, just send it to everyone.
448 sendForth(ourGlobals->serverLuaSL, SID, "return \"%s\"", key); 434 scripts = eina_hash_iterator_data_new(ourGlobals->scripts);
435 while(eina_iterator_next(scripts, (void **) &me))
436 {
437 if (temp)
438 {
439 char buf2[PATH_MAX];
440 int i, j, len = strlen(temp);
449 441
450 // TODO - For now, just send it to everyone. 442 // Escape ' and \ characters.
451 scripts = eina_hash_iterator_data_new(ourGlobals->scripts); 443 for (i = 0, j = 0; i <= len; i++)
452 while(eina_iterator_next(scripts, (void **) &me))
453 { 444 {
454 if (temp) 445 if ('\'' == temp[i])
455 { 446 buf2[j++] = '\\';
456 char buf2[PATH_MAX]; 447 if ('\\' == temp[i])
457 int i, j, len = strlen(temp); 448 buf2[j++] = '\\';
458 449 buf2[j++] = temp[i];
459 // Escape ' and \ characters.
460 for (i = 0, j = 0; i <= len; i++)
461 {
462 if ('\'' == temp[i])
463 buf2[j++] = '\\';
464 if ('\\' == temp[i])
465 buf2[j++] = '\\';
466 buf2[j++] = temp[i];
467 }
468 sendForth(ourGlobals->serverLuaSL, me->SID, "events.dataserver(\"%s\", '%s')", key, buf2);
469 }
470 else
471 sendForth(ourGlobals->serverLuaSL, me->SID, "events.dataserver(\"%s\", \"EndOfFuckingAround\")", key);
472 } 450 }
473 eina_iterator_free(scripts); 451 sendForth(ourGlobals->serverLuaSL, me->SID, "events.dataserver(\"%s\", '%s')", key, buf2);
474 free(temp);
475
476 close(fd);
477 } 452 }
478 453 else
454 sendForth(ourGlobals->serverLuaSL, me->SID, "events.dataserver(\"%s\", \"EndOfFuckingAround\")", key);
479 } 455 }
480 else 456 eina_iterator_free(scripts);
481 PI("Script %s sent command %s", SID, command); 457 free(temp);
458
459 close(fd);
482 } 460 }
483 }
484 461
485 // Get the next blob to check it. 462 }
486 command = eina_strbuf_string_get(LuaSLStream); 463 else
464 PI("Script %s sent command %s", SID, command);
487 } 465 }
488 466
489 return ECORE_CALLBACK_RENEW; 467 return ECORE_CALLBACK_RENEW;
@@ -492,26 +470,9 @@ static Eina_Bool _dataLuaSL(void *data, int type, Ecore_Con_Event_Server_Data *e
492static Eina_Bool _delLuaSL(void *data, int type, Ecore_Con_Event_Server_Del *ev) 470static Eina_Bool _delLuaSL(void *data, int type, Ecore_Con_Event_Server_Del *ev)
493{ 471{
494 gameGlobals *ourGlobals = data; 472 gameGlobals *ourGlobals = data;
495 static int count = 0;
496 473
497 ourGlobals->serverLuaSL = NULL; 474 ourGlobals->serverLuaSL = NULL;
498 475
499 // Let it fail a couple of times during startup, then try to start our own script server.
500 count++;
501 if (1 < count)
502 {
503 char buf[PATH_MAX];
504
505 PW("Failed to connect to a script server, starting our own.");
506 sprintf(buf, "%s/LuaSL &", prefix_bin_get());
507 system(buf);
508 count = 0;
509 // TODO - There's also the question of what to do if the connection failed.
510 // Did the server crash, or was it just the connection?
511 // Probably gonna need some smarts, for now we just restart all the scripts.
512 // Which I think gets done on server add.
513 }
514
515 // TODO - May want to renew even if it's not running the GUI, but then we still need some sort of "shut down" signal, which we don't need during testing. 476 // TODO - May want to renew even if it's not running the GUI, but then we still need some sort of "shut down" signal, which we don't need during testing.
516// if (ourGlobals->ui) 477// if (ourGlobals->ui)
517 return ECORE_CALLBACK_RENEW; 478 return ECORE_CALLBACK_RENEW;
@@ -525,7 +486,7 @@ static Eina_Bool _addClient(void *data, int type, Ecore_Con_Event_Client_Add *ev
525{ 486{
526 gameGlobals *ourGlobals = data; 487 gameGlobals *ourGlobals = data;
527 488
528 ourGlobals->client = ev->client; 489 ourGlobals->client = ecore_con_client_data_get(ev->client);
529 490
530 if (ourGlobals->client) 491 if (ourGlobals->client)
531 { 492 {
@@ -536,12 +497,11 @@ static Eina_Bool _addClient(void *data, int type, Ecore_Con_Event_Client_Add *ev
536 return ECORE_CALLBACK_RENEW; 497 return ECORE_CALLBACK_RENEW;
537} 498}
538 499
539 500static Eina_Bool clientParser(void *data, Connection *conn, char *SID, char *command, char *arguments)
540Eina_Bool clientParser(void *data, Connection *connection, char *SID, char *command, char *arguments)
541{ 501{
542 gameGlobals *ourGlobals = data; 502 gameGlobals *ourGlobals = data;
543 503
544 if (0 == strncmp(command, "events.touch_start", 18)) 504 if (0 == strncmp(command, "events.touch_start(", 19))
545 { 505 {
546 Eina_Iterator *scripts; 506 Eina_Iterator *scripts;
547 LoveScript *me; 507 LoveScript *me;
@@ -556,7 +516,7 @@ Eina_Bool clientParser(void *data, Connection *connection, char *SID, char *comm
556 } 516 }
557 eina_iterator_free(scripts); 517 eina_iterator_free(scripts);
558 } 518 }
559 else if (0 == strncmp(command, "events.listen", 13)) 519 else if (0 == strncmp(command, "events.listen(", 14))
560 { 520 {
561 Eina_Iterator *scripts; 521 Eina_Iterator *scripts;
562 LoveScript *me; 522 LoveScript *me;
@@ -605,11 +565,6 @@ int main(int argc, char **argv)
605 565
606 if (ecore_con_init()) 566 if (ecore_con_init())
607 { 567 {
608 LuaSLStream = eina_strbuf_new();
609 reachOut("127.0.0.1", 8211, &ourGlobals, (Ecore_Event_Handler_Cb) _addLuaSL, (Ecore_Event_Handler_Cb) _dataLuaSL, (Ecore_Event_Handler_Cb) _delLuaSL);
610
611 if (openArms("love", ourGlobals.address, ourGlobals.port + 1, &ourGlobals, (Ecore_Event_Handler_Cb) _addClient, NULL, (Ecore_Event_Handler_Cb) _delClient, clientParser))
612 {
613 if (ecore_evas_init()) 568 if (ecore_evas_init())
614 { 569 {
615 if (edje_init()) 570 if (edje_init())
@@ -721,20 +676,30 @@ int main(int argc, char **argv)
721 edje_object_signal_callback_add(ourGlobals.edje, "*", "game_*", _edje_signal_cb, &ourGlobals); 676 edje_object_signal_callback_add(ourGlobals.edje, "*", "game_*", _edje_signal_cb, &ourGlobals);
722 } 677 }
723 678
724 ecore_main_loop_begin(); 679 PD("About to try connecting to a LuaSL server.");
725 PD("Fell out of the main loop"); 680 // Try to connect to a local LuaSL server.
681 reachOut("LuaSL", "./LuaSL", "127.0.0.1", ourGlobals.port, &ourGlobals, (Ecore_Event_Handler_Cb) _addLuaSL, /*(Ecore_Event_Handler_Cb) _dataLuaSL*/ NULL, (Ecore_Event_Handler_Cb) _delLuaSL, LuaSLParser);
682
683 PD("Love is about to try creating a love server.");
684 if (openArms("love", ourGlobals.address, ourGlobals.port + 1, &ourGlobals, (Ecore_Event_Handler_Cb) _addClient, NULL, (Ecore_Event_Handler_Cb) _delClient, clientParser))
685 {
686 ecore_main_loop_begin();
687 PD("Fell out of the main loop");
726 688
727 if (ourGlobals.server) ecore_con_server_del(ourGlobals.server); 689// if (ourGlobals.server) ecore_con_server_del(ourGlobals.server);
728 if (ourGlobals.serverLuaSL) ecore_con_server_del(ourGlobals.serverLuaSL); 690// if (ourGlobals.serverLuaSL) ecore_con_server_del(ourGlobals.serverLuaSL);
691
692 }
693 else
694 PC("Failed to add server!");
729 695
730 if (ourGlobals.ui) 696 if (ourGlobals.ui)
731 { 697 {
732 ecore_animator_del(ani); 698 ecore_animator_del(ani);
733 ecore_evas_free(ourGlobals.ee); 699 ecore_evas_free(ourGlobals.ee);
734 } 700 }
735 }
736
737 edje_shutdown(); 701 edje_shutdown();
702 }
738 } 703 }
739 else 704 else
740 PC("Failed to init edje!"); 705 PC("Failed to init edje!");
@@ -743,10 +708,6 @@ int main(int argc, char **argv)
743 else 708 else
744 PC("Failed to init ecore_evas!"); 709 PC("Failed to init ecore_evas!");
745 710
746 }
747 else
748 PC("Failed to add server!");
749
750 ecore_con_shutdown(); 711 ecore_con_shutdown();
751 } 712 }
752 else 713 else
diff --git a/src/purkle/purkle.c b/src/purkle/purkle.c
index d00fd67..9a21700 100644
--- a/src/purkle/purkle.c
+++ b/src/purkle/purkle.c
@@ -49,17 +49,14 @@ static int say(lua_State *L)
49 if (id && text) 49 if (id && text)
50 { 50 {
51 GuiLua *gl; 51 GuiLua *gl;
52 Ecore_Con_Server *server = NULL;
53 52
54 snprintf(buf, sizeof(buf), "events.listen(%d, '%s', '%s', '%s')", channel, name, id, text); 53 snprintf(buf, sizeof(buf), "events.listen(%d, '%s', '%s', '%s')", channel, name, id, text);
55 // We do this rather than caching it, coz the server might change out from under us. 54 // We do this rather than caching it, coz the server might change out from under us.
56 lua_getfield(L, LUA_REGISTRYINDEX, glName); 55 lua_getfield(L, LUA_REGISTRYINDEX, glName);
57 gl = lua_touserdata(L, -1); 56 gl = lua_touserdata(L, -1);
58 lua_pop(L, 1); 57 lua_pop(L, 1);
59 if (gl) 58 if (gl && gl->server)
60 server = gl->server; 59 sendForth(gl->server, id, buf);
61 if (server)
62 sendForth(server, id, buf);
63 else 60 else
64 PW("PURKLE NOT SAY, no where to send %s", buf); 61 PW("PURKLE NOT SAY, no where to send %s", buf);
65 } 62 }