Author Topic: Buffer  (Read 5225 times)

Offline Wipe

  • Rotator
  • Random is god
Buffer
« on: April 05, 2013, 11:50:59 pm »
Small interface for "packing" data of various type into single byte array... and back.

Initially used only with Run*Script() functions, later as a base of other scripts requiring to store various thing into one place. Unlike Serializator, Buffer makes use of operators, making code a bit more clear (IMHO). Additionally, it makes storing arrays bit easier (up to type[][][]), adds a way to "convert" data into (u)int(8/16/32/64) with single function.

Sending character name, id, and skills to client
Code: [Select]
// SERVER
void SendChar( Critter& cr )
{
     array<int> skills;
     for( uint s=__SkillBegin; s<=__SkillEnd; s++ )
     {
          skills.insertLast( cr.Param[s] );
     }
     Buffer@ buf = NewBuffer();
     buf << cr.Name << cr.Id << skills;
     cr.RunClientScript( "GetChar", 0, 0, 0, null, buf.AsInt32() );
}
// CLIENT
void GetChar( int, int, int, string@, int[]@ data )
{
     string name = "";
     uint id = 0;
     array<int> skills;
     Buffer@ buf = NewBuffer( data );
     buff >> name >> id >> skills;
}

See also buffer_h.fos for (bit incomplete) documentation. In short time i'll add some of mini-projects which will serve as examples of practical usage.

https://github.com/whine/buffer
Games are meant to be created, not played...

Offline Wipe

  • Rotator
  • Random is god
Re: Buffer
« Reply #1 on: April 06, 2013, 01:44:02 pm »
One of latest usage for Buffer has been done some time ago during tent system rework - i needed something for easy storing of tent names and that's how PData ("Personal Data") mini-system was made. Initially allowing to attach only strings to Location, after few updates, it allows to attach any data (as long Buffer knows how to convert it to uint8[]) to most important objects used - Location, Map, Critter and Item (but not stackable ones, due to mess with merging/splitting stacks). It can be easily extended to almost anything what a) can be identified by number, b) we can check if it exists by providing that number.

Other than Buffer, enum is second thing which has been used as a base of whole thing. Unlike defines, enums actually exists inside AngelScripts engine, so we can use them in our way. FOnline SDK does not provide anything what could make working with enums easier, so we need to provide our own stuff; lucky, it was already done at this point :P

When first PData is created, two AnyData entries are created - first contains data stored as byte array, and second - array of ids of single type (Critter etc.) which have anything attached to them. So for example: we want to attach array of strings to Map.
Code: [Select]
void SetMapOwners( Map& map, array<string>& owners )
{
     Buffer@ buff = NewBuffer();
     buff << owners;
     SetPersonalData( Map, "owners", buff.AsUint8() );
}

This will do few things (let's assume that map have id 12345): first, AnyData named "PDataMap:12345" is created, where we keep our string array. Second, we push map id into array named "PDataMap". This will help us later in cleanup. But before that, let's get the saved data and abuse it hard
Code: [Select]
void GetMapOwners( Map& map )
{
     array<uint8> raw;
     if( IsPersonalData( map, "owners" ) && GetPersonalData( map, "owners", raw ))
     {
          array<string> owners;
          Buffer@ buff = NewBuffer( raw );
          buffer >> owners;
          // ... do some heavy abuse on owners[] ... //
     }
}

Due to fact that AnyData is saved forever and ever, we need to take care of removing these, which are owned by non-existing objects - instead doing it on our own (what sometimes is impossible), we're going to use time event which will watch ids saved in previously made "PDataMap" for us. All what we need to do is start it on server init (for simplicity, event is not saved in worldsave).
Code: [Select]
StartPersonalDataCleanup()
Whole system sits deep under swarm of fuctions, but in the end we should use just top layer of them.
Code: [Select]
import void StartPersonalDataCleanup() from "pdata";

import bool IsPersonalData( Location& location, string& name ) from "pdata";
import bool GetPersonalData( Location& location, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Location& location, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Location& location, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Location& location, string& name ) from "pdata";

import bool IsPersonalData( Map& map, string& name ) from "pdata";
import bool GetPersonalData( Map& map, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Map& map, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Map& map, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Map& map, string& name ) from "pdata";

import bool IsPersonalData( Critter& critter, string& name ) from "pdata";
import bool GetPersonalData( Critter& critter, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Critter& critter, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Critter& critter, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Critter& critter, string& name ) from "pdata";

import bool IsPersonalData( Item& item, string& name ) from "pdata";
import bool GetPersonalData( Item& item, string& name, array<uint8>& value ) from "pdata";
import uint GetPersonalData( Item& item, array<string>& names, array<array<uint8>>& values ) from "pdata";
import bool SetPersonalData( Item& item, string& name, array<uint8>& value ) from "pdata";
import bool UnsetPersonalData( Item& item, string& name ) from "pdata";



This is probably not best example ever made for FOnline script, but whole Buffer-scripts family (yes, there's more!1one) is released for people who already have experience with developing FOnline, and are able to tune even poorly documented source (yes, that's only code i can create!1two) to own needs... sorry!

So, have fun.
https://github.com/whine/buffer/tree/master/pdata
Games are meant to be created, not played...

Offline wladimiiir

  • Rotator
  • Independent FOnline developer
Re: Buffer
« Reply #2 on: April 16, 2013, 03:38:41 pm »
Thanks for sharing.

Offline Wipe

  • Rotator
  • Random is god
Re: Buffer
« Reply #3 on: May 21, 2013, 08:20:03 am »
Wish to see if there any issues with base/lazy scripts - i know that (about base) operators aren't following any standards others than my personal taste (that especially affect ~buffer, -buffer operators), but i'd like to see if any issues have been spotted when using buffer/buffer_lazy). These two are going to be a base of bigger projects i'd like to share, so any feedback is appreciated :)

(PS: thank's for galachad for keeping script up to date)
« Last Edit: May 21, 2013, 08:22:33 am by Wipe »
Games are meant to be created, not played...