Extending the refactored engine – Properties

by Ali Lloyd on May 28, 2014 7 comments

One of the main goals of the refactoring project was to increase the clarity and extensibility of the LiveCode engine, by cleaning up and modularising the script execution code. The project has made it easier than ever to contribute to the development of LiveCode.

One of the areas of syntax in which this is particularly visible is that of properties. The setting and getting of properties is now largely table-driven. Say you want to add ‘myProperty’ as a global boolean property. Here is how it would be done

1) Add your property to the property enum type

The file ‘parsedef.h’ contains all the enum types associated with livecode syntax. For internal reference, ‘myProperty’ needs a numerical value, so you would just add P_MY_PROPERTY to the Properies enum.

2) Add ‘myProperty’ to the table of syntax tokens.

The file ‘lextable.cpp’ contains all the strings of LiveCode’s reserved words in various contexts. The factor table is where all the tokens for properties are defined. In this case, we would add the line

{"myProperty", TT_PROPERTY, P_MY_PROPERTY},

This associates the token with its type (property) and the enum value added in step 1. Make sure it is in alphabetical order! Script parsing uses the alphabetical ordering to speed lookup, so any mistakes will cause unexpected errors.

3) Add to the property info table

The property info table, kMCPropertyInfoTable, is located at the top of the file ‘property.cpp’. We would add

DEFINE_RW_PROPERTY(P_MY_PROPERTY, Bool, <Module>, MyProperty)

where <Module> is the name of the module in which the property should reside. This adds all the relevant information for the engine to be able to execute the relevant property setters and getters.

4) Implement the functions

The final piece of the puzzle is to implement the following two functions:

MC<Module>GetMyProperty(MCExecContext& ctxt, bool& r_value)
MC<Module>SetMyProperty(MCExecContext& ctxt, bool p_value)

All being well, this is enough to get the line ‘set the myProperty to true’ in LiveCode to execute the C++ code in the body of MC<Module>SetMyProperty(MCExecContext& ctxt, bool p_value), with p_value equal to true.

In the enhancement requests section of the LiveCode forums, Dar Scott recently suggested having properties of “opened things” (i.e. sockets, processes and files). This proved to be relatively simple to add to the engine, and can be seen on GitHub at https://github.com/runrevali/livecode/tree/feature_pseudo-object_props.

I have implemented the following examples:

the rect of screen 
the openmode of file|process 
the name of socket 

Notice that the last example is merely an example and not actually useful at all (it just returns the name you put in, or throws an error if the socket is not found). The first example, although equivalent to ‘line of the screenrects’, is an example of the kind of syntax that will be available with Open Language. However it is not a waste of time to implement pseudo-object properties now – it will save some effort later on when Open Language is implemented. Getting the openmode (read/write/update/append etc) of a process or file is, I believe, not currently possible, at least not directly.

The idea is just to have as a separate type of chunk expression, the pseudo-object, which behaves similarly to object chunks. There are no compound pseudo-objects (yet); the only way they parse correctly is in the form ‘the
of [screen|socket|file|process] ‘.

The framework has been set up so that more pseudo-objects can be added if necessary. Every pseudo-object needs:

– A property table, and function MC<Module>GetPropertyTable() that returns it,

– A ‘get object’ function, MC<Module>GetObject, that returns the relevant pseudo-object from the expression (eg the socket from the socket name, the screen from the screen index)

– A template function which calls the appropriate getters and setters

The implementations of these should be fairly easy to copy, see for example the file exec-network-socket.cpp for the implementations of the first two, and for the third exec.h, (search for MCSocketPropertyThunk) which contains the macros and templates – the complex systems of levers and pulleys that makes it work.

If the infrastructure of your pseudo-object is already there, you can add properties to it in much the same way as for the global properties described above, but adding the appropriate incantation to the pseudo-object’s property table. See MCScreenGetRect for a simple example, or MCProcessGetOpenMode for an example using an enumerated string type.

If you’re thinking of contributing to the engine, go to the Engine Contributors LiveCode forum at forums.runrev.com to discuss your ideas with us and other contributors.

read more
Ali LloydExtending the refactored engine – Properties

LiveCode for Tiger Moms

by Hanson Schmidt-Cornelius on May 23, 2014 3 comments

Over the last few years, more information has been emerging in the media, contrasting differences in education practices between Asian and Western parents and guardians, with books being published and reports appearing in prestigious journals. I do not intend to poke around in a bees nest here and will leave judgement on child education to the respective parents and guardians. 

What I do offer is an insight into how LiveCode can assist would be Tiger Mothers, parents and guardians who would like to raise their children’s mental maths ability and self-esteem.

In most societies, mathematics is part of an educational curriculum and there are a number of tested and proven approaches to teach this and encourage sprogs to enjoy their learning. However, especially when it comes to learning the basics of manipulating numbers and using mathematical operators, you may come across a degree of resistance.

Maybe this is because a certain games console is being neglected or there is a lack in agreement on the importance of being able to add a couple of numbers together. On the other hand you may find yourself with a child who is just purely bored with the level of mathematics offered at school and requires more challenging content. And no, the latter kind of children are not just fabled beings, they do actually exist and can be a challenge to work with.

There are of course applications that teach maths, and there are text books that have problems upon problems your kids are encouraged to indulge in. These tools are limited by what the application designers consider appropriate or by the number of equations one can squeeze on the page of a textbook. As most parents/guardians will know, children develop at different speeds, and motivation can be a balancing act between joy and tantrums.

This is where LiveCode comes in. Properly applied, LiveCode can help you emerge victorious from any battle and empower you to generate an endless numbers of equations that are at the right level for your child.

And of course the answers are also provided, allowing you to keep your street cred. Children have a miraculous tendency to remember events where you display any sign of weakness, and they utilize this knowledge to maximize their advantage in the next round of homework activities.

The code in this blog is a mathematical problem generator that can be placed in the script of a button control and modified at will. There is no woolliness in the code, only functionality that serves the purpose of generating equations for endless fun at learning.

You can of course modify the code to create your own stack that populates the configuration information with the appropriate variables and outputs the problems in a more interactive fashion. If you are really adventurous, why not ask your child to update the code for you, teaching them to build their own learning aids. 

I have added comments after the lines of code that are intended to be updated. These lines set variable values that control how the problems are generated:

1. tOperators stores a list of operators that should be used in the equations.

2. tInputRange1 defines the range of the first number in the equations.

3. tInputRange2 defines the range of the second number in the equations.

4. tOutputRange specifies the range of valid result values.

5. tAllowReal is a flag that determines whether or not the output can be a floating point number.

6. tProblemCount defines the maximum number of equations that are to be generated.

on mouseUp
   local tOperators, tInputRange1, tInputRange2, tOutputRange, tProblemCount, tAllowReal
   local tProblems, tProblemIndex, tEquation, tOperator, tVariable1, tVariable2, tResult
   // Parameters to be updated.
   put "+,-,*,/" into tOperators // The operators that are used in the equations.
   put "-50,50" into tInputRange1 // The range of the first number in the equations.
   put "1,100" into tInputRange2 // The range of the second number in the equations.
   put "-500,500" into tOutputRange // The permissible result range.
   put false into tAllowReal // Are the results allowed to have floating point values (true/false).
   put "20" into tProblemCount // The number of problems to generate.
   put empty into tProblems
   repeat with tProblemIndex = 1 to tProblemCount
     put item random (number of items in tOperators) of tOperators into tOperator
     repeat with tTestValidity = 1 to 100
         put random (item 2 of tInputRange1 - item 1 of tInputRange1 + 1) + item 1 of tInputRange1 -1 into tVariable1
         put random (item 2 of tInputRange2 - item 1 of tInputRange2 + 1) + item 1 of tInputRange2 -1 into tVariable2
         // Do a bit of testing to ensure we do not violate some fundamental rules.
         if tOperator is "/" and tVariable is 2 then next repeat
         do "do" && quote & "put" && tVariable1 && tOperator && tVariable2 && "into tResult" & quote
         // Test if the answer is allowed to contain floating point results.
         if tAllowReal is false and tResult is not an integer then next repeat
         // Test if the answer is within the specified range.
         if tResult  item 2 of tOutputRange then next repeat
         put tVariable1 & tab & tOperator & tab & tVariable2 & tab & "=" & tab & tab & tab & tResult into tEquation
         // Check that we do not already have the new equation we generated.
         if tEquation is among the lines of tProblems then next repeat
         put tEquation & return after tProblems
         exit repeat
     end repeat
   end repeat
   put tProblems into msg
end mouseUp

The default settings, as shown in this code, were used to generate the output shown in the attached image. The output is written directly into the message box. This output can be copied and pasted into other applications for printing or other manipulation. I left a larger gap between the problems and the results. This allows the results to be covered up when the problems are being solved and revealed when the answers are being checked.

example-output

read more
Hanson Schmidt-CorneliusLiveCode for Tiger Moms

How to Create an App with no coding experience?

by Steven Crighton on May 21, 2014 7 comments

A little over a year ago, and before I had discovered LiveCode, I asked my best friend Google this very question …How to create an app?

I found myself having lots of ideas both good and bad, and a serious desire to launch my own app, but how on earth could I achieve it?

I have a background in web development, design, online brand management and digital marketing, I am certainly not an app developer.

read more
Steven CrightonHow to Create an App with no coding experience?

LiveCode Global Jam: May 23 and 24

by Richard Gaskin on May 16, 2014 3 comments

Many open source projects have “global jam” events to rally their community around specific initiatives, and in the LiveCode world we have a big task ahead of us: testing LiveCode 7.0.

This first LiveCode Global Jam will take place May 23 and 24, with the goal of bringing as many interested LiveCode fans together to make a difference with one of the most ambitious LiveCode versions ever.

Version 7.0 includes a wide range of new features, including not only Unicode, but also folding in the OS X Cocoa support and more. With so much going into it, it can become a solid reference version for all of our work with LiveCode going forward – provided we take the time to test it thoroughly before release.

The theme of this first LiveCode Global Jam is “7th Heaven”, sharing a vision with the community for a new version that’s the most capable and stable version ever. To make this happen we’ll need as many people testing it as we can get – and that’s where you come in.

If you can set aside even just an hour during the Global Jam to help test with your projects, it’ll help us all a lot.

Prior to the Global Jam we’ll be providing testing guidelines so you can test copies of your stack files safely, and if you find any errors we’ll include tips for delivering the type of report the dev team can act on quickly. Additionally, we’re putting together a team of volunteers to provide live support for testers, so if you have trouble pinning down a reproducible recipe for your bug report you’ll have people you can contact to help. While we’re submitting bug reports, the team at RunRev is committed to focusing on fixing any issues you find as they come in, in as close to real-time as possible.

But it wouldn’t be much fun if it was all work, so we also have two live Q&A video chats scheduled as well: LiveCode CEO Kevin Miller from Edinburgh and yours truly as LiveCode Community Manager from Los Angeles. The video chats will be held via Google Hangouts so you can submit questions there, and they’ll be recorded so you can watch any you miss later on YouTube.

For access to the event schedule, testing support contacts, and more, you needn’t look any further than your installed copy of LiveCode: the LiveCode Global Jam is being managed via RevNet, accessed through the GoRevNet plugin included in the Development->Plugins menu.

We have a preliminary version of the Global Jam edition of RevNet in place now, and as we get close to the event you’ll find RevNet updated to include the latest info.

If you’d like to volunteer to help provide support for testers, host a video chat of your own, or have any suggestions for other activities for the LiveCode Global Jam, please send me an email and let’s make it happen. Many thanks to all of you who’ve been testing LiveCode 7, and for those of you who can spare some time to test during the Global Jam.

Together we can make this new version of LiveCode one we can be especially proud to share with the world.

Richard Gaskin

LiveCode Community Manager

richard@livecode.org

read more
Richard GaskinLiveCode Global Jam: May 23 and 24

Multimedia on MacOS

by Panagiotis Merakos on May 15, 2014 23 comments

The current project I am working on is about multimedia on MacOS. It includes replacing all  multimedia functionality (in the player object, revVideoGrabber external etc)  in LiveCode to use the latest Mac APIs (AVFoundation, introduced in OSX 10.7). All these multimedia capabilities rely on the QuickTime/QTKit APIs. But Apple recently deprecated QuickTime APIs. This means that apps that use QuickTime will be rejected in the AppStore submission.

 So, after transitioning the existing Quicktime/QTKit code to AVFoundation, users should be able to submit a multimedia based app to the AppStore for their OS 10.7 customers and above.

 The problem is that the new APIs do not provide the same functionality as the original QuickTime API, so we must ensure that we will provide our users with the same feature set they are currently used to. For example, the player control bar. QTKit’s controller is broken in OSX 10.7+ and AVFoundation does not have a controller until OSX 10.9. This means that we need to write our own custom controller.  

 I have almost finished implementing the custom controller, at least as far as the functionality is concerned. It probably needs a bit more work to look prettier! 

Below are both the QTKit controller and our custom controller, as implemented so far. Note that the selection handles are broken in QTKit controller on OSX 10.7+

QTKit controller for multimedia playback
QTKit controller for multimedia playback

 

custom controller
Custom controller for multimedia playback

The next stage is to update the LiveCode player object and all other multimedia functionality in the engine to use the newest AVFoundation APIs, as well as to implement a QTKit/AVFoundation version of the revVideoGrabber, since it too relies on the deprecated QuickTime API.

read more
Panagiotis MerakosMultimedia on MacOS

Keeping an eye on your server

by David Williams on May 13, 2014 3 comments

Knowing how to interrogate your machines and get the *precise* information you need from them is a pretty wide-ranging topic. There are any number of ways of approaching this depending on what you need the data for. I’m going to go through some of the ways we keep an eye on our hardware, and where necessary, get detailed data from the server for analysis. Please note that the tools and servers we’re looking at here are Linux and may not be applicable to other server environments.

One of the main things we need to be aware of to get a gauge of how well the server is running is the server load average. This is essentially CPU usage calculated over time intervals (usually 1 minute, 5 minute, and 15 minute). We can see the load averages at a glance using the ‘uptime’ command:

root@jasmine [~]# uptime
15:41:41 up 126 days, 1:40, 2 users, load average: 0.10, 0.07, 0.05

This displays (among a few other things), the 3 load averages. A load average of 1 for a computer with 1 CPU core means that the CPU is fully used – anything over 1 means it’s overloaded. Our machines have 8-core CPUs, so we can see that this machine is very calm at the moment – a load of >8 would indicate overloading.

However, this command doesn’t give us much, and is entirely static. A better command for keeping an eye on the load and the rest of the system utilization is the ‘top’ command, perhaps the single most useful all-rounder for seeing system status at a glance:

topscreenshot

This command gives us an interactive and continuously updated display with the uptime, load averages, number (and status) of running tasks (processes), the CPU usage, the memory usage, and then a list of running processes which we can order in various ways. It’s essentially a command-line analogue of the task manager (windows) or activity monitor (osx), albeit a lot more flexible in some ways.

This shows us a sampling of the current running processes, but what if we need to see a comprehensive list of every single running process on the machine? We can use the ps command. The ps command is used for getting information about processes in various ways, in this instance we want to use the a u and x arguments to give us a detailed list of every single running process. The output of ‘ps -aux’ looks something like this:

psaux

We can look through this to get more of an idea of everything that’s currently running, and if we know what we’re looking for we can search through the output (via the ‘grep’ command for example) to determine whether the expected processes are there or not. This is great, but it’s very hard to read if we just want a summary of the current processlist. There are various utilities that do this, but why not write a quick one that does exactly what we want in LiveCode Server?

#!/usr/local/cpanel/cgi-sys/livecode-server

put $0 into tUserFilter
put shell("ps aux") into tProcessList

repeat for each line tLine in tProcessList
if tUserFilter <> empty and word 1 of tLine <> tUserFilter 
then next repeat
add 1 to tOutputArray[word 1 of tLine][word 11 to -1 of tLine]
end repeat

repeat for each key tUser in tOutputArray
put tUser & ":" & return
repeat for each key tProcName in tOutputArray[tUser]
put tab & tProcName & ":" && 
tOutputArray[tUser][tProcName] & return
end repeat
put return
end repeat

This little script gives us a nice summary of what the running processes are for each user and how many of those processes are running. We can also give it a user to filter by if we only want to see processes from that user using the $x variables – command line arguments passed to a LiveCode app are accessible by using $ and their position in the argument list (in this instance we use $0 to access the first argument passed, which we expect to be a username).

psdigest

The above tells us all about load and processes, but what if we want to know about what those processes are doing with the disk? There is some standard functionality in Linux for this, but we often use a great utility called ‘iotop’ (non-standard) to get this info, which functions in a similar way to top:

iotop

We can see, again, that this server isn’t very busy. One other thing we may want to know about is the current open connections and their status, which we can check using netstat. We almost always use netstat with the -n argument, as otherwise it will try and lookup the hostnames of the addresses involved, which is time-consuming.

netstat

This information contains a list of all the open TCP and UDP connections on the server, with the local address:port and the remote address:port pairs for each. This is very useful as we can quickly look through or parse this data for various purposes, for example we can see all the current mysql connections by using grep (the Linux search command) with the mysql port number:

netstat -n | grep 3306

This is useful as we can see where all these connections are coming from, which can aid in diagnosing certain types of issue. We could expand on this slightly to simply get the number of current mysql connections using the wc (word count) command with the -l (count lines) option:

netstat -n | grep 3306 | wc -l

These are some of the basic command line utilities we use to gather information about the system. There are many many more tools of various complexity that we use which would most likely take a small novel’s worth of blog posts to cover. At the heart of it, being able to query the system for specific information at the command line is often more fast an effective than using a complex GUI-based program that may not tell you precisely what you’re looking for.

read more
David WilliamsKeeping an eye on your server

Matrix Multiplication and Fullscreen Mode

by Ian Macphail on May 9, 2014 6 comments

In the old days, things were pretty simple. If you wrote an app for an iPhone, you knew it would look the same on everyone else’s iPhone too. You could also write a version of your app to fit the fixed size of the iPad. And if you were feeling extra fancy even create an alternate layout for the different orientations.

Then along came Android. As an open source operating system not tied to any particular vendor, device manufacturers are free to make devices with any size or shape they want, (within reason, i.e. a rectangle). Consequently, You could be assured that whatever size you designed your app within, your users would end up running it on a device with totally different dimensions.

To tackle this problem we’ve introduced fullscreen modes that allow your app to scale to fit the bounds of the screen in a number of different ways, depending on whether your app will allow some parts of the stack to go offscreen or use as much screen space available while keeping all stack content visible.

Each fullscreen mode can result in different scaling values, as well as repositioning to keep the stack content centred on the screen. What we end up with then is a series of transforming operations to be applied when drawing the stack to convert the coordinates to their new size & position.

Within the engine we use a common mathematical trick to represent different types of coordinate transformations – matrix multiplication. I won’t go into too much detail on matrices, (you can read more here), but effectively what they provide is a way to combine multiple different types of geometrical operations into a single object. A matrix can represent a rotation, translation (movement along the x and y axes), or scaling operation. A sequence of such operations can be represented as the multiplication of their representative matrices together, producing a single matrix equivalent to the whole sequence.

The operations to fit a stack’s content within the visible screen space can then be defined in terms of a single matrix, which is used whenever it is necessary to convert from logical stack coordinates to the coordinate system of the view into which it will be drawn. We can use the same matrix to draw the stack, or to convert the location of mouse clicks or touch events, or to make sure pop-up menus and dialogs are positioned correctly regardless of the scale or position of the stack within its window. This ensures that the appearance of the stack and the location of any events related to it are kept consistent whatever the fullscreen mode might be.

read more
Ian MacphailMatrix Multiplication and Fullscreen Mode

Video or Written Documents?

by Heather Laine on May 1, 2014 24 comments

How is it best to deliver help and instruction? I started musing on this question when I got feedback from a customer on just how much he hated video tutorials as a medium to learn programming. Really, I thought? How common is that? His argument was that it’s much faster to read text, pull out the relevant bits and absorb the information you are looking for, and sitting through a video takes longer. I wonder how true this is and in what context. 

Of course, working in support, I’m acutely aware that most people would rather put their hand in a fire than read the instructions. In a perfect world, software would just leap out of the screen, grab you round the throat and yell "Don’t do that to me! Do it this way instead!" Or putting it another way, the interface would be so self explanatory that no-one would need any kind of instructional materials at all. For a complex programming environment like LiveCode, that’s a pretty tall order. You are just going to have to learn the language, sometime, somehow. Read the dictionary, work through some lessons, join one of our summer courses or get some Academy tutorials. But which? Some people prefer to read a book in the bath (our dictionary will probably keep you clean for a year), others might prefer to follow along to a video. The academies are a nice mix, you get both. Every video has a written accompanying document you can copy and paste from. I’d love to be a fly on the wall to see how people actually use them. Do you watch the video? Do you just read the document? How much does the video contribute to your understanding of the document and vice versa? 

I’m the kind of person that likes to learn specific things, when I need them. I am unlikely to sit down and read a book on Dreamweaver from cover to cover, but if I need to know how to do a specific thing like create a rotating gif, I’ll go and look it up. Usually not in the Dreamweaver help, which sucks, but by googling it, and grabbing a nice text tutorial. Yes, I realized in thinking about this, I would not look for a video. Videos annoy me. They mean I have to turn my music off to listen to them, and you can’t copy and paste from a video. I am the Queen of Copy and Paste!

My daughter, on the other hand, will never read anything if there is a video alternative. Reading seems to be something that does not come naturally to the younger generation. 

Relevant to these musings also is the question, is it better to have short self contained tutorials on specific things, or a longer more themed book, tutorial series or video course, going through a subject in depth? Our lessons are an example of the former, they are based around the theory of answering one specific question – how do I use Google Maps in LiveCode? How do I connect to an SQLite database? For me, this is a good way to learn. I’m not overwhelmed by a tome on the theory of storing and accessing data and including it in an app, I just do what I need to do, today. Over time, as I do more and more of these specific tasks, things fall into place and I reach that "aha" moment where it all starts to make sense and I can flexibly create new items from what I have learned and understood. But other people might be happier with a soup to nuts guide before they start on their own first app. 

So where do you guys fit? What comes naturally to a programmer? How and when did you reach your "aha" moment?

This is Lily’s take on this complex issue, after considerable thought:

clip_image002

read more
Heather LaineVideo or Written Documents?