660 likes | 834 Views
Multi-User Publishing Environment (MUPE) Application Platform. Tutorial v.1.21 riku.suomela@nokia.com. MUPE – Multi-User Publishing Environment. MUPE is an application platform for rapid development of (mobile) multi-user context-aware applications and services.
E N D
Multi-User Publishing Environment (MUPE) Application Platform Tutorial v.1.21 riku.suomela@nokia.com
MUPE – Multi-User Publishing Environment • MUPE is an application platform for rapid development of (mobile) multi-user context-aware applications and services. • All parts of MUPE are written in Java (J2ME in clients) • Everything is available under the Nokia Open Source license 1.0. • MUPE server contains a simple virtual world, that is extended for each application. • Scripted client UI script language – one client for all applications. • Context information is added to the system from the network, or from each user client. • Communications data compressed • http://www.mupe.net • http://pong.hiit.fi/mupedev
Key Features • Optimised for the wireless network • Minimized network data traffic (data compression) – compulsory for services whose price depends of it • Optimised graphics (download at connection) • Dynamic content (objects in the client can be referred at a later time) • Persistent content – all content is serialized • Only server side application programming • Support for camera, sound, video with MMAPI • Public screen support
MUPE Application Platform Overview Wireless network Client MUPE Core MUPE Server End-user devices:mobile phoneswith J2ME Middleware:connections MUPE application functionality Context External producers
MUPE in more detail Connection middleware Client Client Manager World Manager MUPE Server Client Client Manager Client Client Manager Client Wireless connection Internet Context Manager MUPE MUPE MUPE Context producer Context producer Context producer
How the server works? • Clients make method calls to the server, and the server replies with a valid UI script. • All connected users can get push messages if using TCP
Server: Static/Dynamic separated • Clients make method calls to the server objects(or receives PUSH message) • Server returns a valid UI script • UIs can be created with XML – no need for programming/compilation • Added application logic – Java (J2SE) programming MUPE Application Programming Java(J2SE) XML DYNAMIC: Application logic STATIC: UI & Interaction
APIs MUPE Server Client API clientMethodName(User caller, …) MUPE Client internal XML API XMLmethodName(User caller, …) XML File XML File XML File XML File XML File
Structure Parser AbstractWorld 1 * Base contains 1 World * 1 1 * BaseExtensions owned by 0..1 Room Service Item User Messaging- Service Grouping- Service Message Group ContextManager
The basic MUPE Server • A Fully functioning virtual world • Easily customisable for new content with Java and XML (only server side programming needed – no J2ME programming required) MUPE Virtual World Content Super Classes User Room Item Service
Building a new MUPE Server AbstractWorld World User MyUser Room MyRoom ContextManager MyContextManager
The World Creation Abstract World Parser World AbstractWorld() World() createDefaultRoom() createContextManager() createWorldContent()
User Connections – A new Instance of the User object World Phone Parser clientCreateUser() elsewhere
Push • TCP allows the server to push information to each connected user
Each content object has 1 Class file and N XML files • All objects that can have a UI must have an XML file • All objects that can be created on the move must have creator.xml • All objects that can be accessed directly must have description.xml • All objects that can be edited must have Editor.xml • Any number (or none) of other XML files allowed • The superclass ones are used if none defined and needed MyUser Xml/content/MyUser/ Description.xml Creator.xml Editor.xml Etc.
The connection (handled by the framework) Client Server clientSubscribe XML UI: character creation User::clientCreate {1} {$(nickname.text)} XML UI: default room
reconnection Client Server clientActivate(caller, passcode) XML UI: default room (or last room user was in)
Basic user creation XML Script for Character Creation <template type='form' id=''> <editfield title='Nickname' id='nickname' /> <command type='ok' text='Ready'> <g_send type='tcp' type='request'> User::clientCreate {1} {$(nickname.text)} </g_send> </command> </template> MUPE Server: Class Constructor public User(User caller, Base location, String name)
Customize the user creation XML Script for Character Creation <template type='form' id=''> <editfield title='Nickname' id='nickname' /> <choicegroup id='type' title='Character type'> <i_choice name='0' text='Fighter' /> <i_choice name='1' text='Thief' /> <i_choice name='2' text='Wizard' /> <i_choice name='3' text='Gnome' /> </choicegroup> <command type='ok' text='Ready'> <g_send type='tcp' type='request'> Player::clientCreate {1} {$(nickname.text)} {$(type.selected)} </g_send> </command> </template> MUPE Server: Class Constructor public String Player(User caller, Base location,String nickname, int type) Player(…, 1, ”Bob”, 3)
Server Side Dynamic XML methods Allows the UIs to be created with references to the Java code. The code is evaluated prior to sending to the clients. Description.xml - A Room description with dynamic calls <template type='form' id=''> <string text=‘!#XMLGetContents#!’> <command type='ok' text='Ready'> <g_send type='tcp' type='request'> !#XMLGetID#!::someMethodname {withStringParameter} </g_send> </command> !#XMLGetRoomCommands#! </template> MUPE Server: XML Embedded Method public String XMLGetContents(User caller) public String XMLGetRoomCommands(User caller) public String XMLGetID(User caller); // provided by the framework always
Server Side Dynamic XML methods The evaluated UI Script <template type='form' id=''> <string text=‘You see a treasure chest. It is locked and made of Iron.’ <command type='ok' text='Ready'> <g_send type='tcp' type='request'> 133::someMethodname {withStringParameter} </g_send> </command> <command type=‘menu’ text=‘pick lock’> <g_send>133::clientAction {picklock} </command> <command type=‘menu’ text=‘Hit’> <g_send>133::clientAction {hit} </command> <command type=‘menu’ text=‘pick up’> <g_send>133::clientAction {pickup} </command> </template>
Server Side Dynamic XML methods with parameters !#XMLGetRoomCommands {param0} {param1}#! public String XMLGetRoomCommands(long caller, long param0, String param1) <string id=‘!#param0#!’ text=‘!#param1#!’ /> <command text=‘!#param1#!’> <g_send>!#param0#!::clientMethod {1}</g_send> </command> !#XMLGetRoomCommands {!#XMLGetID#!} {param1}#!
Server Side Dynamic XML file inclusion The evaluated UI Script <template type='form' id=''> <string text=‘You see a treasure chest. It is locked and made of Iron.’ <command type='ok' text='Ready'> <g_send type='tcp' type='request'> clientPoll </g_send> </command> !#/commands.xml#! </template> Commands.xml: <command type=‘menu’ text=‘pick lock’> <g_send>133::clientAction {picklock} </command> <command type=‘menu’ text=‘Hit’> <g_send>133::clientAction {hit} </command> <command type=‘menu’ text=‘pick up’> <g_send>133::clientAction {pickup} </command>
parameterised XML files <!--param0=idparam1=xparam2=yparam3=cropxparam4=cropyparam5=cropwidthparam6=cropheightparam7=framewidthparam8=frameheightparam9=anyotherattributes,suchasselectable="true“param10=Anyhooks,atributes,etcinsidetheitem--> <imageid='!#param0#!'x='!#param1#!'y='!#param2#!'resource='bm_all' cropx='!#param3#!'cropy='!#param4#!'cropwidth='!#param5#!'cropheight='!#param6#!' framewidth='!#param7#!'frameheight='!#param8#!'!#param9#!> !#param10#! </image> getDynamicXML(<filename>, <caller>, <parms …>); getDynamicXML(”ui_icon.xml”, this, XMLGetID(0),2,3,4,5,6,7,8,9,10);
The general problem Server Client ID=4 ID=st1 ? Room ID=34 User ID=11 User ID=17 ID=kot ? ID=bob Room ID=31 User ID=7 User ID=67 ContextManager ID=2 How to know which object’s methods to call?
Easy solution: always use same id:s on client and server Server Client ID=11 Room ID=34 User ID=11 User ID=17 <image id=’11’ … /> Room ID=31 User ID=7 User ID=67 SuperUser ID=2
What object is called on the server side? <OBJECT ID>::<clientMethodName> {param1} {param2} … {param N} (exceptions: clientActivate, clientCreate, clientSubscribe, clientPoll) Client Server 134::clientMakeSomething {param1} {234} Determine object - evaluate <I_settext id=‘str1’ text=‘update text’ />
Bag of tricks • The client needs to determine what object to call on theserver side • Many things can be determined in the server side already • UI/Interaction & User self need to be determined on the client side
Client Side Database $(service.<key>) For every application Application defined:
Single UI Template id=‘main’type=‘form’ Template id=‘main’type=‘canvas’ <template type='form' id=''> <editfield title='Nickname' id='nickname' /> <choicegroup id='type' title='Character type'> <i_choice name='0' text='Fighter' /> <i_choice name='1' text='Thief' /> <i_choice name='2' text='Wizard' /> <i_choice name='3' text='Gnome' /> </choicegroup> <command type='ok' text='Ready'> <g_send type='tcp' type='request'> Player::clientCreate {1} {$(nickname.text)} {$(type.selected)} </g_send> </command> </template>
Multi UI Template id=‘main’uigroup=‘g1’ Template id=‘chat’uigroup=‘g1’ Template id=‘avatar’uigroup=‘g1’ <setactiveui='chat'/>
Update Item Template id=‘main’uigroup=‘g1’ Template id=‘chat’uigroup=‘g1’ <string id=‘w’ /> Template id=‘avatar’uigroup=‘g1’ <i_settext id=‘w’ ui='chat' text=‘hello, world’ />
Add UI Template id=‘main’uigroup=‘g1’ Template id=‘chat’uigroup=‘g1’ <string id=‘w’ /> Template id=‘avatar’uigroup=‘g1’ Template id=‘newUI’uigroup=‘g1’ <template …/>
Object Creation into template <object_name id=‘<ID>’ …/> <string id=‘123’ text=‘Hello World.'/> <string id=‘123’> <parms> <text>‘Hello World.‘</text> </parms> </string/>
Object Attributes <imageid=‘1'resource='bm_all'x='5%'y='25%'> <i_attributename='description'value='Buy beer'/> </image>
System hooks <i_hookname='on_resource_loaded'> <i_equalattr='resource_id'value='res_tile'> <i_eventid='timebar'hook='start'/> </i_equal> </i_hook>
Item hooks: phone buttons <i_hookui='game_canvas'id='player'name='on_left_down'> <!– handler --> </i_hook> name='on_left_down‘ 'on_right_down‘ 'on_up_down‘ 'on_down_down‘ 'on_fire_down‘ …
Standard (system provided) item hooks <i_hookname='on_show'> <i_hook name='on_hide‘ 'on_select‘ 'on_selector_enter‘ 'on_selector_leave‘ …
Item hooks: custom <i_eventid='timebar'hook='timetick'/> <i_eventid='timebar'hook='timeout'/> <i_hookname='timetick'> <!– implement --> </i_hook> <i_hookname='timeout'> <!– implement --> </i_hook>
Timers: finalise <g_starttimerid='timeout'times='8'time='1000'finalise='true'> <i_eventid='timebar'hook='timetick'/> <break/> <i_eventid='timebar'hook='timeout'/> </g_starttimer>
Timers: initialise <g_starttimerid='move_tmr'times='16'time='100'initialise='true'> <g_allowuserinputvalue='false'/> <i_eventid='timebar'hook='stop'/> <g_sendtype='tcp'>!#param1#!::clientMoveChar {!#param2#!} {!#param3#!}</g_send> <break/> <i_setframeid='player'delta='1'/> <g_moveid='player'deltax='!#param2#!'deltay='!#param3#!'/> </g_starttimer>
Item traversal: Foreach <g_foreachgroup='maincanvas'> <g_setselectablegroup='maincanvas'id='$(this.id)'value='false'/> </g_foreach>