########################### A Graphical user interface for our framework, still in implementation## @author: XingYang Shao(Daniel)##################### implement Client; include "sys.m";include "draw.m";include "tk.m";include "tkclient.m";include "client.m"; #include "dfsnodeserver.m"; sys : Sys;draw : Draw;tk : Tk;tkclient : Tkclient; toplevel : ref Tk->Toplevel;winctl : chan of string; perc := 0; users := array [MAX_USER_NUM] of ref UserState;usernum := 0; hasAdmin := 0; init(ctxt : ref Draw->Context, nil : list of string){ sys = load Sys Sys->PATH; draw = load Draw Draw->PATH; tk = load Tk Tk->PATH; tkclient = load Tkclient Tkclient->PATH; userstate := ref UserState; userstate.set("Daniel", 10000, big 1999, "192.168.43.99"); tkclient->init(); (toplevel, winctl) = tkclient->toplevel(ctxt, nil, "Client - Map-Reduce System", Tkclient->Appl); cmd := chan of string; tk->namechan(toplevel, cmd, "cmd"); tk->cmd(toplevel, "frame .info -height 400 -width 200"); tk->cmd(toplevel, "frame .info.self -height 100 -width 200"); tk->cmd(toplevel, "frame .info.all -height 300 -width 200"); tk->cmd(toplevel, "label .info.self.nm -height 20 -width 200 -text {Name : " + userstate.name + "}"); tk->cmd(toplevel, "label .info.self.id -height 20 -width 200 -text {ID : " + sys->sprint("%d", userstate.id) + "}"); tk->cmd(toplevel, "label .info.self.rt -height 20 -width 200 -text {Register time : " + sys->sprint("%bd", userstate.regtime) + "}"); tk->cmd(toplevel, "label .info.self.ip -height 20 -width 200 -text {IP : " + userstate.ip + "}"); tk->cmd(toplevel, "label .info.self.sepaln -height 20 -width 200 -text {------------------------------}"); tk->cmd(toplevel, "pack .info.self.nm .info.self.id .info.self.rt .info.self.ip .info.self.sepaln -side top -fill x"); for(i := 0; i < MAX_USER_NUM; i++) { cmdstr_fr := sys->sprint("frame .info.all.m%d -height 30 -width 200", i); cmdstr_nm := sys->sprint("label .info.all.m%d.nm -height 15 -width 200 -text {No User}", i); cmdstr_ip := sys->sprint("label .info.all.m%d.ip -height 15 -width 200 -text { }", i); cmdstr_pack := sys->sprint("pack .info.all.m%d.nm .info.all.m%d.ip -side top -fill x", i, i); tk->cmd(toplevel, cmdstr_fr); tk->cmd(toplevel, cmdstr_nm); tk->cmd(toplevel, cmdstr_ip); tk->cmd(toplevel, cmdstr_pack); } tk->cmd(toplevel, "pack .info.all.m0 .info.all.m1 .info.all.m2 .info.all.m3 .info.all.m4 .info.all.m5 .info.all.m6 .info.all.m7 .info.all.m8 .info.all.m9 -side top -fill x"); tk->cmd(toplevel, "pack .info.self .info.all -side top -fill x"); tk->cmd(toplevel, "frame .show -height 350 -width 400"); tk->cmd(toplevel, "label .show.prog -height 50 -width 400 -text {Progress Percentage : 0%}"); tk->cmd(toplevel, "canvas .show.perc -height 50 -width 400 -background white"); tk->cmd(toplevel, "frame .show.text"); tk->cmd(toplevel, "text .t -yscrollcommand {.scroll set} -bg white -height 250 -width 385"); tk->cmd(toplevel, "scrollbar .scroll -command {.t yview}"); tk->cmd(toplevel, "pack .scroll -side left -fill y -in .show.text"); tk->cmd(toplevel, "pack .t -side right -in .show.text -expand 1 -fill both"); tk->cmd(toplevel, "frame .show.cmd1 -height 25 -width 400"); tk->cmd(toplevel, "frame .show.cmd2 -height 25 -width 400"); tk->cmd(toplevel, "button .show.cmd1.connect -text {Connect} -command {send cmd connect}"); tk->cmd(toplevel, "button .show.cmd1.submit -text {Submit} -command {send cmd submit}"); tk->cmd(toplevel, "button .show.cmd2.start -text {Start} -command {send cmd start}"); tk->cmd(toplevel, "button .show.cmd2.quit -text {Quit} -command {send cmd quit}"); changePerc(0); tk->cmd(toplevel, "pack .show.cmd1.connect .show.cmd1.submit -side left -fill x -expand 1"); tk->cmd(toplevel, "pack .show.cmd2.start .show.cmd2.quit -side left -fill x -expand 1"); tk->cmd(toplevel, "pack .show.prog .show.perc .show.text .show.cmd1 .show.cmd2 -side top -fill x"); tk->cmd(toplevel, "pack .info .show -side left -fill x -expand 1"); tk->cmd(toplevel, "update"); tkclient->startinput(toplevel, "ptr" :: "kbd" :: nil); tkclient->onscreen(toplevel, nil); for (;;) { alt { s := <-cmd => (nil, cmdstr) := sys->tokenize(s, " \t\n"); case (hd cmdstr) { "quit" => exit; "connect" => connect(); "submit" => submit(); "start" => start(); } p := <-toplevel.ctxt.ptr => tk->pointer(toplevel, *p); c := <-toplevel.ctxt.kbd => tk->keyboard(toplevel, c); ctl := <-winctl or ctl = <-toplevel.ctxt.ctl or ctl = <-toplevel.wreq => tkclient->wmctl(toplevel, ctl); } tk->cmd(toplevel, "update"); }} ############################################################################################################ Usage : Declare one new variable of type UserState, and then this method is used to set its values.###########################################################################################################UserState.set(userstate : self ref UserState, name : string, id : int, regtime : big, ip : string, admin : int){ userstate.name = name; userstate.id = id; userstate.regtime = regtime; userstate.ip = ip; userstate.admin = admin; #userstate.pic = pic;} ############################################################################################################# Interfaces for inner programs############################################################################################################start(){ sys->print("Start button is pressed\n"); # debug info changePerc(perc + 1); # appendLog("[INFO] Start button is pressed\n");} connect(){ sys->print("Connect button is pressed\n"); # debug info newUser : ref UserState; # for debug newUser = ref ("Daniel", 10000, big 1999, "192.168.43.99", 1); # for debug ## connect to real dfsservers addUser(newUser); # for UI # appendLog("[INFO] Connect button is pressed\n");} submit(){ sys->print("Submit button is pressed\n"); # debug info deleteUser(0); # appendLog("[INFO] Submit button is pressed\n");} changePerc(newPerc : int){ perc = newPerc; perc_string := sys->sprint(".show.prog configure -text {Progress Percentage : %d%%}", perc); tk->cmd(toplevel, perc_string); loc_string := sys->sprint("0 0 %d 49", 4 * perc); tk->cmd(toplevel, ".show.perc create rectangle 0 0 450 49 -outline white -fill white"); tk->cmd(toplevel, ".show.perc create rectangle " + loc_string + " -outline black -fill black");} appendLog(log : string){ if(toplevel == nil) { sys->print("Unexpected Error!"); exit; } if(log == nil) return; tk->cmd(toplevel, ".t insert end '" + log);} ######################################################################################################## # Used to synchronize user information from master.########################################################################################################syncUsers() { ## Variables to be synchronized : users[MAX_USER_NUM], hasAdmin } ######################################################################################################### Used to deal with user changes (FOR UI CHANGES, NOT FOR SYNCHRONIZATION).########################################################################################################addUser(userstate : ref UserState){ if(usernum == MAX_USER_NUM) { sys->print("Warning : Overloading users, only %d users are accepted, others will be ignored.\n", MAX_USER_NUM); return; } users[usernum++] = userstate; sys->print("%s\t%d\t%bd\t%s\n", userstate.name, userstate.id, userstate.regtime, userstate.ip); sys->print("%s\t%d\t%bd\t%s\n", users[usernum-1].name, users[usernum-1].id, users[usernum-1].regtime, users[usernum-1].ip); UpdUsrLbls();} deleteUser(index : int){ if(usernum == 0) { sys->print("Warning : No users in list.\n"); return; } else if(index >= usernum || index < 0) { sys->print("Error : delete user index out of range. Action ignored\n"); } usernum--; for(i := 0; i < usernum; i++) { if(i < index) continue; else { users[i] = users[i + 1]; } } UpdUsrLbls();} # Update User LabelsUpdUsrLbls(){ for(i := 0; i < MAX_USER_NUM; i++) { if(i < usernum) { cmdstr_nm := sys->sprint(".info.all.m%d.nm configure -text {%s}", i, users[i].name); sys->print("%s\n", cmdstr_nm); tk->cmd(toplevel, cmdstr_nm); tk->cmd(toplevel, sys->sprint(".info.all.m%d.ip configure -text {%s}", i, users[i].ip)); } else { tk->cmd(toplevel, sys->sprint(".info.all.m%d.nm configure -text {No User}", i)); tk->cmd(toplevel, sys->sprint(".info.all.m%d.ip configure -text { }", i)); } } tk->cmd(toplevel, "update");}
#########################
#
# A Graphical user interface for our framework, still in implementation
#
# @author: XingYang Shao(Daniel)
#####################
implement Client;
include "sys.m";
include "draw.m";
include "tk.m";
include "tkclient.m";
include "client.m";
#include "dfsnodeserver.m";
sys : Sys;
draw : Draw;
tk : Tk;
tkclient : Tkclient;
toplevel : ref Tk->Toplevel;
winctl : chan of string;
perc := 0;
users := array [MAX_USER_NUM] of ref UserState;
usernum := 0;
hasAdmin := 0;
init(ctxt : ref Draw->Context, nil : list of string)
{
sys = load Sys Sys->PATH;
draw = load Draw Draw->PATH;
tk = load Tk Tk->PATH;
tkclient = load Tkclient Tkclient->PATH;
userstate := ref UserState;
userstate.set("Daniel", 10000, big 1999, "192.168.43.99");
tkclient->init();
(toplevel, winctl) = tkclient->toplevel(ctxt, nil, "Client - Map-Reduce System", Tkclient->Appl);
cmd := chan of string;
tk->namechan(toplevel, cmd, "cmd");
tk->cmd(toplevel, "frame .info -height 400 -width 200");
tk->cmd(toplevel, "frame .info.self -height 100 -width 200");
tk->cmd(toplevel, "frame .info.all -height 300 -width 200");
tk->cmd(toplevel, "label .info.self.nm -height 20 -width 200 -text {Name : " + userstate.name + "}");
tk->cmd(toplevel, "label .info.self.id -height 20 -width 200 -text {ID : " + sys->sprint("%d", userstate.id) + "}");
tk->cmd(toplevel, "label .info.self.rt -height 20 -width 200 -text {Register time : " + sys->sprint("%bd", userstate.regtime) + "}");
tk->cmd(toplevel, "label .info.self.ip -height 20 -width 200 -text {IP : " + userstate.ip + "}");
tk->cmd(toplevel, "label .info.self.sepaln -height 20 -width 200 -text {------------------------------}");
tk->cmd(toplevel, "pack .info.self.nm .info.self.id .info.self.rt .info.self.ip .info.self.sepaln -side top -fill x");
for(i := 0; i < MAX_USER_NUM; i++)
{
cmdstr_fr := sys->sprint("frame .info.all.m%d -height 30 -width 200", i);
cmdstr_nm := sys->sprint("label .info.all.m%d.nm -height 15 -width 200 -text {No User}", i);
cmdstr_ip := sys->sprint("label .info.all.m%d.ip -height 15 -width 200 -text { }", i);
cmdstr_pack := sys->sprint("pack .info.all.m%d.nm .info.all.m%d.ip -side top -fill x", i, i);
tk->cmd(toplevel, cmdstr_fr);
tk->cmd(toplevel, cmdstr_nm);
tk->cmd(toplevel, cmdstr_ip);
tk->cmd(toplevel, cmdstr_pack);
}
tk->cmd(toplevel, "pack .info.all.m0 .info.all.m1 .info.all.m2 .info.all.m3 .info.all.m4 .info.all.m5 .info.all.m6 .info.all.m7 .info.all.m8 .info.all.m9 -side top -fill x");
tk->cmd(toplevel, "pack .info.self .info.all -side top -fill x");
tk->cmd(toplevel, "frame .show -height 350 -width 400");
tk->cmd(toplevel, "label .show.prog -height 50 -width 400 -text {Progress Percentage : 0%}");
tk->cmd(toplevel, "canvas .show.perc -height 50 -width 400 -background white");
tk->cmd(toplevel, "frame .show.text");
tk->cmd(toplevel, "text .t -yscrollcommand {.scroll set} -bg white -height 250 -width 385");
tk->cmd(toplevel, "scrollbar .scroll -command {.t yview}");
tk->cmd(toplevel, "pack .scroll -side left -fill y -in .show.text");
tk->cmd(toplevel, "pack .t -side right -in .show.text -expand 1 -fill both");
tk->cmd(toplevel, "frame .show.cmd1 -height 25 -width 400");
tk->cmd(toplevel, "frame .show.cmd2 -height 25 -width 400");
tk->cmd(toplevel, "button .show.cmd1.connect -text {Connect} -command {send cmd connect}");
tk->cmd(toplevel, "button .show.cmd1.submit -text {Submit} -command {send cmd submit}");
tk->cmd(toplevel, "button .show.cmd2.start -text {Start} -command {send cmd start}");
tk->cmd(toplevel, "button .show.cmd2.quit -text {Quit} -command {send cmd quit}");
changePerc(0);
tk->cmd(toplevel, "pack .show.cmd1.connect .show.cmd1.submit -side left -fill x -expand 1");
tk->cmd(toplevel, "pack .show.cmd2.start .show.cmd2.quit -side left -fill x -expand 1");
tk->cmd(toplevel, "pack .show.prog .show.perc .show.text .show.cmd1 .show.cmd2 -side top -fill x");
tk->cmd(toplevel, "pack .info .show -side left -fill x -expand 1");
tk->cmd(toplevel, "update");
tkclient->startinput(toplevel, "ptr" :: "kbd" :: nil);
tkclient->onscreen(toplevel, nil);
for (;;) {
alt {
s := <-cmd =>
(nil, cmdstr) := sys->tokenize(s, " \t\n");
case (hd cmdstr)
{
"quit" =>
exit;
"connect" =>
connect();
"submit" =>
submit();
"start" =>
start();
}
p := <-toplevel.ctxt.ptr =>
tk->pointer(toplevel, *p);
c := <-toplevel.ctxt.kbd =>
tk->keyboard(toplevel, c);
ctl := <-winctl or
ctl = <-toplevel.ctxt.ctl or
ctl = <-toplevel.wreq =>
tkclient->wmctl(toplevel, ctl);
}
tk->cmd(toplevel, "update");
}
}
##########################################################################################################
#
# Usage : Declare one new variable of type UserState, and then this method is used to set its values.
#
##########################################################################################################
UserState.set(userstate : self ref UserState, name : string, id : int, regtime : big, ip : string, admin : int)
{
userstate.name = name;
userstate.id = id;
userstate.regtime = regtime;
userstate.ip = ip;
userstate.admin = admin;
#userstate.pic = pic;
}
###########################################################################################################
#
# Interfaces for inner programs
#
###########################################################################################################
start()
{
sys->print("Start button is pressed\n"); # debug info
changePerc(perc + 1);
# appendLog("[INFO] Start button is pressed\n");
}
connect()
{
sys->print("Connect button is pressed\n"); # debug info
newUser : ref UserState; # for debug
newUser = ref ("Daniel", 10000, big 1999, "192.168.43.99", 1); # for debug
## connect to real dfsservers
addUser(newUser); # for UI
# appendLog("[INFO] Connect button is pressed\n");
}
submit()
{
sys->print("Submit button is pressed\n"); # debug info
deleteUser(0);
# appendLog("[INFO] Submit button is pressed\n");
}
changePerc(newPerc : int)
{
perc = newPerc;
perc_string := sys->sprint(".show.prog configure -text {Progress Percentage : %d%%}", perc);
tk->cmd(toplevel, perc_string);
loc_string := sys->sprint("0 0 %d 49", 4 * perc);
tk->cmd(toplevel, ".show.perc create rectangle 0 0 450 49 -outline white -fill white");
tk->cmd(toplevel, ".show.perc create rectangle " + loc_string + " -outline black -fill black");
}
appendLog(log : string)
{
if(toplevel == nil)
{
sys->print("Unexpected Error!");
exit;
}
if(log == nil) return;
tk->cmd(toplevel, ".t insert end '" + log);
}
#######################################################################################################
#
# Used to synchronize user information from master.
#
#######################################################################################################
syncUsers()
{
## Variables to be synchronized : users[MAX_USER_NUM], hasAdmin
}
#######################################################################################################
#
# Used to deal with user changes (FOR UI CHANGES, NOT FOR SYNCHRONIZATION).
#
#######################################################################################################
addUser(userstate : ref UserState)
{
if(usernum == MAX_USER_NUM)
{
sys->print("Warning : Overloading users, only %d users are accepted, others will be ignored.\n", MAX_USER_NUM);
return;
}
users[usernum++] = userstate;
sys->print("%s\t%d\t%bd\t%s\n", userstate.name, userstate.id, userstate.regtime, userstate.ip);
sys->print("%s\t%d\t%bd\t%s\n", users[usernum-1].name, users[usernum-1].id, users[usernum-1].regtime, users[usernum-1].ip);
UpdUsrLbls();
}
deleteUser(index : int)
{
if(usernum == 0)
{
sys->print("Warning : No users in list.\n");
return;
}
else if(index >= usernum || index < 0)
{
sys->print("Error : delete user index out of range. Action ignored\n");
}
usernum--;
for(i := 0; i < usernum; i++)
{
if(i < index) continue;
else
{
users[i] = users[i + 1];
}
}
UpdUsrLbls();
}
# Update User Labels
UpdUsrLbls()
{
for(i := 0; i < MAX_USER_NUM; i++)
{
if(i < usernum)
{
cmdstr_nm := sys->sprint(".info.all.m%d.nm configure -text {%s}", i, users[i].name);
sys->print("%s\n", cmdstr_nm);
tk->cmd(toplevel, cmdstr_nm);
tk->cmd(toplevel, sys->sprint(".info.all.m%d.ip configure -text {%s}", i, users[i].ip));
}
else
{
tk->cmd(toplevel, sys->sprint(".info.all.m%d.nm configure -text {No User}", i));
tk->cmd(toplevel, sys->sprint(".info.all.m%d.ip configure -text { }", i));
}
}
tk->cmd(toplevel, "update");
}