Skip to content

Commit

Permalink
Piu simulator workers
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Soquet authored and mkellner committed Feb 27, 2019
1 parent a9f2507 commit 772024a
Show file tree
Hide file tree
Showing 6 changed files with 408 additions and 99 deletions.
95 changes: 91 additions & 4 deletions build/simulator/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ typedef struct {
xsIntegerValue commodettoFormat;
} txPixelFormat;

typedef struct sxWorker txWorker;
struct sxWorker {
txScreen* screen;
txWorker* nextWorker;
xsIntegerValue id;
xsSlot slot;
};

extern void fxAbortCallback(void *info);
extern txPreparation* xsPreparation();

Expand Down Expand Up @@ -175,19 +183,40 @@ void fxScreenIdle(txScreen* screen)
}
}

void fxScreenInvoke(txScreen* screen, char* message, int size)
void fxScreenInvoke(txScreen* screen, char* buffer, int size)
{
xsBeginHost(screen->machine);
{
if (size < 0) {
int id = 0 - size;
txWorker* worker = screen->firstWorker;
while (worker) {
if (worker->id == id)
break;
worker = worker->nextWorker;
}
if (worker) {
xsVars(2);
xsVar(0) = xsAccess(worker->slot);
xsVar(1) = xsDemarshallAlien(buffer);
if (xsFindResult(xsVar(0), xsID("onmessage"))) {
(void)xsCallFunction1(xsResult, xsVar(0), xsVar(1));
}
else if (xsFindResult(xsVar(0), xsID("onMessage"))) {
(void)xsCallFunction1(xsResult, xsVar(0), xsVar(1));
}
}
}
else {
xsVars(2);
xsVar(0) = xsGet(xsGlobal, xsID("screen"));
xsVar(1) = xsGet(xsVar(0), xsID("context"));
if (xsTest(xsVar(1))) {
if (xsFindResult(xsVar(1), xsID("onMessage"))) {
if (size)
xsCallFunction1(xsResult, xsVar(1), xsArrayBuffer(message, size));
(void)xsCallFunction1(xsResult, xsVar(1), xsArrayBuffer(buffer, size));
else
xsCallFunction1(xsResult, xsVar(1), xsString(message));
(void)xsCallFunction1(xsResult, xsVar(1), xsString(buffer));

}
}
}
Expand Down Expand Up @@ -806,4 +835,62 @@ xsBooleanValue fxArchiveWrite(void* dst, size_t offset, void* buffer, size_t siz
return 1;
}

void Worker_destructor(void* data)
{
}

void Worker_constructor(xsMachine* the)
{
txScreen* screen = xsGetHostData(xsGet(xsGlobal, xsID_screen));
txWorker* worker = NULL;
if (!screen->createWorker) goto err;
worker = c_malloc(sizeof(txWorker));
if (!worker) goto err;
worker->id = (*screen->createWorker)(screen, xsToString(xsArg(0)));
if (!worker->id) goto err;
worker->slot =xsThis;
xsRemember(worker->slot);
worker->screen = screen;
worker->nextWorker = screen->firstWorker;
screen->firstWorker = worker;
xsSetHostData(xsThis, worker);
return;
err:
if (worker)
c_free(worker);
xsUnknownError("unable to instantiate worker");

}

void Worker_postMessage(xsMachine* the)
{
txWorker* worker = xsGetHostData(xsThis);
if (worker) {
txScreen* screen = worker->screen;
if (screen->post)
(*screen->post)(screen, xsMarshallAlien(xsArg(0)), 0 - worker->id);
}
}

void Worker_terminate(xsMachine* the)
{
txWorker* worker = xsGetHostData(xsThis);
if (worker) {
txScreen* screen = worker->screen;
txWorker **address = (txWorker**)&screen->firstWorker, *current;
while ((current = *address)) {
if (current == worker) {
*address = worker->nextWorker;
break;
}
address = &current->nextWorker;
}
xsForget(worker->slot);
if (screen->deleteWorker)
(*screen->deleteWorker)(screen, worker->id);
c_free(worker);
xsSetHostData(xsThis, NULL);
}
}


7 changes: 6 additions & 1 deletion build/simulator/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ typedef struct sxScreen txScreen;

typedef void (*txScreenAbortProc)(txScreen* screen);
typedef void (*txScreenBufferChangedProc)(txScreen* screen);
typedef int (*txScreenCreateWorkerProc)(txScreen* screen, char* name);
typedef void (*txScreenFormatChangedProc)(txScreen* screen);
typedef void (*txScreenDeleteWorkerProc)(txScreen* screen, int id);
typedef void (*txScreenIdleProc)(txScreen* screen);
typedef void (*txScreenLaunchProc)(txScreen* screen);
typedef void (*txScreenMessageProc)(txScreen* screen, char* message, int size);
typedef void (*txScreenMessageProc)(txScreen* screen, char* buffer, int size);
typedef void (*txScreenQuitProc)(txScreen* screen);
typedef void (*txScreenStartProc)(txScreen* screen, double interval);
typedef void (*txScreenStopProc)(txScreen* screen);
Expand All @@ -39,8 +41,11 @@ struct sxScreen {
void* machine;
void* view;
void* archive;
void* firstWorker;
txScreenAbortProc abort;
txScreenBufferChangedProc bufferChanged;
txScreenCreateWorkerProc createWorker;
txScreenDeleteWorkerProc deleteWorker;
txScreenFormatChangedProc formatChanged;
txScreenIdleProc idle;
txScreenMessageProc invoke;
Expand Down
29 changes: 29 additions & 0 deletions build/simulator/worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2016-2017 Moddable Tech, Inc.
*
* This file is part of the Moddable SDK Runtime.
*
* The Moddable SDK Runtime is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Moddable SDK Runtime is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Moddable SDK Runtime. If not, see <http://www.gnu.org/licenses/>.
*
*/

class Worker @ "Worker_destructor" {
constructor(module) @ "Worker_constructor";
postMessage(message) @ "Worker_postMessage";
terminate() @ "Worker_terminate";
};

export default Worker;

Object.freeze(Worker.prototype);
100 changes: 74 additions & 26 deletions modules/piu/PC/Screen/lin/piuScreen.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ struct PiuScreenMessageStruct {
PiuScreenMessage nextMessage;
PiuScreen* self;
int size;
char buffer[1];
char* buffer;
};

static void PiuScreenBind(void* it, PiuApplication* application, PiuView* view);
Expand Down Expand Up @@ -200,26 +200,23 @@ void PiuScreenBind(void* it, PiuApplication* application, PiuView* view)
free(screen);
}

void PiuScreenDictionary(xsMachine* the, void* it)
{
}

PiuScreenMessage PiuScreenCreateMessage(PiuScreen* self, char* buffer, int size)
{
PiuScreenMessage message;
if (size) {
message = (PiuScreenMessage)malloc(sizeof(PiuScreenMessageRecord) - 1 + size);
if (!message)
return NULL;
message->size = size;
memcpy(message->buffer, buffer, size);
}
PiuScreenMessage message = (PiuScreenMessage)malloc(sizeof(PiuScreenMessageRecord));
if (!message)
return NULL;
message->size = size;
if (size < 0)
message->buffer = buffer;
else {
message = (PiuScreenMessage)malloc(sizeof(PiuScreenMessageRecord) + size);
if (!message)
if (!size)
size = strlen(buffer) + 1;;
message->buffer = malloc(size);
if (!message->buffer) {
free(message);
return NULL;
message->size = 0;
strcpy(message->buffer, buffer);
}
memcpy(message->buffer, buffer, size);
}
message->nextMessage = (*self)->firstMessage;
(*self)->firstMessage = message;
Expand All @@ -238,13 +235,18 @@ void PiuScreenDeleteMessage(PiuScreen* self, PiuScreenMessage message)
while ((current = *address)) {
if (current == message) {
*address = message->nextMessage;
free(message->buffer);
free(message);
break;
}
address = &(current->nextMessage);
}
}

void PiuScreenDictionary(xsMachine* the, void* it)
{
}

void PiuScreenMark(xsMachine* the, void* it, xsMarkRoot markRoot)
{
PiuContentMark(the, it, markRoot);
Expand Down Expand Up @@ -350,18 +352,24 @@ void PiuScreen_launch(xsMachine* the)
xsThrow(xsException);
}
}

void PiuScreen_postMessage(xsMachine* the)
{
PiuScreen* self = PIU(Screen, xsThis);
PiuScreenMessage message;
if (xsIsInstanceOf(xsArg(0), xsArrayBufferPrototype)) {
int size = (int)xsGetArrayBufferLength(xsArg(0));
message = PiuScreenCreateMessage(self, xsToArrayBuffer(xsArg(0)), size);
if (xsToInteger(xsArgc) > 1) {
int worker = (int)xsToInteger(xsArg(1));
message = PiuScreenCreateMessage(self, xsMarshallAlien(xsArg(0)), 0 - worker);
}
else {
xsStringValue string = xsToString(xsArg(0));
message = PiuScreenCreateMessage(self, string, 0);
if (xsIsInstanceOf(xsArg(0), xsArrayBufferPrototype)) {
int size = (int)xsGetArrayBufferLength(xsArg(0));
message = PiuScreenCreateMessage(self, xsToArrayBuffer(xsArg(0)), size);
}
else {
xsStringValue string = xsToString(xsArg(0));
message = PiuScreenCreateMessage(self, string, 0);
}
}
if (message)
g_idle_add(PiuScreen_postMessageAux, message);
Expand Down Expand Up @@ -403,6 +411,41 @@ void fxScreenBufferChanged(txScreen* screen)
gtk_widget_queue_draw_area((*self)->gtkDrawingArea, 0, 0, screen->width, screen->height);
}

int fxScreenCreateWorker(txScreen* screen, char* name)
{
PiuScreen* self = (PiuScreen*)screen->view;
int worker = 0;
xsBeginHost((*self)->the);
{
xsVars(3);
xsVar(0) = xsReference((*self)->behavior);
if (xsFindResult(xsVar(0), xsID_onCreateWorker)) {
xsVar(1) = xsReference((*self)->reference);
xsVar(2) = xsString(name);
xsResult = xsCallFunction2(xsResult, xsVar(0), xsVar(1), xsVar(2));
worker = xsToInteger(xsResult);
}
}
xsEndHost((*self)->the);
return worker;
}

void fxScreenDeleteWorker(txScreen* screen, int worker)
{
PiuScreen* self = (PiuScreen*)screen->view;
xsBeginHost((*self)->the);
{
xsVars(3);
xsVar(0) = xsReference((*self)->behavior);
if (xsFindResult(xsVar(0), xsID_onDeleteWorker)) {
xsVar(1) = xsReference((*self)->reference);
xsVar(2) = xsInteger(worker);
(void)xsCallFunction2(xsResult, xsVar(0), xsVar(1), xsVar(2));
}
}
xsEndHost((*self)->the);
}

void fxScreenFormatChanged(txScreen* screen)
{
}
Expand All @@ -429,15 +472,19 @@ gboolean fxScreenPostAux(gpointer data)
PiuScreen* self = message->self;
if ((*self)->behavior) {
xsBeginHost((*self)->the);
xsVars(3);
xsVars(4);
xsVar(0) = xsReference((*self)->behavior);
if (xsFindResult(xsVar(0), xsID_onMessage)) {
xsVar(1) = xsReference((*self)->reference);
if (message->size)
if (message->size < 0) {
xsVar(2) = xsDemarshallAlien(message->buffer);
xsVar(3) = xsInteger(0 - message->size);
}
else if (message->size > 0)
xsVar(2) = xsArrayBuffer(message->buffer, message->size);
else
xsVar(2) = xsString(message->buffer);
(void)xsCallFunction2(xsResult, xsVar(0), xsVar(1), xsVar(2));
(void)xsCallFunction3(xsResult, xsVar(0), xsVar(1), xsVar(2), xsVar(3));
}
xsEndHost((*self)->the);
}
Expand All @@ -462,3 +509,4 @@ void fxScreenStop(txScreen* screen)
(*self)->timerRunning = FALSE;
}
}

Loading

0 comments on commit 772024a

Please sign in to comment.