Lawo / ember-plus

Ember+ control protocol - Slick and free for all!
https://github.com/Lawo/ember-plus/wiki
Boost Software License 1.0
111 stars 41 forks source link

libember_slim get directory does not report any changes #101

Closed pixellon closed 4 years ago

pixellon commented 5 years ago

Hi I have implemented an ember plus provider and consumer using libember slim on linux. I have added a custom node that reads a text file myfile.txt.

int file_write (char * filename,char* text){
    FILE *fp;

    fp = fopen(filename,"w");
    if(fp == NULL){
        printf("unable to open file\n");
        exit(1);
    }
    fprintf(fp,"%s",text);
    fclose(fp);
    return 0;
}

'char* file_read(char * filename){
    FILE *fp;
    char * contents;
    char filecontent[32];
    fp = fopen(filename,"r");
    if(fp == NULL){
        printf("no such file \n");
        exit(1);
    }
    fscanf(fp,"%s",filecontent);
    contents = strdup(filecontent);
    fclose(fp);
    return contents;
}
static void createfiletest(SampleNode *pParent)
{
   SampleNode *pParam = createParameter(pParent, "filetest", "filetest");
   dword fields = pParam->fields;

   pParam->param.access = GlowAccess_ReadWrite;
   fields |= GlowFieldFlag_Access;

   pParam->param.type = GlowParameterType_String;
   fields |= GlowFieldFlag_Type;

   pParam->param.defaultValue.choice.pString = (char *)file_read("myfile.txt") ;
   pParam->param.defaultValue.flag = GlowParameterType_String;
   fields |= GlowFieldFlag_DefaultValue;

   pParam->param.value.choice.pString = (char *)file_read("myfile.txt") ;
   pParam->param.value.flag = GlowParameterType_String;
   fields |= GlowFieldFlag_Value;

   pParam->param.streamIdentifier = 2;
   fields |= GlowFieldFlag_StreamIdentifier;

   pParam->fields = (GlowFieldFlags)fields;
}
static void buildTree(SampleNode *pRoot)
{
   SampleNode *pVisualRoot, *pFood, *pNonFood, *pStreams, *pAudio;

   pVisualRoot = createNode(pRoot, "root", "root");

   pFood = createNode(pVisualRoot, "food", "Some food");
   createNode(pFood, "parsley", "tasty herb");
   createNode(pFood, "salad", "eat a lot of it!");

   pNonFood = createNode(pVisualRoot, "non-food", "tech stuff");

   pAudio = createNode(pNonFood, "audio", "ask Lawo");
   createGain(pAudio);
   createVolume(pAudio);
   createFormat(pAudio);
   createfiletest(pAudio);
   createNode(pAudio, "dangling", NULL);

   pStreams = createNode(pNonFood, "streams", "see 'em move");
   pStreams->node.pSchemaIdentifiers = stringDup("de.l-s-b.emberplus.samples.streams");
   pStreams->fields |= GlowFieldFlag_SchemaIdentifier;
   createStream1(pStreams);
   createStream2(pStreams);
   createStream3(pStreams);
   createStream4(pStreams);
}

Once i start the provider and consumer. i change the text inside my myfile.txt file and issue a get directory command. From what i understand the getDirectory command has to probe again for the changes in any elements in the tree but that does not seem to happen. I would appreciate if you could let me know if I am doing anything wrong ?

In this case how do i notify the consumer of the change ? should the getdirectory from the consumer not automatically read the changed parameters ?

Regards, -Pix.

mywave82 commented 5 years ago

I have created myself a function that looks like this (I keep a track of the clients in a linked list that I maintain, and made my own TreeEntry that assembles all the details needed for a node and glue them together with my own stuff)

void DistributeParameterChanged (TreeEntry pCursor) { GlowOutput output; byte pBuffer[512]; int packetSize; Client iter, *next;

    if (!Clients)
    {
            return;
    }

    glowOutput_init(&output, pBuffer, sizeof (pBuffer), 0);
    glowOutput_beginPackage(&output, true);
    glow_writeQualifiedParameter(&output, &pCursor->param,

GlowFieldFlag_Value, pCursor->Oid, pCursor->OidLength); packetSize = glowOutput_finishPackage(&output);

    for (iter = Clients; iter; iter = next)
    {
            next = iter->next; /* Just in case ClientWrite() calls

ClientKill() */ ClientWrite (iter, pBuffer, packetSize); } }

Stian Skjelstad

On Mon, Sep 23, 2019 at 9:04 AM pixellon notifications@github.com wrote:

Hi I have implemented an ember plus provider and consumer using libember slim on linux. I have added a custom node that reads a text file myfile.txt. ` int file_write (char filename,char text){ FILE *fp;

fp = fopen(filename,"w"); if(fp == NULL){ printf("unable to open file\n"); exit(1); } fprintf(fp,"%s",text); fclose(fp); return 0;

}

char file_read(char filename){ FILE fp; char contents; char filecontent[32]; fp = fopen(filename,"r"); if(fp == NULL){ printf("no such file \n"); exit(1); } fscanf(fp,"%s",filecontent); contents = strdup(filecontent); fclose(fp); return contents; }

static void createfiletest(SampleNode pParent) { SampleNode pParam = createParameter(pParent, "filetest", "filetest"); dword fields = pParam->fields;

pParam->param.access = GlowAccess_ReadWrite; fields |= GlowFieldFlag_Access;

pParam->param.type = GlowParameterType_String; fields |= GlowFieldFlag_Type;

pParam->param.defaultValue.choice.pString = (char *)file_read("myfile.txt") ; pParam->param.defaultValue.flag = GlowParameterType_String; fields |= GlowFieldFlag_DefaultValue;

pParam->param.value.choice.pString = (char *)file_read("myfile.txt") ; pParam->param.value.flag = GlowParameterType_String; fields |= GlowFieldFlag_Value;

pParam->param.streamIdentifier = 2; fields |= GlowFieldFlag_StreamIdentifier;

pParam->fields = (GlowFieldFlags)fields; } static void buildTree(SampleNode pRoot) { SampleNode pVisualRoot, pFood, pNonFood, pStreams, pAudio;

pVisualRoot = createNode(pRoot, "root", "root");

pFood = createNode(pVisualRoot, "food", "Some food"); createNode(pFood, "parsley", "tasty herb"); createNode(pFood, "salad", "eat a lot of it!");

pNonFood = createNode(pVisualRoot, "non-food", "tech stuff");

pAudio = createNode(pNonFood, "audio", "ask Lawo"); createGain(pAudio); createVolume(pAudio); createFormat(pAudio); createfiletest(pAudio); createNode(pAudio, "dangling", NULL);

pStreams = createNode(pNonFood, "streams", "see 'em move"); pStreams->node.pSchemaIdentifiers = stringDup("de.l-s-b.emberplus.samples.streams"); pStreams->fields |= GlowFieldFlag_SchemaIdentifier; createStream1(pStreams); createStream2(pStreams); createStream3(pStreams); createStream4(pStreams); } ` Once i start the provider and consumer. i change the text inside my myfile.txt file and issue a get directory command. From what i understand the getDirectory command has to probe again for the changes in any elements in the tree but that does not seem to happen. I would appreciate if you could let me know if I am doing anything wrong ?

In this case how do i notify the consumer of the change ? should the getdirectory from the consumer not automatically read the changed parameters ?

Regards, -Pix.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Lawo/ember-plus/issues/101?email_source=notifications&email_token=AC5IVRBIIWHPO7PEUMF7HEDQLBS7NA5CNFSM4IZHDASKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4HM6QGJQ, or mute the thread https://github.com/notifications/unsubscribe-auth/AC5IVRGOVYQTTRCR3UUGL4DQLBS7NANCNFSM4IZHDASA .

pixellon commented 5 years ago

Is this not what onParameter does ? I am doing a string compare onParameter and then changing the values on my provider. My understanding was that the getDirectory command will automatically query and update all the nodes and leafs which would automatically update the changed values. rather than the provider having to report them every time there is a change. Correct me if I am wrong here.

-Ash

mywave82 commented 5 years ago

That is the callback when the client sends a new value (for a writable node).

This variant of the library is just the bare bone for communication, and up to the application to maintain the tree, and decide what information should be sent to whom and when.

On Mon, 23 Sep 2019, 09:56 pixellon, notifications@github.com wrote:

Is this not what onParameter does ? I am doing a string compare onParameter and then changing the values on my provider. My understanding was that the getDirectory command will automatically query and update all the nodes and leafs which would automatically update the changed values. rather than the provider having to report them every time there is a change. Correct me if I am wrong here.

-Ash

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Lawo/ember-plus/issues/101?email_source=notifications&email_token=AC5IVREFYYCOB27JJFAPC2TQLBZCNA5CNFSM4IZHDASKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7KB6SQ#issuecomment-533995338, or mute the thread https://github.com/notifications/unsubscribe-auth/AC5IVRFEJF3RRNCPQ2MN5I3QLBZCNANCNFSM4IZHDASA .

pixellon commented 5 years ago

Hi @mywave82 what does the WriteClient function do in your code snippet ? In my case if i have to report the updated text every time the consumer issues a get directory command what should i be doing ?

mywave82 commented 5 years ago

Hi Ash

ClientWrite() buffers up data and schedules the file-descriptor for writing in the main-loop (Our application model is single threaded, main-loop using Linux as the host. Using an in-house library similar to glib-main loop, but much simpler)

If you do not buffer, and assume kernel buffer-space is sufficient, ClientWrite could directly call write()/send().

int ClientWrite (Client client, void data, const int Amount) { assert (client);

    if (Amount > client->TxBufferAvailable)
    {
            ClientKill (client);
            return -1;
    }
    memcpy (client->pTxBuffer + client->TxBufferFill, data, Amount);

    client->TxBufferFill += Amount;
    client->TxBufferAvailable -= Amount;

    assert ((client->TxBufferFill + client->TxBufferAvailable) ==

CLIENT_TX_BUFFER_SIZE);

    main_loop_fd_set_events (client->sock_reg, POLLIN | POLLOUT |

POLLHUP);

    return 0;

}

Stian Skjelstad

Hi @mywave82 https://github.com/mywave82 what does the WriteClient function do in your code snippet ?

pixellon commented 5 years ago

Hi Stian,

Thanks for the suggestion. I will try it out and let you know how it goes.

Regards, -Ash.

On 23 Sep 2019, at 14:59, Stian Sebastian Skjelstad notifications@github.com wrote:

Hi Ash

ClientWrite() buffers up data and schedules the file-descriptor for writing in the main-loop (Our application model is single threaded, main-loop using Linux as the host. Using an in-house library similar to glib-main loop, but much simpler)

If you do not buffer, and assume kernel buffer-space is sufficient, ClientWrite could directly call write()/send().

int ClientWrite (Client client, void data, const int Amount) { assert (client);

if (Amount > client->TxBufferAvailable) { ClientKill (client); return -1; } memcpy (client->pTxBuffer + client->TxBufferFill, data, Amount);

client->TxBufferFill += Amount; client->TxBufferAvailable -= Amount;

assert ((client->TxBufferFill + client->TxBufferAvailable) == CLIENT_TX_BUFFER_SIZE);

main_loop_fd_set_events (client->sock_reg, POLLIN | POLLOUT | POLLHUP);

return 0; }

Stian Skjelstad

Hi @mywave82 https://github.com/mywave82 what does the WriteClient function do in your code snippet ?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

pixellon commented 4 years ago

Hi Stian,

I did try the suggestion and I was now successfully able to report back the changes.

Thanks, -Ash.