Wednesday, 4 November 2015

Modernising Uniface - part 2

I posted last week about Modernising Uniface, which included my comments about Theo Neeskens post on UnifaceInfo.com.  I received some comments that I was talking purely about the IDE, and not the language itself.  So let me start by stating that this post of about the modernisation of the IDE, and not the language itself.

This time the post is all about the effort it took to make the seemingly simple move from grey backgrounds (which psychologically make software feel outdated) white clean, clear, white backgrounds, like this...

For both of these dialogs, the older grey version sits behind the newer white version.  You can also see the buttons have changed, but we've been promised more about those in the next blog post.


The main problems they hand with this change included...
  • Forms having index, foreground or background colour set
  • Painted entities having index, foreground or background colour set (and being painted at least 3 characters wide)
  • Entities having foreground or background colour set in the model
  • Grids not having borders
  • Multi-occurrence entities not having borders

A couple of these have been resolved by making new properties available, but all of them required fix programs to find the affected items and update them to the new properties.  All of the tools have been provided in a zip file, to be downloaded and modified if you wish, but not supported by Uniface and used at your own risk.

I've had my hands on Uniface 9.7 now (which I hadn't when I wrote the first post) and I can say that it definitely feels more up-to-date, and I agree that the white backgrounds and blue buttons are a large part of that.  We've actually been changing our web offering to a similar colour scheme over the past few months, so I can't disagree with their choice!

Again, the full blog post is definitely worth checking out... Modernizing Uniface 9.7, Part 2.


Summary: Uniface is modernising it's IDE, and we're not going to have to wait for Uniface 10 to get in on the action.

Thursday, 15 October 2015

Modernising Uniface

Uniface have been putting a lot of work into the new Uniface 10 IDE, and this is something I'm looking forwards to getting my hands on, but it could be a while yet.  Good things come to those who wait, they say.

Well the good news is that the delays in Uniface 10 have led to the decision to release a Uniface 9.7.  Whilst they may be planning to put limited time into this, whilst focusing their efforts on Uniface 10, it looks like they have big plans to modernise.

In the first of a 10 part series, Theo Neeskens has outlined the objectives and the first set of changes - the start screen.

The objectives were straightforward enough...

  1. New start page - Windows 10-esque - big change.
  2. Change grey backgrounds to white backgrounds.
  3. Use trendy flat buttons.
  4. Fresh look and new colour scheme - something different.

Looks like they met the objectives, based on these screenshots...



Now that's a radical change!  I think changes like this will be very well received, and help stop people getting such a negative first impression of Uniface as a language.

The full blog post is definitely worth checking out... Modernizing Uniface 9.7 in 10 easy steps.

Summary: Uniface is modernising, and we're not going to have to wait for Uniface 10 to get in on the action.

Friday, 24 July 2015

Where to put your code

There's an interesting blog post by Dennis Vorst gone up on the Uniface.info blog, titled Where to put your code.  As the title suggests, it's about which places are best for different types of code, based on their content.  

There are a number of options; conceptual at the entity or field level, locally at the entity or field level, within the component, a local procedure or a global procedure.  All of these have their merits.  

I've posted my response, defending the mighty global procedure, but why don't you have a read and add your opinion in the comments?

Summary: Check out this blog post... http://unifaceinfo.com/where-to-put-your-code

Monday, 29 June 2015

WCG Online

I must apologise, this is not a Uniface-related post.  That said, please read on!

World Community Grid enables anyone with a computer, smartphone or tablet to donate their unused computing power to advance cutting-edge scientific research on topics related to health, poverty and sustainability. Through the contributions of over 650,000 individuals and 460 organizations, World Community Grid has supported 24 research projects to date, including searches for more effective treatments for cancer, HIV/AIDS and neglected tropical diseases. Other projects are looking for low-cost water filtration systems and new materials for capturing solar energy efficiently.

Active projects include... 
  • Outsmart Ebola Together
  • Uncovering Genome Mysteries
  • Mapping Cancer Markers
  • The Clean Energy Project - Phase 2
  • FightAIDS@Home.

If you're not already a member, you can sign up here.

I have just launched a companion site; WCG Online...



This site is designed to give you, a valued member of the community, access to some more detailed statistics, as well as some lovely pretty graphs.  It requires for username and a verifcation code, in order to fetch the relevant data.  Nothing is stored on my server, all data is stored in your brower's local or session storage.  This is then used to notify you of new milestones, such as badges earned.  It allows you to rename and hide devices, so if you've got multiple devices (two phones, a tablet, etc) you can give them more easily identifiable names, or hide them completely from the other pages.

The site is also designed to be fully responsive and mobile friendly, created from the ground up in jQuery Mobile.

The next part of the project is to create custom widgets that you can link to on your own site.  The offical site has widgets, but they use iframes and are rather basic.  So I'm hoping to create images, and give a lot more flexiblity.  Watch for those coming soon to WCG Online.

There is also a Play store app, which provides a shortcut to the website, and is free to download, if you're interested.

Saturday, 2 May 2015

Performance of getitem

I've previously posted about how scanning is slow, and I stand by that.  But I've recently discovered that in some situations, it can be less slow than using getitem.  

I was doing a code review of some old code and found that it was using $scan in a situation where I thought you'd usually use getitem, and wondered why someone would have done it this way.  But before I replaced it, I wanted to check the performance to see what difference I would be making by changing it, and I was surprised by the results!

The code was designed to check if a variable matched one of a reasonably large number of items.  For this example, if stuck with 10 items...

  if ( temp = "ONE" | temp = "TWO" | temp = "THREE" | temp = "FOUR" | temp = "FIVE" | temp = "SIX" | temp = "SEVEN" | temp = "EIGHT" | temp = "NINE" | temp = "TEN" )
    ;testing condition
  endif

I could have used a line continuation marker, but you get the idea.

What the developer had done is replaced this set of conditions with a single $scan, like this...

  list = "|ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE|TEN|"
 
if ( $scan(list,"|%%temp%%%|") > 0 )
    ;testing condition
  endif

Note that this is not a Uniface list, a "bar" or "pipe" character has been used as the delimiter - this is placed at the beginning and end of the value to ensure it is not found as a sub-part of another longer value.  It This takes up a lot less space, and is perfectly readable, but I was concerned about performance.  

To test this, I wanted to make sure it was fair, so I decided to always check both the first and the last item in the list in each iteration.  I also wanted to test in a few different ways, and I came up with 4...

1) Set of conditions

  temp = "ONE"
  if ( temp = "ONE" | temp = "TWO" | temp = "THREE" | temp = "FOUR" | temp = "FIVE" | temp = "SIX" | temp = "SEVEN" | temp = "EIGHT" | temp = "NINE" | temp = "TEN" )
    ;testing condition
  endif
  temp = "TEN"
  if ( temp = "ONE" | temp = "TWO" | temp = "THREE" | temp = "FOUR" | temp = "FIVE" | temp = "SIX" | temp = "SEVEN" | temp = "EIGHT" | temp = "NINE" | temp = "TEN" )
    ;testing condition
  endif

2) $scan a bar delimited string

  list = "|ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE|TEN|"
 
if ( $scan(list,"|ONE|") > 0 )
    ;testing condition
  endif
  list = "|ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE|TEN|"
  if ( $scan(list,"|TEN|") > 0 )
    ;testing condition
  endif

3) getitem/id a Uniface list

  list = "ONE·;TWO·;THREE·;FOUR·;FIVE·;SIX·;SEVEN·;EIGHT·;NINE·;TEN"
  getitem/id temp,list,"ONE"
  if ( $status > 0 )
    ;testing condition
  endif
  list = "ONE·;TWO·;THREE·;FOUR·;FIVE·;SIX·;SEVEN·;EIGHT·;NINE·;TEN"
  getitem/id temp,list,"TEN"
  if ( $status > 0 )
    ;testing condition
  endif

4) $item a Uniface list

  list = "ONE·;TWO·;THREE·;FOUR·;FIVE·;SIX·;SEVEN·;EIGHT·;NINE·;TEN"
  if ( $item("ONE",list) != "" )
    ;testing condition
  endif
  list = "ONE·;TWO·;THREE·;FOUR·;FIVE·;SIX·;SEVEN·;EIGHT·;NINE·;TEN"
  if ( $item("TEN",list) != "" )
    ;testing condition
  endif


I wasn't really sure what I was expecting, but I thought the $scan would be the worst performance.  I tested over 2,000,000 iterations, and here's what I got...

1) Set of conditions: 37.30, 36.95, 37.83 = 37.36 secs
2) $scan a bar delimited string: 21.76, 21.97, 21.24 = 21.66 secs
3) getitem/id a Uniface list: 24.46, 24.22, 24.89 = 24.52 secs
4) $item a Uniface list: 22.65, 23.25, 23.47 = 23.12 secs

So the slowest was the set of conditions.  I didn't test it, but knowing that if statements shortcut I figure that if the item was always passing the first condition it would be quick, but because half of my test items were only passing the last condition, it would have to check each of the conditions in the set before it passed.

Although there wasn't a big difference, what surprised me is that the getitem/id and $item were actually slower than the $scan in this case.  I then remembered back to a conversation on the Uniface-L mailing list, which talked about how Uniface handles lists in the background.  The description there indicates that an array is built in the background, which means there is an upfront cost for calling getitem/id (or $item) once, but then if you're looping through it is much quicker to access the rest, because the array can be used.  However, because I'm rebuilding the list each time, that means the array needs to be rebuilt each time.  

This means that actually $scan can be used to improve the performance when checking that an item is in a list, as long as you're only checking this list once and it's not going to be re-used.  I expect there to be a point at which the number of times the list is re-used means that using getitem/id (or $item) would become better for performance.

Also, I've not tested different lengths of lists.  However, given the results and my reasoning for why the results ended up this way, I would have thought extending the list would simply emphasize the results.

Summary:  Checking if an item is in a list can be done a number of ways, and if it's being done a lot of times, performance can be eeked out by using a $scan, surprisingly!

Saturday, 11 April 2015

Modernising the client application - icons in the menu

A lot of the Uniface development that I do these days is actually web development, which means I spend a lot of time with Javascript and JQuery, and less time with Uniface procscript.  However, we still have client applications as well, and they can look tired and dated, so anything we can do to make them look more modern, can be a big win!

This is a simple little trick that appeared in Uniface 9.6.  It's actually been around for a while in dropdown menus, first as an undocumented feature, and then documented in Uniface 9.5 - I wrote a blog post on this almost three years ago.  However, the same trick now works in menus.

You can reference images in the menu items like this...


You might not be able to read the image clearly, so the three menu items are...

  1. ^U_REM_SELECT·!Cu%t
  2. ^U_SAVE·!Copy
  3. ^U_INS_SELECT·!Paste

In this case, the image is at the start, with a gold-not (or gold-exclamation-mark) as a delimiter, and the menu item text after that.

This appears in the client application this this...



As you can see - lovely icons!  Please note that you would need these glyphs in your system for it to work, these are not provided as part of Uniface itself.  

You can include icons in one of two ways...

  • ^glyph - glyphs need to be compiled into UOBJ (always available and performs well).
  • @filename - images loaded from a fileserver (not always available and performs badly).

I would recommend the glyph option though, for performance and reliability.

You may also note that the percent character (%) can be used to denote which character should work when traversing the menu using the "Alt" key.  If you do not explicitly denote this, the first character will be used.

This is documented in the "Defining and Using Menus" section of the manuals, but can be hard to find unless you know what you're looking for!  It's worth reading this for more information though.

Summary:  It's possible to make the client application look a little more modern now by including icons in the menu bars.

Thursday, 9 April 2015

Undocumented feature - current assignment file

One great feature of Uniface is it's great flexibility and configurability, through the use of different assignment (.asn) files.  These are used to define paths to the different runtime files and server locations, etc.  The problem can then come though, especially with multiple environments, that you don't know which assignment file you're using!

I wrote a post a while ago about the undocumented $assignments function, which allows you to get access to the assignment file settings that you are currently using, but this doesn't help you get to the filename itself.

One suggestion I've seen before is to add a logical to each assignment file which specifies the name/location of the file.  However, it's way too easy for someone to move, copy or rename the file and neglect to update the logical, and then worse than not knowing, you think you do know but the information you're being given is inaccurate.

Luckily Uniface 9.6.06 has solved this problem with a new undocumented feature of $processinfo...


  putmess $processinfo("cmdline")

This will put the command line used to access the application into the message buffer.  For example...


  "\\server\location\uniface\bin\uniface.exe" /asn=\\server\location\adm\uclidev.asn /ini=\\server\location\ini\me.ini APPSHELL


As you can see, the assignment file and ini file are both specified in the command line, along with the application shell as well.  This should give you all the information you need, although you'll need to do some string manipulation to pull out the bit(s) you want.

This was recently discussed on the UnifaceInfo.com forums, so you can check there for more context, and sign up if you haven't already!

Summary: You can access the current assignment file location, but accessing the command line, as long as you're happy to use an undocumented/unsupported feature.