Commit 8b010b61 authored by Yori Fournier's avatar Yori Fournier
Browse files

Merge branch '66-feature-resyncfig' into 'dev'

Resolve "FEATURE : reSyncFig"

Closes #66

See merge request !49
parents 35162722 6cbe381f
Pipeline #454 passed with stage
in 2 minutes and 51 seconds
......@@ -104,9 +104,32 @@ class MplClient2():
def listRemoteData(self):
""" The server retuns a list with the content of its G_RAWDATA
not implemented yet.
"""
pass
query = Query(Query.LISTDATA,None)
status = self.send(query)
if not status :
print('something went wrong with the sending of readData request...')
answer = self.waitForSignal()
if isinstance(answer,Answer) :
return answer.content
elif isinstance(answer,Status):
print(answer.content)
return None
def getData(self, dataname) :
""" The server returns the actual data known under "dataname" warning: this can possibly be HUGE
"""
query = Query(Query.GETDATA,dataname)
status = self.send(query)
if not status :
print('something went wrong with the sending of readData request...')
answer = self.waitForSignal()
if isinstance(answer,Answer) :
return answer.content
elif isinstance(answer,Status):
print(answer.content)
return None
def newSyncFigure(self, figname, dataname, *args, **kwargs) :
'''
......@@ -125,7 +148,7 @@ class MplClient2():
# try to create a figure of the same class on the client side
if isinstance(answer,Answer) :
print('trying to create a figure of the same class on the client side')
fig = figname( MyData(), *args, **kwargs)
fig = figname( dataname, *args, **kwargs)
# Link the temporary Sync Figure
fig.syncID = answer.content
fig.client = self
......
......@@ -136,14 +136,8 @@ class MplHandler(SocketServer.StreamRequestHandler):
print(SPCE+"SERVER: Exception details where:",e.message, e.args )
return Status(False,"I couldn't format the rawdata. Exception details where:",e.message, e.args)
# compose the answer
datas = ()
for ax in fig.get_axes():
# ax.data is any user defined object
# ax.packFormattedData returns it's string representation
# to be unpacked by ax.unpackFormattedData
# datas.append(ax.packFormattedData(ax.data))
datas = datas + (ax.data,)
# compose the formated data
datas = tuple(ax.data for ax in fig.get_axes())
return Answer(datas)
......@@ -154,7 +148,17 @@ class MplHandler(SocketServer.StreamRequestHandler):
return Status(True,'Figure with ID '+str(figID)+' deleted from server.')
else :
return Status(False,'Figure with ID '+str(figID)+' not found on server side.')
def treatListData(self,content) :
""" list the keys (and possibly (later) the location from G_RAWDATA """
return Answer(G_RAWDATA.keys())
def treatGetData(self,content) :
""" from G_FIGURES """
if content in G_RAWDATA:
return Answer(G_RAWDATA[content])
else :
return Status(False,'Dataname not found in index of the server side...')
def send(self,sig):
# pickel the signal
......@@ -204,6 +208,10 @@ class MplHandler(SocketServer.StreamRequestHandler):
return self.treatSyncFigFormatRawData(sig.content)
elif sig.queryType == sig.DELETESYNCFIGURE :
return self.treatDeleteSyncFigure(sig.content)
elif sig.queryType == sig.LISTDATA :
return self.treatListData(sig.content)
elif sig.queryType == sig.GETDATA :
return self.treatGetData(sig.content)
else :
self.servPrint('received unknown query type')
return Status(False,"received unknown query type")
......
......@@ -83,7 +83,6 @@ class MyFig_client(Figure):
# (private variable can not be updated)
FIGSIZE = D_FIGSIZE
# CONSTRUCTOR --------------------------------------------------------
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, rawdata, *args, **kwargs):
......@@ -110,6 +109,7 @@ class MyFig_client(Figure):
# initialise
self._initialize(*args, **kwargs)
self.set_rawdata(rawdata)
def deSyncFig(self):
if self.client is not None :
......@@ -119,8 +119,56 @@ class MyFig_client(Figure):
else :
print('The figure could not be deleted on the server Side')
else:
print('The client is not connected to a server yet')
print('The client is not connected to a server yet. Please use the client to set up a sync conection.')
def getState(self) :
""" this function collects the current state of in the figure by creating a dict that holds all keyword,value pairs (taking the aliases into account)
Warning: myplotlib allows in a transparent manner to modify the axes directly. Those changes can not be covert.
"""
state = dict()
# test for double keywords and print a waring
for ax in self.axes:
# find aliases for this specific axes
masks = dict()
for alias in self.aliases.keys() :
axes4alias,keyword = self.aliases[alias]
if axes4alias == ax :
masks.update({keyword : alias})
# collect all keywords of the axes and replace the keys with the aliases
axKeywords = ax.keywords.copy()
for mask in masks :
if mask in axKeywords :
axKeywords[masks[mask]] = axKeywords.pop(mask)
# Test if kewords are already set by an other axes
for key in axKeywords.keys() :
if key in state.keys():
print('Warning: The keyword \"',key,'\" appears in multiple axes. The Defaults will be overwritten. Prevent this by using aliases')
# update the global keyword index
state.update(axKeywords)
return state
def reSyncFig(self):
if self.client is not None :
# collect the current state of the figure
state = self.getState()
# call the client to create a new figure on the server side
newFig = self.client.newSyncFigure(self.__class__, self.remote_rawdata, **state)
# since the state matches the current instance. only the new syncID is kept.
self.syncID = newFig.syncID
else:
print('The client is not connected to a server yet. Please use the client to set up a sync conection.')
# INITIALIZE -------------------------------------------------------
def _initialize(self, *args, **kwargs):
......@@ -229,8 +277,21 @@ class MyFig_client(Figure):
#if the name is correct we should never get here.
print(SEVR + "The axes name ", name, " was not found")
return None
#~ def getAxesName(self,unknownax) :
#~ """ compares all axes against the function parameter and returns the name of that axes if found in figure"""
#~
#~ for ax in self.get_axes() :
#~ if unknownax == ax :
#~ return ax.name
# SET RAW DATA -----------------------------------------------------
def set_rawdata(self, rawdata):
''' This function sets loacally the names of the remote data in a similar way as a local figure would do.
Warning : No consitancy checking is done. The server side will report the errors.
'''
self.remote_rawdata = rawdata
# FORMAT RAW DATA --------------------------------------------------
def formatRawData(self):
# HEre comes a function that send a signal to the server
......
......@@ -10,9 +10,11 @@ class Query(Signal) :
UPDATESYNCFIGURE = 3
SYNCFIGFORMATRAWDATA = 4
DELETESYNCFIGURE = 5
LISTDATA = 6
GETDATA = 7
def __init__(self,queryType, content) :
if queryType in [Query.READDATA,Query.NEWSYNCFIGURE,Query.UPDATESYNCFIGURE,Query.SYNCFIGFORMATRAWDATA,Query.DELETESYNCFIGURE] :
if queryType in range(1,8) :
self.queryType = queryType
if queryType == Query.READDATA :
if type(content) == dict :
......@@ -35,6 +37,10 @@ class Query(Signal) :
elif queryType == Query.DELETESYNCFIGURE :
self.content = content
elif queryType == Query.LISTDATA :
self.content = content
elif queryType == Query.GETDATA :
self.content = content
else :
print('unknown query type!')
raise
......
......@@ -12,3 +12,30 @@ class FigTest(MyFig):
frame1 = [0.1, 0.1, 0.8, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1), "p1")
class FigTest2(MyFig): # Fig with two Axes
# Set the size of the Figure in inch
# (private variable can not be updated)
FIGSIZE = (8., 6.)
def addAxes(self):
ratio = 6. / 8. # height/width of the axes (in inch)
frame1 = [0.1, 0.1, 0.4, 0.8] # part of the fig that is available
frame2 = [0.6, 0.1, 0.4, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1),"p1")
self.add_axes(AxTest(self, ratio, frame2),"p2")
def declareAliases(self):
# it is important to not hold additional references to an axes in the figure to avoid memory leaks. use the this function
# get the plot added above
p1 = self.getAxesByName("p1")
p2 = self.getAxesByName("p2")
self.aliases = {'xRange_p1': (p1, "xRange"),
'xRange_p2': (p2, "xRange")}
return(True)
......@@ -12,3 +12,30 @@ class FigTest(MyFig):
frame1 = [0.1, 0.1, 0.8, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1), "p1")
class FigTest2(MyFig): # Fig with two Axes
# Set the size of the Figure in inch
# (private variable can not be updated)
FIGSIZE = (8., 6.)
def addAxes(self):
ratio = 6. / 8. # height/width of the axes (in inch)
frame1 = [0.1, 0.1, 0.4, 0.8] # part of the fig that is available
frame2 = [0.6, 0.1, 0.4, 0.8] # part of the fig that is available
self.add_axes(AxTest(self, ratio, frame1),"p1")
self.add_axes(AxTest(self, ratio, frame2),"p2")
def declareAliases(self):
# it is important to not hold additional references to an axes in the figure to avoid memory leaks. use the this function
# get the plot added above
p1 = self.getAxesByName("p1")
p2 = self.getAxesByName("p2")
self.aliases = {'xRange_p1': (p1, "xRange"),
'xRange_p2': (p2, "xRange")}
return(True)
......@@ -2,11 +2,16 @@ import threading
from time import sleep
from serverside.myIOs import readStupidData
from serverside.myIOs import readStupidData2
from serverside.figTest import FigTest as FigTests
from clientside.figTest import FigTest as FigTestc
SERVER_IOFUNCTIONS = {'readStupidData': readStupidData}
SERVER_FIGURES = {'FigTest': FigTests}
# This is for the double figure
from serverside.figTest import FigTest2 as FigTests2
from clientside.figTest import FigTest2 as FigTestc2
SERVER_IOFUNCTIONS = {'readStupidData': readStupidData,'readStupidData2': readStupidData2}
SERVER_FIGURES = {'FigTest': FigTests,'FigTest2': FigTests2}
import serverside.myplotlib as mpl_server
import clientside.myplotlib as mpl_client
......@@ -14,16 +19,10 @@ import clientside.myplotlib as mpl_client
server = mpl_server.MplServer2(port=12345, knownFunctions=SERVER_IOFUNCTIONS, knownFigures=SERVER_FIGURES)
client = mpl_client.MplClient2()
# Start a thread with the server -- that thread will then start one
# more thread for each request
# server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
# server_thread.daemon = True
# server_thread.start()
server.run()
print "Server loop running in thread:", server.server_thread.name
server.run(as_daemon=True)
print("Server loop running in thread:", server.server_thread.name)
client.connect(('localhost', 12345))
print("Client is now connected")
client.readData('readStupidData', 'data1')
fig1 = client.newSyncFigure(FigTestc, ('data1',))
......@@ -35,11 +34,16 @@ fig1.update(xRange=[-2, 2],yRange=[-2, 2])
win.refresh()
sleep(2)
# multiple figures
fig2 = client.newSyncFigure(FigTestc, ('data1',), xRange=[-1.5, 1.5], yRange=[-1.5, 1.5])
# multiple figures with multiple data
client.readData('readStupidData2', 'data2')
print("known datasets: ",client.listRemoteData())
fig2 = client.newSyncFigure(FigTestc2, ('data1','data2'), xRange_p1=[-2.0, 2.0], xRange_p2=[-3, 3], yRange=[-2.0, 2.0])
print('current state:::',fig2.getState())
win=mpl_client.MyWin(fig2)
sleep(2)
# desync resync test
fig1.deSyncFig()
fig2.deSyncFig()
fig1.reSyncFig()
sleep(2)
......@@ -10,18 +10,23 @@ SERVER_FIGURES = {'FigTest': FigTests}
import serverside.myplotlib as mpl_server
import clientside.myplotlib as mpl_client
server = mpl_server.MplServer2(port=50803, knownFunctions=SERVER_IOFUNCTIONS, knownFigures=SERVER_FIGURES)
server = mpl_server.MplServer2(port=12345, knownFunctions=SERVER_IOFUNCTIONS, knownFigures=SERVER_FIGURES)
client = mpl_client.MplClient2()
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
client.connect(('', 50803))
server.run(as_daemon=True)
print "Server loop running in thread:", server.server_thread.name
client.connect(('', 12345))
print("Client is now connected")
# create a figure
client.readData('readStupidData', 'data1')
fig = client.newSyncFigure(FigTestc, ('data1',))
fig1 = client.newSyncFigure(FigTestc, ('data1',))
# update test
fig1.update(xRange=[-2, 2],yRange=[-2, 2])
# multiple figures
fig2 = client.newSyncFigure(FigTestc, ('data1',), xRange=[-1.5, 1.5], yRange=[-1.5, 1.5])
fig1.deSyncFig()
fig2.deSyncFig()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment